• Home
  • 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 #ifndef V8_PARSING_PARSER_BASE_H_
6 #define V8_PARSING_PARSER_BASE_H_
7 
8 #include <stdint.h>
9 
10 #include <utility>
11 #include <vector>
12 
13 #include "src/ast/ast-source-ranges.h"
14 #include "src/ast/ast.h"
15 #include "src/ast/scopes.h"
16 #include "src/base/flags.h"
17 #include "src/base/hashmap.h"
18 #include "src/base/pointer-with-payload.h"
19 #include "src/base/v8-fallthrough.h"
20 #include "src/codegen/bailout-reason.h"
21 #include "src/common/globals.h"
22 #include "src/common/message-template.h"
23 #include "src/logging/log.h"
24 #include "src/logging/runtime-call-stats-scope.h"
25 #include "src/objects/function-kind.h"
26 #include "src/parsing/expression-scope.h"
27 #include "src/parsing/func-name-inferrer.h"
28 #include "src/parsing/parse-info.h"
29 #include "src/parsing/scanner.h"
30 #include "src/parsing/token.h"
31 #include "src/regexp/regexp.h"
32 #include "src/zone/zone-chunk-list.h"
33 
34 namespace v8 {
35 namespace internal {
36 
37 class PreParserIdentifier;
38 
39 enum FunctionNameValidity {
40   kFunctionNameIsStrictReserved,
41   kSkipFunctionNameCheck,
42   kFunctionNameValidityUnknown
43 };
44 
45 enum AllowLabelledFunctionStatement {
46   kAllowLabelledFunctionStatement,
47   kDisallowLabelledFunctionStatement,
48 };
49 
50 enum ParsingArrowHeadFlag { kCertainlyNotArrowHead, kMaybeArrowHead };
51 
52 enum class ParseFunctionFlag : uint8_t {
53   kIsNormal = 0,
54   kIsGenerator = 1 << 0,
55   kIsAsync = 1 << 1
56 };
57 
58 using ParseFunctionFlags = base::Flags<ParseFunctionFlag>;
59 
60 struct FormalParametersBase {
FormalParametersBaseFormalParametersBase61   explicit FormalParametersBase(DeclarationScope* scope) : scope(scope) {}
62 
num_parametersFormalParametersBase63   int num_parameters() const {
64     // Don't include the rest parameter into the function's formal parameter
65     // count (esp. the SharedFunctionInfo::internal_formal_parameter_count,
66     // which says whether we need to create an arguments adaptor frame).
67     return arity - has_rest;
68   }
69 
UpdateArityAndFunctionLengthFormalParametersBase70   void UpdateArityAndFunctionLength(bool is_optional, bool is_rest) {
71     if (!is_optional && !is_rest && function_length == arity) {
72       ++function_length;
73     }
74     ++arity;
75   }
76 
77   DeclarationScope* scope;
78   bool has_rest = false;
79   bool is_simple = true;
80   int function_length = 0;
81   int arity = 0;
82 };
83 
84 // Stack-allocated scope to collect source ranges from the parser.
85 class V8_NODISCARD SourceRangeScope final {
86  public:
SourceRangeScope(const Scanner * scanner,SourceRange * range)87   SourceRangeScope(const Scanner* scanner, SourceRange* range)
88       : scanner_(scanner), range_(range) {
89     range_->start = scanner->peek_location().beg_pos;
90     DCHECK_NE(range_->start, kNoSourcePosition);
91     DCHECK_EQ(range_->end, kNoSourcePosition);
92   }
93 
~SourceRangeScope()94   ~SourceRangeScope() {
95     DCHECK_EQ(kNoSourcePosition, range_->end);
96     range_->end = scanner_->location().end_pos;
97     DCHECK_NE(range_->end, kNoSourcePosition);
98   }
99 
100  private:
101   const Scanner* scanner_;
102   SourceRange* range_;
103 
104   DISALLOW_IMPLICIT_CONSTRUCTORS(SourceRangeScope);
105 };
106 
107 // ----------------------------------------------------------------------------
108 // The RETURN_IF_PARSE_ERROR macro is a convenient macro to enforce error
109 // handling for functions that may fail (by returning if there was an parser
110 // error).
111 //
112 // Usage:
113 //     foo = ParseFoo(); // may fail
114 //     RETURN_IF_PARSE_ERROR
115 //
116 //     SAFE_USE(foo);
117 
118 #define RETURN_IF_PARSE_ERROR \
119   if (has_error()) return impl()->NullStatement();
120 
121 // Common base class template shared between parser and pre-parser.
122 // The Impl parameter is the actual class of the parser/pre-parser,
123 // following the Curiously Recurring Template Pattern (CRTP).
124 // The structure of the parser objects is roughly the following:
125 //
126 //   // A structure template containing type definitions, needed to
127 //   // avoid a cyclic dependency.
128 //   template <typename Impl>
129 //   struct ParserTypes;
130 //
131 //   // The parser base object, which should just implement pure
132 //   // parser behavior.  The Impl parameter is the actual derived
133 //   // class (according to CRTP), which implements impure parser
134 //   // behavior.
135 //   template <typename Impl>
136 //   class ParserBase { ... };
137 //
138 //   // And then, for each parser variant (e.g., parser, preparser, etc):
139 //   class Parser;
140 //
141 //   template <>
142 //   class ParserTypes<Parser> { ... };
143 //
144 //   class Parser : public ParserBase<Parser> { ... };
145 //
146 // The parser base object implements pure parsing, according to the
147 // language grammar.  Different parser implementations may exhibit
148 // different parser-driven behavior that is not considered as pure
149 // parsing, e.g., early error detection and reporting, AST generation, etc.
150 
151 // The ParserTypes structure encapsulates the differences in the
152 // types used in parsing methods.  E.g., Parser methods use Expression*
153 // and PreParser methods use PreParserExpression.  For any given parser
154 // implementation class Impl, it is expected to contain the following typedefs:
155 //
156 // template <>
157 // struct ParserTypes<Impl> {
158 //   // Synonyms for ParserBase<Impl> and Impl, respectively.
159 //   typedef Base;
160 //   typedef Impl;
161 //   // Return types for traversing functions.
162 //   typedef Identifier;
163 //   typedef Expression;
164 //   typedef FunctionLiteral;
165 //   typedef ObjectLiteralProperty;
166 //   typedef ClassLiteralProperty;
167 //   typedef ExpressionList;
168 //   typedef ObjectPropertyList;
169 //   typedef ClassPropertyList;
170 //   typedef FormalParameters;
171 //   typedef Statement;
172 //   typedef StatementList;
173 //   typedef Block;
174 //   typedef BreakableStatement;
175 //   typedef ForStatement;
176 //   typedef IterationStatement;
177 //   // For constructing objects returned by the traversing functions.
178 //   typedef Factory;
179 //   // For other implementation-specific tasks.
180 //   typedef Target;
181 //   typedef TargetScope;
182 // };
183 
184 template <typename Impl>
185 struct ParserTypes;
186 
187 enum class ParsePropertyKind : uint8_t {
188   kAccessorGetter,
189   kAccessorSetter,
190   kValue,
191   kShorthand,
192   kAssign,
193   kMethod,
194   kClassField,
195   kShorthandOrClassField,
196   kSpread,
197   kNotSet
198 };
199 
200 template <typename Impl>
201 class ParserBase {
202  public:
203   // Shorten type names defined by ParserTypes<Impl>.
204   using Types = ParserTypes<Impl>;
205   using ExpressionScope = typename v8::internal::ExpressionScope<Types>;
206   using ExpressionParsingScope =
207       typename v8::internal::ExpressionParsingScope<Types>;
208   using AccumulationScope = typename v8::internal::AccumulationScope<Types>;
209   using ArrowHeadParsingScope =
210       typename v8::internal::ArrowHeadParsingScope<Types>;
211   using VariableDeclarationParsingScope =
212       typename v8::internal::VariableDeclarationParsingScope<Types>;
213   using ParameterDeclarationParsingScope =
214       typename v8::internal::ParameterDeclarationParsingScope<Types>;
215 
216   // Return types for traversing functions.
217   using BlockT = typename Types::Block;
218   using BreakableStatementT = typename Types::BreakableStatement;
219   using ClassLiteralPropertyT = typename Types::ClassLiteralProperty;
220   using ClassPropertyListT = typename Types::ClassPropertyList;
221   using ClassStaticElementListT = typename Types::ClassStaticElementList;
222   using ExpressionT = typename Types::Expression;
223   using ExpressionListT = typename Types::ExpressionList;
224   using FormalParametersT = typename Types::FormalParameters;
225   using ForStatementT = typename Types::ForStatement;
226   using FunctionLiteralT = typename Types::FunctionLiteral;
227   using IdentifierT = typename Types::Identifier;
228   using IterationStatementT = typename Types::IterationStatement;
229   using ObjectLiteralPropertyT = typename Types::ObjectLiteralProperty;
230   using ObjectPropertyListT = typename Types::ObjectPropertyList;
231   using StatementT = typename Types::Statement;
232   using StatementListT = typename Types::StatementList;
233   using SuspendExpressionT = typename Types::Suspend;
234   // For constructing objects returned by the traversing functions.
235   using FactoryT = typename Types::Factory;
236   // Other implementation-specific tasks.
237   using FuncNameInferrer = typename Types::FuncNameInferrer;
238   using FuncNameInferrerState = typename Types::FuncNameInferrer::State;
239   using SourceRange = typename Types::SourceRange;
240   using SourceRangeScope = typename Types::SourceRangeScope;
241 
242   // All implementation-specific methods must be called through this.
impl()243   Impl* impl() { return static_cast<Impl*>(this); }
impl()244   const Impl* impl() const { return static_cast<const Impl*>(this); }
245 
ParserBase(Zone * zone,Scanner * scanner,uintptr_t stack_limit,AstValueFactory * ast_value_factory,PendingCompilationErrorHandler * pending_error_handler,RuntimeCallStats * runtime_call_stats,Logger * logger,UnoptimizedCompileFlags flags,bool parsing_on_main_thread)246   ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
247              AstValueFactory* ast_value_factory,
248              PendingCompilationErrorHandler* pending_error_handler,
249              RuntimeCallStats* runtime_call_stats, Logger* logger,
250              UnoptimizedCompileFlags flags, bool parsing_on_main_thread)
251       : scope_(nullptr),
252         original_scope_(nullptr),
253         function_state_(nullptr),
254         fni_(ast_value_factory),
255         ast_value_factory_(ast_value_factory),
256         ast_node_factory_(ast_value_factory, zone),
257         runtime_call_stats_(runtime_call_stats),
258         logger_(logger),
259         parsing_on_main_thread_(parsing_on_main_thread),
260         stack_limit_(stack_limit),
261         pending_error_handler_(pending_error_handler),
262         zone_(zone),
263         expression_scope_(nullptr),
264         scanner_(scanner),
265         flags_(flags),
266         function_literal_id_(0),
267         default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile) {
268     pointer_buffer_.reserve(32);
269     variable_buffer_.reserve(32);
270   }
271 
flags()272   const UnoptimizedCompileFlags& flags() const { return flags_; }
273 
allow_eval_cache()274   bool allow_eval_cache() const { return allow_eval_cache_; }
set_allow_eval_cache(bool allow)275   void set_allow_eval_cache(bool allow) { allow_eval_cache_ = allow; }
276 
has_error()277   V8_INLINE bool has_error() const { return scanner()->has_parser_error(); }
278 
stack_limit()279   uintptr_t stack_limit() const { return stack_limit_; }
280 
set_stack_limit(uintptr_t stack_limit)281   void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
282 
set_default_eager_compile_hint(FunctionLiteral::EagerCompileHint eager_compile_hint)283   void set_default_eager_compile_hint(
284       FunctionLiteral::EagerCompileHint eager_compile_hint) {
285     default_eager_compile_hint_ = eager_compile_hint;
286   }
287 
default_eager_compile_hint()288   FunctionLiteral::EagerCompileHint default_eager_compile_hint() const {
289     return default_eager_compile_hint_;
290   }
291 
loop_nesting_depth()292   int loop_nesting_depth() const {
293     return function_state_->loop_nesting_depth();
294   }
GetNextFunctionLiteralId()295   int GetNextFunctionLiteralId() { return ++function_literal_id_; }
GetLastFunctionLiteralId()296   int GetLastFunctionLiteralId() const { return function_literal_id_; }
297 
SkipFunctionLiterals(int delta)298   void SkipFunctionLiterals(int delta) { function_literal_id_ += delta; }
299 
ResetFunctionLiteralId()300   void ResetFunctionLiteralId() { function_literal_id_ = 0; }
301 
302   // The Zone where the parsing outputs are stored.
main_zone()303   Zone* main_zone() const { return ast_value_factory()->single_parse_zone(); }
304 
305   // The current Zone, which might be the main zone or a temporary Zone.
zone()306   Zone* zone() const { return zone_; }
307 
308  protected:
309   friend class v8::internal::ExpressionScope<ParserTypes<Impl>>;
310   friend class v8::internal::ExpressionParsingScope<ParserTypes<Impl>>;
311   friend class v8::internal::ArrowHeadParsingScope<ParserTypes<Impl>>;
312 
313   enum VariableDeclarationContext {
314     kStatementListItem,
315     kStatement,
316     kForStatement
317   };
318 
319   class ClassLiteralChecker;
320 
321   // ---------------------------------------------------------------------------
322   // BlockState and FunctionState implement the parser's scope stack.
323   // The parser's current scope is in scope_. BlockState and FunctionState
324   // constructors push on the scope stack and the destructors pop. They are also
325   // used to hold the parser's per-funcion state.
326   class BlockState {
327    public:
BlockState(Scope ** scope_stack,Scope * scope)328     BlockState(Scope** scope_stack, Scope* scope)
329         : scope_stack_(scope_stack), outer_scope_(*scope_stack) {
330       *scope_stack_ = scope;
331     }
332 
BlockState(Zone * zone,Scope ** scope_stack)333     BlockState(Zone* zone, Scope** scope_stack)
334         : BlockState(scope_stack,
335                      zone->New<Scope>(zone, *scope_stack, BLOCK_SCOPE)) {}
336 
~BlockState()337     ~BlockState() { *scope_stack_ = outer_scope_; }
338 
339    private:
340     Scope** const scope_stack_;
341     Scope* const outer_scope_;
342   };
343 
344   // ---------------------------------------------------------------------------
345   // Target is a support class to facilitate manipulation of the
346   // Parser's target_stack_ (the stack of potential 'break' and
347   // 'continue' statement targets). Upon construction, a new target is
348   // added; it is removed upon destruction.
349 
350   // |labels| is a list of all labels that can be used as a target for break.
351   // |own_labels| is a list of all labels that an iteration statement is
352   // directly prefixed with, i.e. all the labels that a continue statement in
353   // the body can use to continue this iteration statement. This is always a
354   // subset of |labels|.
355   //
356   // Example: "l1: { l2: if (b) l3: l4: for (;;) s }"
357   // labels() of the Block will be l1.
358   // labels() of the ForStatement will be l2, l3, l4.
359   // own_labels() of the ForStatement will be l3, l4.
360   class Target {
361    public:
362     enum TargetType { TARGET_FOR_ANONYMOUS, TARGET_FOR_NAMED_ONLY };
363 
Target(ParserBase * parser,BreakableStatementT statement,ZonePtrList<const AstRawString> * labels,ZonePtrList<const AstRawString> * own_labels,TargetType target_type)364     Target(ParserBase* parser, BreakableStatementT statement,
365            ZonePtrList<const AstRawString>* labels,
366            ZonePtrList<const AstRawString>* own_labels, TargetType target_type)
367         : stack_(parser->function_state_->target_stack_address()),
368           statement_(statement),
369           labels_(labels),
370           own_labels_(own_labels),
371           target_type_(target_type),
372           previous_(*stack_) {
373       DCHECK_IMPLIES(Impl::IsIterationStatement(statement_),
374                      target_type == Target::TARGET_FOR_ANONYMOUS);
375       DCHECK_IMPLIES(!Impl::IsIterationStatement(statement_),
376                      own_labels == nullptr);
377       *stack_ = this;
378     }
379 
~Target()380     ~Target() { *stack_ = previous_; }
381 
previous()382     const Target* previous() const { return previous_; }
statement()383     const BreakableStatementT statement() const { return statement_; }
labels()384     const ZonePtrList<const AstRawString>* labels() const { return labels_; }
own_labels()385     const ZonePtrList<const AstRawString>* own_labels() const {
386       return own_labels_;
387     }
is_iteration()388     bool is_iteration() const { return Impl::IsIterationStatement(statement_); }
is_target_for_anonymous()389     bool is_target_for_anonymous() const {
390       return target_type_ == TARGET_FOR_ANONYMOUS;
391     }
392 
393    private:
394     Target** const stack_;
395     const BreakableStatementT statement_;
396     const ZonePtrList<const AstRawString>* const labels_;
397     const ZonePtrList<const AstRawString>* const own_labels_;
398     const TargetType target_type_;
399     Target* const previous_;
400   };
401 
target_stack()402   Target* target_stack() { return *function_state_->target_stack_address(); }
403 
LookupBreakTarget(IdentifierT label)404   BreakableStatementT LookupBreakTarget(IdentifierT label) {
405     bool anonymous = impl()->IsNull(label);
406     for (const Target* t = target_stack(); t != nullptr; t = t->previous()) {
407       if ((anonymous && t->is_target_for_anonymous()) ||
408           (!anonymous &&
409            ContainsLabel(t->labels(),
410                          impl()->GetRawNameFromIdentifier(label)))) {
411         return t->statement();
412       }
413     }
414     return impl()->NullStatement();
415   }
416 
LookupContinueTarget(IdentifierT label)417   IterationStatementT LookupContinueTarget(IdentifierT label) {
418     bool anonymous = impl()->IsNull(label);
419     for (const Target* t = target_stack(); t != nullptr; t = t->previous()) {
420       if (!t->is_iteration()) continue;
421 
422       DCHECK(t->is_target_for_anonymous());
423       if (anonymous || ContainsLabel(t->own_labels(),
424                                      impl()->GetRawNameFromIdentifier(label))) {
425         return impl()->AsIterationStatement(t->statement());
426       }
427     }
428     return impl()->NullStatement();
429   }
430 
431   class FunctionState final : public BlockState {
432    public:
433     FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
434                   DeclarationScope* scope);
435     ~FunctionState();
436 
scope()437     DeclarationScope* scope() const { return scope_->AsDeclarationScope(); }
438 
AddProperty()439     void AddProperty() { expected_property_count_++; }
expected_property_count()440     int expected_property_count() { return expected_property_count_; }
441 
DisableOptimization(BailoutReason reason)442     void DisableOptimization(BailoutReason reason) {
443       dont_optimize_reason_ = reason;
444     }
dont_optimize_reason()445     BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }
446 
AddSuspend()447     void AddSuspend() { suspend_count_++; }
suspend_count()448     int suspend_count() const { return suspend_count_; }
CanSuspend()449     bool CanSuspend() const { return suspend_count_ > 0; }
450 
kind()451     FunctionKind kind() const { return scope()->function_kind(); }
452 
next_function_is_likely_called()453     bool next_function_is_likely_called() const {
454       return next_function_is_likely_called_;
455     }
456 
previous_function_was_likely_called()457     bool previous_function_was_likely_called() const {
458       return previous_function_was_likely_called_;
459     }
460 
set_next_function_is_likely_called()461     void set_next_function_is_likely_called() {
462       next_function_is_likely_called_ = !FLAG_max_lazy;
463     }
464 
RecordFunctionOrEvalCall()465     void RecordFunctionOrEvalCall() { contains_function_or_eval_ = true; }
contains_function_or_eval()466     bool contains_function_or_eval() const {
467       return contains_function_or_eval_;
468     }
469 
470     class V8_NODISCARD FunctionOrEvalRecordingScope {
471      public:
FunctionOrEvalRecordingScope(FunctionState * state)472       explicit FunctionOrEvalRecordingScope(FunctionState* state)
473           : state_and_prev_value_(state, state->contains_function_or_eval_) {
474         state->contains_function_or_eval_ = false;
475       }
~FunctionOrEvalRecordingScope()476       ~FunctionOrEvalRecordingScope() {
477         bool found = state_and_prev_value_->contains_function_or_eval_;
478         if (!found) {
479           state_and_prev_value_->contains_function_or_eval_ =
480               state_and_prev_value_.GetPayload();
481         }
482       }
483 
484      private:
485       base::PointerWithPayload<FunctionState, bool, 1> state_and_prev_value_;
486     };
487 
488     class V8_NODISCARD LoopScope final {
489      public:
LoopScope(FunctionState * function_state)490       explicit LoopScope(FunctionState* function_state)
491           : function_state_(function_state) {
492         function_state_->loop_nesting_depth_++;
493       }
494 
~LoopScope()495       ~LoopScope() { function_state_->loop_nesting_depth_--; }
496 
497      private:
498       FunctionState* function_state_;
499     };
500 
loop_nesting_depth()501     int loop_nesting_depth() const { return loop_nesting_depth_; }
502 
target_stack_address()503     Target** target_stack_address() { return &target_stack_; }
504 
505    private:
506     // Properties count estimation.
507     int expected_property_count_;
508 
509     // How many suspends are needed for this function.
510     int suspend_count_;
511 
512     // How deeply nested we currently are in this function.
513     int loop_nesting_depth_ = 0;
514 
515     FunctionState** function_state_stack_;
516     FunctionState* outer_function_state_;
517     DeclarationScope* scope_;
518     Target* target_stack_ = nullptr;  // for break, continue statements
519 
520     // A reason, if any, why this function should not be optimized.
521     BailoutReason dont_optimize_reason_;
522 
523     // Record whether the next (=== immediately following) function literal is
524     // preceded by a parenthesis / exclamation mark. Also record the previous
525     // state.
526     // These are managed by the FunctionState constructor; the caller may only
527     // call set_next_function_is_likely_called.
528     bool next_function_is_likely_called_;
529     bool previous_function_was_likely_called_;
530 
531     // Track if a function or eval occurs within this FunctionState
532     bool contains_function_or_eval_;
533 
534     friend Impl;
535   };
536 
537   struct DeclarationDescriptor {
538     VariableMode mode;
539     VariableKind kind;
540     int declaration_pos;
541     int initialization_pos;
542   };
543 
544   struct DeclarationParsingResult {
545     struct Declaration {
DeclarationDeclarationParsingResult::Declaration546       Declaration(ExpressionT pattern, ExpressionT initializer)
547           : pattern(pattern), initializer(initializer) {
548         DCHECK_IMPLIES(Impl::IsNull(pattern), Impl::IsNull(initializer));
549       }
550 
551       ExpressionT pattern;
552       ExpressionT initializer;
553       int value_beg_pos = kNoSourcePosition;
554     };
555 
DeclarationParsingResultDeclarationParsingResult556     DeclarationParsingResult()
557         : first_initializer_loc(Scanner::Location::invalid()),
558           bindings_loc(Scanner::Location::invalid()) {}
559 
560     DeclarationDescriptor descriptor;
561     std::vector<Declaration> declarations;
562     Scanner::Location first_initializer_loc;
563     Scanner::Location bindings_loc;
564   };
565 
566   struct CatchInfo {
567    public:
CatchInfoCatchInfo568     explicit CatchInfo(ParserBase* parser)
569         : pattern(parser->impl()->NullExpression()),
570           variable(nullptr),
571           scope(nullptr) {}
572     ExpressionT pattern;
573     Variable* variable;
574     Scope* scope;
575   };
576 
577   struct ForInfo {
578    public:
ForInfoForInfo579     explicit ForInfo(ParserBase* parser)
580         : bound_names(1, parser->zone()),
581           mode(ForEachStatement::ENUMERATE),
582           position(kNoSourcePosition),
583           parsing_result() {}
584     ZonePtrList<const AstRawString> bound_names;
585     ForEachStatement::VisitMode mode;
586     int position;
587     DeclarationParsingResult parsing_result;
588   };
589 
590   struct ClassInfo {
591    public:
ClassInfoClassInfo592     explicit ClassInfo(ParserBase* parser)
593         : extends(parser->impl()->NullExpression()),
594           public_members(parser->impl()->NewClassPropertyList(4)),
595           private_members(parser->impl()->NewClassPropertyList(4)),
596           static_elements(parser->impl()->NewClassStaticElementList(4)),
597           instance_fields(parser->impl()->NewClassPropertyList(4)),
598           constructor(parser->impl()->NullExpression()),
599           has_seen_constructor(false),
600           has_static_computed_names(false),
601           has_static_elements(false),
602           has_static_private_methods(false),
603           has_static_blocks(false),
604           has_instance_members(false),
605           requires_brand(false),
606           is_anonymous(false),
607           has_private_methods(false),
608           static_elements_scope(nullptr),
609           instance_members_scope(nullptr),
610           computed_field_count(0) {}
611     ExpressionT extends;
612     ClassPropertyListT public_members;
613     ClassPropertyListT private_members;
614     ClassStaticElementListT static_elements;
615     ClassPropertyListT instance_fields;
616     FunctionLiteralT constructor;
617 
618     bool has_seen_constructor;
619     bool has_static_computed_names;
620     bool has_static_elements;
621     bool has_static_private_methods;
622     bool has_static_blocks;
623     bool has_instance_members;
624     bool requires_brand;
625     bool is_anonymous;
626     bool has_private_methods;
627     DeclarationScope* static_elements_scope;
628     DeclarationScope* instance_members_scope;
629     int computed_field_count;
630     Variable* home_object_variable = nullptr;
631     Variable* static_home_object_variable = nullptr;
632   };
633 
634   enum class PropertyPosition { kObjectLiteral, kClassLiteral };
635   struct ParsePropertyInfo {
636    public:
637     explicit ParsePropertyInfo(ParserBase* parser,
638                                AccumulationScope* accumulation_scope = nullptr)
accumulation_scopeParsePropertyInfo639         : accumulation_scope(accumulation_scope),
640           name(parser->impl()->NullIdentifier()),
641           position(PropertyPosition::kClassLiteral),
642           function_flags(ParseFunctionFlag::kIsNormal),
643           kind(ParsePropertyKind::kNotSet),
644           is_computed_name(false),
645           is_private(false),
646           is_static(false),
647           is_rest(false) {}
648 
ParsePropertyKindFromTokenParsePropertyInfo649     bool ParsePropertyKindFromToken(Token::Value token) {
650       // This returns true, setting the property kind, iff the given token is
651       // one which must occur after a property name, indicating that the
652       // previous token was in fact a name and not a modifier (like the "get" in
653       // "get x").
654       switch (token) {
655         case Token::COLON:
656           kind = ParsePropertyKind::kValue;
657           return true;
658         case Token::COMMA:
659           kind = ParsePropertyKind::kShorthand;
660           return true;
661         case Token::RBRACE:
662           kind = ParsePropertyKind::kShorthandOrClassField;
663           return true;
664         case Token::ASSIGN:
665           kind = ParsePropertyKind::kAssign;
666           return true;
667         case Token::LPAREN:
668           kind = ParsePropertyKind::kMethod;
669           return true;
670         case Token::MUL:
671         case Token::SEMICOLON:
672           kind = ParsePropertyKind::kClassField;
673           return true;
674         default:
675           break;
676       }
677       return false;
678     }
679 
680     AccumulationScope* accumulation_scope;
681     IdentifierT name;
682     PropertyPosition position;
683     ParseFunctionFlags function_flags;
684     ParsePropertyKind kind;
685     bool is_computed_name;
686     bool is_private;
687     bool is_static;
688     bool is_rest;
689   };
690 
DeclareLabel(ZonePtrList<const AstRawString> ** labels,ZonePtrList<const AstRawString> ** own_labels,const AstRawString * label)691   void DeclareLabel(ZonePtrList<const AstRawString>** labels,
692                     ZonePtrList<const AstRawString>** own_labels,
693                     const AstRawString* label) {
694     if (ContainsLabel(*labels, label) || TargetStackContainsLabel(label)) {
695       ReportMessage(MessageTemplate::kLabelRedeclaration, label);
696       return;
697     }
698 
699     // Add {label} to both {labels} and {own_labels}.
700     if (*labels == nullptr) {
701       DCHECK_NULL(*own_labels);
702       *labels =
703           zone()->template New<ZonePtrList<const AstRawString>>(1, zone());
704       *own_labels =
705           zone()->template New<ZonePtrList<const AstRawString>>(1, zone());
706     } else {
707       if (*own_labels == nullptr) {
708         *own_labels =
709             zone()->template New<ZonePtrList<const AstRawString>>(1, zone());
710       }
711     }
712     (*labels)->Add(label, zone());
713     (*own_labels)->Add(label, zone());
714   }
715 
ContainsLabel(const ZonePtrList<const AstRawString> * labels,const AstRawString * label)716   bool ContainsLabel(const ZonePtrList<const AstRawString>* labels,
717                      const AstRawString* label) {
718     DCHECK_NOT_NULL(label);
719     if (labels != nullptr) {
720       for (int i = labels->length(); i-- > 0;) {
721         if (labels->at(i) == label) return true;
722       }
723     }
724     return false;
725   }
726 
TargetStackContainsLabel(const AstRawString * label)727   bool TargetStackContainsLabel(const AstRawString* label) {
728     for (const Target* t = target_stack(); t != nullptr; t = t->previous()) {
729       if (ContainsLabel(t->labels(), label)) return true;
730     }
731     return false;
732   }
733 
ClassPropertyKindFor(ParsePropertyKind kind)734   ClassLiteralProperty::Kind ClassPropertyKindFor(ParsePropertyKind kind) {
735     switch (kind) {
736       case ParsePropertyKind::kAccessorGetter:
737         return ClassLiteralProperty::GETTER;
738       case ParsePropertyKind::kAccessorSetter:
739         return ClassLiteralProperty::SETTER;
740       case ParsePropertyKind::kMethod:
741         return ClassLiteralProperty::METHOD;
742       case ParsePropertyKind::kClassField:
743         return ClassLiteralProperty::FIELD;
744       default:
745         // Only returns for deterministic kinds
746         UNREACHABLE();
747     }
748   }
749 
GetVariableMode(ClassLiteralProperty::Kind kind)750   VariableMode GetVariableMode(ClassLiteralProperty::Kind kind) {
751     switch (kind) {
752       case ClassLiteralProperty::Kind::FIELD:
753         return VariableMode::kConst;
754       case ClassLiteralProperty::Kind::METHOD:
755         return VariableMode::kPrivateMethod;
756       case ClassLiteralProperty::Kind::GETTER:
757         return VariableMode::kPrivateGetterOnly;
758       case ClassLiteralProperty::Kind::SETTER:
759         return VariableMode::kPrivateSetterOnly;
760     }
761   }
762 
ClassFieldVariableName(AstValueFactory * ast_value_factory,int index)763   const AstRawString* ClassFieldVariableName(AstValueFactory* ast_value_factory,
764                                              int index) {
765     std::string name = ".class-field-" + std::to_string(index);
766     return ast_value_factory->GetOneByteString(name.c_str());
767   }
768 
NewScriptScope(REPLMode repl_mode)769   DeclarationScope* NewScriptScope(REPLMode repl_mode) const {
770     return zone()->template New<DeclarationScope>(zone(), ast_value_factory(),
771                                                   repl_mode);
772   }
773 
NewVarblockScope()774   DeclarationScope* NewVarblockScope() const {
775     return zone()->template New<DeclarationScope>(zone(), scope(), BLOCK_SCOPE);
776   }
777 
NewModuleScope(DeclarationScope * parent)778   ModuleScope* NewModuleScope(DeclarationScope* parent) const {
779     return zone()->template New<ModuleScope>(parent, ast_value_factory());
780   }
781 
NewEvalScope(Scope * parent)782   DeclarationScope* NewEvalScope(Scope* parent) const {
783     return zone()->template New<DeclarationScope>(zone(), parent, EVAL_SCOPE);
784   }
785 
NewClassScope(Scope * parent,bool is_anonymous)786   ClassScope* NewClassScope(Scope* parent, bool is_anonymous) const {
787     return zone()->template New<ClassScope>(zone(), parent, is_anonymous);
788   }
789 
NewBlockScopeForObjectLiteral()790   Scope* NewBlockScopeForObjectLiteral() {
791     Scope* scope = NewScope(BLOCK_SCOPE);
792     scope->set_is_block_scope_for_object_literal();
793     return scope;
794   }
795 
NewScope(ScopeType scope_type)796   Scope* NewScope(ScopeType scope_type) const {
797     return NewScopeWithParent(scope(), scope_type);
798   }
799 
800   // This constructor should only be used when absolutely necessary. Most scopes
801   // should automatically use scope() as parent, and be fine with
802   // NewScope(ScopeType) above.
NewScopeWithParent(Scope * parent,ScopeType scope_type)803   Scope* NewScopeWithParent(Scope* parent, ScopeType scope_type) const {
804     // Must always use the specific constructors for the blocklisted scope
805     // types.
806     DCHECK_NE(FUNCTION_SCOPE, scope_type);
807     DCHECK_NE(SCRIPT_SCOPE, scope_type);
808     DCHECK_NE(MODULE_SCOPE, scope_type);
809     DCHECK_NOT_NULL(parent);
810     return zone()->template New<Scope>(zone(), parent, scope_type);
811   }
812 
813   // Creates a function scope that always allocates in zone(). The function
814   // scope itself is either allocated in zone() or in target_zone if one is
815   // passed in.
816   DeclarationScope* NewFunctionScope(FunctionKind kind,
817                                      Zone* parse_zone = nullptr) const {
818     DCHECK(ast_value_factory());
819     if (parse_zone == nullptr) parse_zone = zone();
820     DeclarationScope* result = zone()->template New<DeclarationScope>(
821         parse_zone, scope(), FUNCTION_SCOPE, kind);
822 
823     // Record presence of an inner function scope
824     function_state_->RecordFunctionOrEvalCall();
825 
826     // TODO(verwaest): Move into the DeclarationScope constructor.
827     if (!IsArrowFunction(kind)) {
828       result->DeclareDefaultFunctionVariables(ast_value_factory());
829     }
830     return result;
831   }
832 
GetDeclarationScope()833   V8_INLINE DeclarationScope* GetDeclarationScope() const {
834     return scope()->GetDeclarationScope();
835   }
GetClosureScope()836   V8_INLINE DeclarationScope* GetClosureScope() const {
837     return scope()->GetClosureScope();
838   }
839 
NewRawVariable(const AstRawString * name,int pos)840   VariableProxy* NewRawVariable(const AstRawString* name, int pos) {
841     return factory()->ast_node_factory()->NewVariableProxy(
842         name, NORMAL_VARIABLE, pos);
843   }
844 
NewUnresolved(const AstRawString * name)845   VariableProxy* NewUnresolved(const AstRawString* name) {
846     return scope()->NewUnresolved(factory()->ast_node_factory(), name,
847                                   scanner()->location().beg_pos);
848   }
849 
850   VariableProxy* NewUnresolved(const AstRawString* name, int begin_pos,
851                                VariableKind kind = NORMAL_VARIABLE) {
852     return scope()->NewUnresolved(factory()->ast_node_factory(), name,
853                                   begin_pos, kind);
854   }
855 
scanner()856   Scanner* scanner() const { return scanner_; }
ast_value_factory()857   AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
position()858   int position() const { return scanner_->location().beg_pos; }
peek_position()859   int peek_position() const { return scanner_->peek_location().beg_pos; }
end_position()860   int end_position() const { return scanner_->location().end_pos; }
peek_end_position()861   int peek_end_position() const { return scanner_->peek_location().end_pos; }
stack_overflow()862   bool stack_overflow() const {
863     return pending_error_handler()->stack_overflow();
864   }
set_stack_overflow()865   void set_stack_overflow() {
866     scanner_->set_parser_error();
867     pending_error_handler()->set_stack_overflow();
868   }
CheckStackOverflow()869   void CheckStackOverflow() {
870     // Any further calls to Next or peek will return the illegal token.
871     if (GetCurrentStackPosition() < stack_limit_) set_stack_overflow();
872   }
873 
peek()874   V8_INLINE Token::Value peek() { return scanner()->peek(); }
875 
876   // Returns the position past the following semicolon (if it exists), and the
877   // position past the end of the current token otherwise.
PositionAfterSemicolon()878   int PositionAfterSemicolon() {
879     return (peek() == Token::SEMICOLON) ? peek_end_position() : end_position();
880   }
881 
PeekAhead()882   V8_INLINE Token::Value PeekAhead() { return scanner()->PeekAhead(); }
883 
Next()884   V8_INLINE Token::Value Next() { return scanner()->Next(); }
885 
Consume(Token::Value token)886   V8_INLINE void Consume(Token::Value token) {
887     Token::Value next = scanner()->Next();
888     USE(next);
889     USE(token);
890     DCHECK_IMPLIES(!has_error(), next == token);
891   }
892 
Check(Token::Value token)893   V8_INLINE bool Check(Token::Value token) {
894     Token::Value next = scanner()->peek();
895     if (next == token) {
896       Consume(next);
897       return true;
898     }
899     return false;
900   }
901 
Expect(Token::Value token)902   void Expect(Token::Value token) {
903     Token::Value next = Next();
904     if (V8_UNLIKELY(next != token)) {
905       ReportUnexpectedToken(next);
906     }
907   }
908 
ExpectSemicolon()909   void ExpectSemicolon() {
910     // Check for automatic semicolon insertion according to
911     // the rules given in ECMA-262, section 7.9, page 21.
912     Token::Value tok = peek();
913     if (V8_LIKELY(tok == Token::SEMICOLON)) {
914       Next();
915       return;
916     }
917     if (V8_LIKELY(scanner()->HasLineTerminatorBeforeNext() ||
918                   Token::IsAutoSemicolon(tok))) {
919       return;
920     }
921 
922     if (scanner()->current_token() == Token::AWAIT && !is_async_function()) {
923       if (flags().parsing_while_debugging() == ParsingWhileDebugging::kYes) {
924         ReportMessageAt(scanner()->location(),
925                         MessageTemplate::kAwaitNotInDebugEvaluate);
926       } else {
927         ReportMessageAt(scanner()->location(),
928                         MessageTemplate::kAwaitNotInAsyncContext);
929       }
930       return;
931     }
932 
933     ReportUnexpectedToken(Next());
934   }
935 
peek_any_identifier()936   bool peek_any_identifier() { return Token::IsAnyIdentifier(peek()); }
937 
PeekContextualKeyword(const AstRawString * name)938   bool PeekContextualKeyword(const AstRawString* name) {
939     return peek() == Token::IDENTIFIER &&
940            !scanner()->next_literal_contains_escapes() &&
941            scanner()->NextSymbol(ast_value_factory()) == name;
942   }
943 
CheckContextualKeyword(const AstRawString * name)944   bool CheckContextualKeyword(const AstRawString* name) {
945     if (PeekContextualKeyword(name)) {
946       Consume(Token::IDENTIFIER);
947       return true;
948     }
949     return false;
950   }
951 
952   void ExpectContextualKeyword(const AstRawString* name,
953                                const char* fullname = nullptr, int pos = -1) {
954     Expect(Token::IDENTIFIER);
955     if (V8_UNLIKELY(scanner()->CurrentSymbol(ast_value_factory()) != name)) {
956       ReportUnexpectedToken(scanner()->current_token());
957     }
958     if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
959       const char* full = fullname == nullptr
960                              ? reinterpret_cast<const char*>(name->raw_data())
961                              : fullname;
962       int start = pos == -1 ? position() : pos;
963       impl()->ReportMessageAt(Scanner::Location(start, end_position()),
964                               MessageTemplate::kInvalidEscapedMetaProperty,
965                               full);
966     }
967   }
968 
CheckInOrOf(ForEachStatement::VisitMode * visit_mode)969   bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode) {
970     if (Check(Token::IN)) {
971       *visit_mode = ForEachStatement::ENUMERATE;
972       return true;
973     } else if (CheckContextualKeyword(ast_value_factory()->of_string())) {
974       *visit_mode = ForEachStatement::ITERATE;
975       return true;
976     }
977     return false;
978   }
979 
PeekInOrOf()980   bool PeekInOrOf() {
981     return peek() == Token::IN ||
982            PeekContextualKeyword(ast_value_factory()->of_string());
983   }
984 
985   // Checks whether an octal literal was last seen between beg_pos and end_pos.
986   // Only called for strict mode strings.
CheckStrictOctalLiteral(int beg_pos,int end_pos)987   void CheckStrictOctalLiteral(int beg_pos, int end_pos) {
988     Scanner::Location octal = scanner()->octal_position();
989     if (octal.IsValid() && beg_pos <= octal.beg_pos &&
990         octal.end_pos <= end_pos) {
991       MessageTemplate message = scanner()->octal_message();
992       DCHECK_NE(message, MessageTemplate::kNone);
993       impl()->ReportMessageAt(octal, message);
994       scanner()->clear_octal_position();
995       if (message == MessageTemplate::kStrictDecimalWithLeadingZero) {
996         impl()->CountUsage(v8::Isolate::kDecimalWithLeadingZeroInStrictMode);
997       }
998     }
999   }
1000 
1001   // Checks if an octal literal or an invalid hex or unicode escape sequence
1002   // appears in the current template literal token. In the presence of such,
1003   // either returns false or reports an error, depending on should_throw.
1004   // Otherwise returns true.
CheckTemplateEscapes(bool should_throw)1005   inline bool CheckTemplateEscapes(bool should_throw) {
1006     DCHECK(Token::IsTemplate(scanner()->current_token()));
1007     if (!scanner()->has_invalid_template_escape()) return true;
1008 
1009     // Handle error case(s)
1010     if (should_throw) {
1011       impl()->ReportMessageAt(scanner()->invalid_template_escape_location(),
1012                               scanner()->invalid_template_escape_message());
1013     }
1014     scanner()->clear_invalid_template_escape_message();
1015     return should_throw;
1016   }
1017 
1018   ExpressionT ParsePossibleDestructuringSubPattern(AccumulationScope* scope);
1019   void ClassifyParameter(IdentifierT parameter, int beg_pos, int end_pos);
1020   void ClassifyArrowParameter(AccumulationScope* accumulation_scope,
1021                               int position, ExpressionT parameter);
1022 
1023   // Checking the name of a function literal. This has to be done after parsing
1024   // the function, since the function can declare itself strict.
CheckFunctionName(LanguageMode language_mode,IdentifierT function_name,FunctionNameValidity function_name_validity,const Scanner::Location & function_name_loc)1025   void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
1026                          FunctionNameValidity function_name_validity,
1027                          const Scanner::Location& function_name_loc) {
1028     if (impl()->IsNull(function_name)) return;
1029     if (function_name_validity == kSkipFunctionNameCheck) return;
1030     // The function name needs to be checked in strict mode.
1031     if (is_sloppy(language_mode)) return;
1032 
1033     if (impl()->IsEvalOrArguments(function_name)) {
1034       impl()->ReportMessageAt(function_name_loc,
1035                               MessageTemplate::kStrictEvalArguments);
1036       return;
1037     }
1038     if (function_name_validity == kFunctionNameIsStrictReserved) {
1039       impl()->ReportMessageAt(function_name_loc,
1040                               MessageTemplate::kUnexpectedStrictReserved);
1041       return;
1042     }
1043   }
1044 
factory()1045   typename Types::Factory* factory() { return &ast_node_factory_; }
1046 
GetReceiverScope()1047   DeclarationScope* GetReceiverScope() const {
1048     return scope()->GetReceiverScope();
1049   }
language_mode()1050   LanguageMode language_mode() { return scope()->language_mode(); }
RaiseLanguageMode(LanguageMode mode)1051   void RaiseLanguageMode(LanguageMode mode) {
1052     LanguageMode old = scope()->language_mode();
1053     impl()->SetLanguageMode(scope(), old > mode ? old : mode);
1054   }
is_generator()1055   bool is_generator() const {
1056     return IsGeneratorFunction(function_state_->kind());
1057   }
is_async_function()1058   bool is_async_function() const {
1059     return IsAsyncFunction(function_state_->kind());
1060   }
is_async_generator()1061   bool is_async_generator() const {
1062     return IsAsyncGeneratorFunction(function_state_->kind());
1063   }
is_resumable()1064   bool is_resumable() const {
1065     return IsResumableFunction(function_state_->kind());
1066   }
is_await_allowed()1067   bool is_await_allowed() const {
1068     return is_async_function() || IsModule(function_state_->kind());
1069   }
is_await_as_identifier_disallowed()1070   bool is_await_as_identifier_disallowed() {
1071     return flags().is_module() ||
1072            IsAwaitAsIdentifierDisallowed(function_state_->kind());
1073   }
pending_error_handler()1074   const PendingCompilationErrorHandler* pending_error_handler() const {
1075     return pending_error_handler_;
1076   }
pending_error_handler()1077   PendingCompilationErrorHandler* pending_error_handler() {
1078     return pending_error_handler_;
1079   }
1080 
1081   // Report syntax errors.
1082   template <typename... Ts>
ReportMessage(MessageTemplate message,const Ts &...args)1083   V8_NOINLINE void ReportMessage(MessageTemplate message, const Ts&... args) {
1084     ReportMessageAt(scanner()->location(), message, args...);
1085   }
1086 
1087   template <typename... Ts>
ReportMessageAt(Scanner::Location source_location,MessageTemplate message,const Ts &...args)1088   V8_NOINLINE void ReportMessageAt(Scanner::Location source_location,
1089                                    MessageTemplate message, const Ts&... args) {
1090     impl()->pending_error_handler()->ReportMessageAt(
1091         source_location.beg_pos, source_location.end_pos, message, args...);
1092     scanner()->set_parser_error();
1093   }
1094 
ReportMessageAt(Scanner::Location source_location,MessageTemplate message,const PreParserIdentifier & arg0)1095   V8_NOINLINE void ReportMessageAt(Scanner::Location source_location,
1096                                    MessageTemplate message,
1097                                    const PreParserIdentifier& arg0) {
1098     ReportMessageAt(source_location, message,
1099                     impl()->PreParserIdentifierToAstRawString(arg0));
1100   }
1101 
1102   V8_NOINLINE void ReportUnexpectedToken(Token::Value token);
1103 
ValidateFormalParameters(LanguageMode language_mode,const FormalParametersT & parameters,bool allow_duplicates)1104   void ValidateFormalParameters(LanguageMode language_mode,
1105                                 const FormalParametersT& parameters,
1106                                 bool allow_duplicates) {
1107     if (!allow_duplicates) parameters.ValidateDuplicate(impl());
1108     if (is_strict(language_mode)) parameters.ValidateStrictMode(impl());
1109   }
1110 
1111   // Needs to be called if the reference needs to be available from the current
1112   // point. It causes the receiver to be context allocated if necessary.
1113   // Returns the receiver variable that we're referencing.
UseThis()1114   V8_INLINE Variable* UseThis() {
1115     DeclarationScope* closure_scope = scope()->GetClosureScope();
1116     DeclarationScope* receiver_scope = closure_scope->GetReceiverScope();
1117     Variable* var = receiver_scope->receiver();
1118     var->set_is_used();
1119     if (closure_scope == receiver_scope) {
1120       // It's possible that we're parsing the head of an arrow function, in
1121       // which case we haven't realized yet that closure_scope !=
1122       // receiver_scope. Mark through the ExpressionScope for now.
1123       expression_scope()->RecordThisUse();
1124     } else {
1125       closure_scope->set_has_this_reference();
1126       var->ForceContextAllocation();
1127     }
1128     return var;
1129   }
1130 
1131   V8_INLINE IdentifierT ParseAndClassifyIdentifier(Token::Value token);
1132 
1133   // Similar logic to ParseAndClassifyIdentifier but the identifier is
1134   // already parsed in prop_info. Returns false if this is an invalid
1135   // identifier or an invalid use of the "arguments" keyword.
1136   V8_INLINE bool ClassifyPropertyIdentifier(Token::Value token,
1137                                             ParsePropertyInfo* prop_info);
1138   // Parses an identifier or a strict mode future reserved word. Allows passing
1139   // in function_kind for the case of parsing the identifier in a function
1140   // expression, where the relevant "function_kind" bit is of the function being
1141   // parsed, not the containing function.
1142   V8_INLINE IdentifierT ParseIdentifier(FunctionKind function_kind);
ParseIdentifier()1143   V8_INLINE IdentifierT ParseIdentifier() {
1144     return ParseIdentifier(function_state_->kind());
1145   }
1146   // Same as above but additionally disallows 'eval' and 'arguments' in strict
1147   // mode.
1148   IdentifierT ParseNonRestrictedIdentifier();
1149 
1150   // This method should be used to ambiguously parse property names that can
1151   // become destructuring identifiers.
1152   V8_INLINE IdentifierT ParsePropertyName();
1153 
1154   ExpressionT ParsePropertyOrPrivatePropertyName();
1155 
GetNextSymbolForRegExpLiteral()1156   const AstRawString* GetNextSymbolForRegExpLiteral() const {
1157     return scanner()->NextSymbol(ast_value_factory());
1158   }
1159   bool ValidateRegExpLiteral(const AstRawString* pattern, RegExpFlags flags,
1160                              RegExpError* regexp_error);
1161   ExpressionT ParseRegExpLiteral();
1162 
1163   ExpressionT ParseBindingPattern();
1164   ExpressionT ParsePrimaryExpression();
1165 
1166   // Use when parsing an expression that is known to not be a pattern or part of
1167   // a pattern.
1168   V8_INLINE ExpressionT ParseExpression();
1169   V8_INLINE ExpressionT ParseAssignmentExpression();
1170 
1171   // These methods do not wrap the parsing of the expression inside a new
1172   // expression_scope; they use the outer expression_scope instead. They should
1173   // be used whenever we're parsing something with the "cover" grammar that
1174   // recognizes both patterns and non-patterns (which roughly corresponds to
1175   // what's inside the parentheses generated by the symbol
1176   // "CoverParenthesizedExpressionAndArrowParameterList" in the ES 2017
1177   // specification).
1178   ExpressionT ParseExpressionCoverGrammar();
1179   ExpressionT ParseAssignmentExpressionCoverGrammar();
1180 
1181   ExpressionT ParseArrowParametersWithRest(ExpressionListT* list,
1182                                            AccumulationScope* scope,
1183                                            int seen_variables);
1184 
1185   ExpressionT ParseArrayLiteral();
1186 
IsAccessor(ParsePropertyKind kind)1187   inline static bool IsAccessor(ParsePropertyKind kind) {
1188     return base::IsInRange(kind, ParsePropertyKind::kAccessorGetter,
1189                            ParsePropertyKind::kAccessorSetter);
1190   }
1191 
1192   ExpressionT ParseProperty(ParsePropertyInfo* prop_info);
1193   ExpressionT ParseObjectLiteral();
1194   ClassLiteralPropertyT ParseClassPropertyDefinition(
1195       ClassInfo* class_info, ParsePropertyInfo* prop_info, bool has_extends);
1196   void CheckClassFieldName(IdentifierT name, bool is_static);
1197   void CheckClassMethodName(IdentifierT name, ParsePropertyKind type,
1198                             ParseFunctionFlags flags, bool is_static,
1199                             bool* has_seen_constructor);
1200   ExpressionT ParseMemberInitializer(ClassInfo* class_info, int beg_pos,
1201                                      bool is_static);
1202   BlockT ParseClassStaticBlock(ClassInfo* class_info);
1203   ObjectLiteralPropertyT ParseObjectPropertyDefinition(
1204       ParsePropertyInfo* prop_info, bool* has_seen_proto);
1205   void ParseArguments(
1206       ExpressionListT* args, bool* has_spread,
1207       ParsingArrowHeadFlag maybe_arrow = kCertainlyNotArrowHead);
1208 
1209   ExpressionT ParseYieldExpression();
1210   V8_INLINE ExpressionT ParseConditionalExpression();
1211   ExpressionT ParseConditionalContinuation(ExpressionT expression, int pos);
1212   ExpressionT ParseLogicalExpression();
1213   ExpressionT ParseCoalesceExpression(ExpressionT expression);
1214   ExpressionT ParseBinaryContinuation(ExpressionT x, int prec, int prec1);
1215   V8_INLINE ExpressionT ParseBinaryExpression(int prec);
1216   ExpressionT ParseUnaryOrPrefixExpression();
1217   ExpressionT ParseAwaitExpression();
1218   V8_INLINE ExpressionT ParseUnaryExpression();
1219   V8_INLINE ExpressionT ParsePostfixExpression();
1220   V8_NOINLINE ExpressionT ParsePostfixContinuation(ExpressionT expression,
1221                                                    int lhs_beg_pos);
1222   V8_INLINE ExpressionT ParseLeftHandSideExpression();
1223   ExpressionT ParseLeftHandSideContinuation(ExpressionT expression);
1224   ExpressionT ParseMemberWithPresentNewPrefixesExpression();
1225   ExpressionT ParseFunctionExpression();
1226   V8_INLINE ExpressionT ParseMemberExpression();
1227   V8_INLINE ExpressionT
ParseMemberExpressionContinuation(ExpressionT expression)1228   ParseMemberExpressionContinuation(ExpressionT expression) {
1229     if (!Token::IsMember(peek())) return expression;
1230     return DoParseMemberExpressionContinuation(expression);
1231   }
1232   ExpressionT DoParseMemberExpressionContinuation(ExpressionT expression);
1233 
1234   ExpressionT ParseArrowFunctionLiteral(const FormalParametersT& parameters);
1235   void ParseAsyncFunctionBody(Scope* scope, StatementListT* body);
1236   ExpressionT ParseAsyncFunctionLiteral();
1237   ExpressionT ParseClassExpression(Scope* outer_scope);
1238   ExpressionT ParseClassLiteral(Scope* outer_scope, IdentifierT name,
1239                                 Scanner::Location class_name_location,
1240                                 bool name_is_strict_reserved,
1241                                 int class_token_pos);
1242 
1243   ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool tagged);
1244   ExpressionT ParseSuperExpression();
1245   ExpressionT ParseImportExpressions();
1246   ExpressionT ParseNewTargetExpression();
1247 
1248   V8_INLINE void ParseFormalParameter(FormalParametersT* parameters);
1249   void ParseFormalParameterList(FormalParametersT* parameters);
1250   void CheckArityRestrictions(int param_count, FunctionKind function_type,
1251                               bool has_rest, int formals_start_pos,
1252                               int formals_end_pos);
1253 
1254   void ParseVariableDeclarations(VariableDeclarationContext var_context,
1255                                  DeclarationParsingResult* parsing_result,
1256                                  ZonePtrList<const AstRawString>* names);
1257   StatementT ParseAsyncFunctionDeclaration(
1258       ZonePtrList<const AstRawString>* names, bool default_export);
1259   StatementT ParseFunctionDeclaration();
1260   StatementT ParseHoistableDeclaration(ZonePtrList<const AstRawString>* names,
1261                                        bool default_export);
1262   StatementT ParseHoistableDeclaration(int pos, ParseFunctionFlags flags,
1263                                        ZonePtrList<const AstRawString>* names,
1264                                        bool default_export);
1265   StatementT ParseClassDeclaration(ZonePtrList<const AstRawString>* names,
1266                                    bool default_export);
1267   StatementT ParseNativeDeclaration();
1268 
1269   // Whether we're parsing a single-expression arrow function or something else.
1270   enum class FunctionBodyType { kExpression, kBlock };
1271   // Consumes the ending }.
1272   void ParseFunctionBody(StatementListT* body, IdentifierT function_name,
1273                          int pos, const FormalParametersT& parameters,
1274                          FunctionKind kind,
1275                          FunctionSyntaxKind function_syntax_kind,
1276                          FunctionBodyType body_type);
1277 
1278   // Check if the scope has conflicting var/let declarations from different
1279   // scopes. This covers for example
1280   //
1281   // function f() { { { var x; } let x; } }
1282   // function g() { { var x; let x; } }
1283   //
1284   // The var declarations are hoisted to the function scope, but originate from
1285   // a scope where the name has also been let bound or the var declaration is
1286   // hoisted over such a scope.
CheckConflictingVarDeclarations(DeclarationScope * scope)1287   void CheckConflictingVarDeclarations(DeclarationScope* scope) {
1288     if (has_error()) return;
1289     bool allowed_catch_binding_var_redeclaration = false;
1290     Declaration* decl = scope->CheckConflictingVarDeclarations(
1291         &allowed_catch_binding_var_redeclaration);
1292     if (allowed_catch_binding_var_redeclaration) {
1293       impl()->CountUsage(v8::Isolate::kVarRedeclaredCatchBinding);
1294     }
1295     if (decl != nullptr) {
1296       // In ES6, conflicting variable bindings are early errors.
1297       const AstRawString* name = decl->var()->raw_name();
1298       int position = decl->position();
1299       Scanner::Location location =
1300           position == kNoSourcePosition
1301               ? Scanner::Location::invalid()
1302               : Scanner::Location(position, position + 1);
1303       impl()->ReportMessageAt(location, MessageTemplate::kVarRedeclaration,
1304                               name);
1305     }
1306   }
1307 
1308   // TODO(nikolaos, marja): The first argument should not really be passed
1309   // by value. The method is expected to add the parsed statements to the
1310   // list. This works because in the case of the parser, StatementListT is
1311   // a pointer whereas the preparser does not really modify the body.
1312   V8_INLINE void ParseStatementList(StatementListT* body,
1313                                     Token::Value end_token);
1314   StatementT ParseStatementListItem();
1315 
ParseStatement(ZonePtrList<const AstRawString> * labels,ZonePtrList<const AstRawString> * own_labels)1316   StatementT ParseStatement(ZonePtrList<const AstRawString>* labels,
1317                             ZonePtrList<const AstRawString>* own_labels) {
1318     return ParseStatement(labels, own_labels,
1319                           kDisallowLabelledFunctionStatement);
1320   }
1321   StatementT ParseStatement(ZonePtrList<const AstRawString>* labels,
1322                             ZonePtrList<const AstRawString>* own_labels,
1323                             AllowLabelledFunctionStatement allow_function);
1324   BlockT ParseBlock(ZonePtrList<const AstRawString>* labels,
1325                     Scope* block_scope);
1326   BlockT ParseBlock(ZonePtrList<const AstRawString>* labels);
1327 
1328   // Parse a SubStatement in strict mode, or with an extra block scope in
1329   // sloppy mode to handle
1330   // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
1331   StatementT ParseScopedStatement(ZonePtrList<const AstRawString>* labels);
1332 
1333   StatementT ParseVariableStatement(VariableDeclarationContext var_context,
1334                                     ZonePtrList<const AstRawString>* names);
1335 
1336   // Magical syntax support.
1337   ExpressionT ParseV8Intrinsic();
1338 
1339   StatementT ParseDebuggerStatement();
1340 
1341   StatementT ParseExpressionOrLabelledStatement(
1342       ZonePtrList<const AstRawString>* labels,
1343       ZonePtrList<const AstRawString>* own_labels,
1344       AllowLabelledFunctionStatement allow_function);
1345   StatementT ParseIfStatement(ZonePtrList<const AstRawString>* labels);
1346   StatementT ParseContinueStatement();
1347   StatementT ParseBreakStatement(ZonePtrList<const AstRawString>* labels);
1348   StatementT ParseReturnStatement();
1349   StatementT ParseWithStatement(ZonePtrList<const AstRawString>* labels);
1350   StatementT ParseDoWhileStatement(ZonePtrList<const AstRawString>* labels,
1351                                    ZonePtrList<const AstRawString>* own_labels);
1352   StatementT ParseWhileStatement(ZonePtrList<const AstRawString>* labels,
1353                                  ZonePtrList<const AstRawString>* own_labels);
1354   StatementT ParseThrowStatement();
1355   StatementT ParseSwitchStatement(ZonePtrList<const AstRawString>* labels);
1356   V8_INLINE StatementT ParseTryStatement();
1357   StatementT ParseForStatement(ZonePtrList<const AstRawString>* labels,
1358                                ZonePtrList<const AstRawString>* own_labels);
1359   StatementT ParseForEachStatementWithDeclarations(
1360       int stmt_pos, ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
1361       ZonePtrList<const AstRawString>* own_labels, Scope* inner_block_scope);
1362   StatementT ParseForEachStatementWithoutDeclarations(
1363       int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
1364       ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
1365       ZonePtrList<const AstRawString>* own_labels);
1366 
1367   // Parse a C-style for loop: 'for (<init>; <cond>; <next>) { ... }'
1368   // "for (<init>;" is assumed to have been parser already.
1369   ForStatementT ParseStandardForLoop(
1370       int stmt_pos, ZonePtrList<const AstRawString>* labels,
1371       ZonePtrList<const AstRawString>* own_labels, ExpressionT* cond,
1372       StatementT* next, StatementT* body);
1373   // Same as the above, but handles those cases where <init> is a
1374   // lexical variable declaration.
1375   StatementT ParseStandardForLoopWithLexicalDeclarations(
1376       int stmt_pos, StatementT init, ForInfo* for_info,
1377       ZonePtrList<const AstRawString>* labels,
1378       ZonePtrList<const AstRawString>* own_labels);
1379   StatementT ParseForAwaitStatement(
1380       ZonePtrList<const AstRawString>* labels,
1381       ZonePtrList<const AstRawString>* own_labels);
1382 
IsLet(const AstRawString * identifier)1383   V8_INLINE bool IsLet(const AstRawString* identifier) const {
1384     return identifier == ast_value_factory()->let_string();
1385   }
1386 
1387   bool IsNextLetKeyword();
1388 
1389   // Checks if the expression is a valid reference expression (e.g., on the
1390   // left-hand side of assignments). Although ruled out by ECMA as early errors,
1391   // we allow calls for web compatibility and rewrite them to a runtime throw.
1392   // Modern language features can be exempted from this hack by passing
1393   // early_error = true.
1394   ExpressionT RewriteInvalidReferenceExpression(ExpressionT expression,
1395                                                 int beg_pos, int end_pos,
1396                                                 MessageTemplate message,
1397                                                 bool early_error);
1398 
1399   bool IsValidReferenceExpression(ExpressionT expression);
1400 
IsAssignableIdentifier(ExpressionT expression)1401   bool IsAssignableIdentifier(ExpressionT expression) {
1402     if (!impl()->IsIdentifier(expression)) return false;
1403     if (is_strict(language_mode()) &&
1404         impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) {
1405       return false;
1406     }
1407     return true;
1408   }
1409 
1410   enum SubFunctionKind { kFunction, kNonStaticMethod, kStaticMethod };
1411 
FunctionKindForImpl(SubFunctionKind sub_function_kind,ParseFunctionFlags flags)1412   FunctionKind FunctionKindForImpl(SubFunctionKind sub_function_kind,
1413                                    ParseFunctionFlags flags) {
1414     static const FunctionKind kFunctionKinds[][2][2] = {
1415         {
1416             // SubFunctionKind::kNormalFunction
1417             {// is_generator=false
1418              FunctionKind::kNormalFunction, FunctionKind::kAsyncFunction},
1419             {// is_generator=true
1420              FunctionKind::kGeneratorFunction,
1421              FunctionKind::kAsyncGeneratorFunction},
1422         },
1423         {
1424             // SubFunctionKind::kNonStaticMethod
1425             {// is_generator=false
1426              FunctionKind::kConciseMethod, FunctionKind::kAsyncConciseMethod},
1427             {// is_generator=true
1428              FunctionKind::kConciseGeneratorMethod,
1429              FunctionKind::kAsyncConciseGeneratorMethod},
1430         },
1431         {
1432             // SubFunctionKind::kStaticMethod
1433             {// is_generator=false
1434              FunctionKind::kStaticConciseMethod,
1435              FunctionKind::kStaticAsyncConciseMethod},
1436             {// is_generator=true
1437              FunctionKind::kStaticConciseGeneratorMethod,
1438              FunctionKind::kStaticAsyncConciseGeneratorMethod},
1439         }};
1440     return kFunctionKinds[sub_function_kind]
1441                          [(flags & ParseFunctionFlag::kIsGenerator) != 0]
1442                          [(flags & ParseFunctionFlag::kIsAsync) != 0];
1443   }
1444 
FunctionKindFor(ParseFunctionFlags flags)1445   inline FunctionKind FunctionKindFor(ParseFunctionFlags flags) {
1446     return FunctionKindForImpl(SubFunctionKind::kFunction, flags);
1447   }
1448 
MethodKindFor(bool is_static,ParseFunctionFlags flags)1449   inline FunctionKind MethodKindFor(bool is_static, ParseFunctionFlags flags) {
1450     return FunctionKindForImpl(is_static ? SubFunctionKind::kStaticMethod
1451                                          : SubFunctionKind::kNonStaticMethod,
1452                                flags);
1453   }
1454 
1455   // Keep track of eval() calls since they disable all local variable
1456   // optimizations. This checks if expression is an eval call, and if yes,
1457   // forwards the information to scope.
CheckPossibleEvalCall(ExpressionT expression,bool is_optional_call,Scope * scope)1458   Call::PossiblyEval CheckPossibleEvalCall(ExpressionT expression,
1459                                            bool is_optional_call,
1460                                            Scope* scope) {
1461     if (impl()->IsIdentifier(expression) &&
1462         impl()->IsEval(impl()->AsIdentifier(expression)) && !is_optional_call) {
1463       function_state_->RecordFunctionOrEvalCall();
1464       scope->RecordEvalCall();
1465 
1466       return Call::IS_POSSIBLY_EVAL;
1467     }
1468     return Call::NOT_EVAL;
1469   }
1470 
1471   // Convenience method which determines the type of return statement to emit
1472   // depending on the current function type.
1473   inline StatementT BuildReturnStatement(
1474       ExpressionT expr, int pos,
1475       int end_pos = ReturnStatement::kFunctionLiteralReturnPosition) {
1476     if (impl()->IsNull(expr)) {
1477       expr = factory()->NewUndefinedLiteral(kNoSourcePosition);
1478     } else if (is_async_generator()) {
1479       // In async generators, if there is an explicit operand to the return
1480       // statement, await the operand.
1481       expr = factory()->NewAwait(expr, kNoSourcePosition);
1482       function_state_->AddSuspend();
1483     }
1484     if (is_async_function()) {
1485       return factory()->NewAsyncReturnStatement(expr, pos, end_pos);
1486     }
1487     return factory()->NewReturnStatement(expr, pos, end_pos);
1488   }
1489 
module()1490   SourceTextModuleDescriptor* module() const {
1491     return scope()->AsModuleScope()->module();
1492   }
scope()1493   Scope* scope() const { return scope_; }
1494 
1495   // Stack of expression expression_scopes.
1496   // The top of the stack is always pointed to by expression_scope().
expression_scope()1497   V8_INLINE ExpressionScope* expression_scope() const {
1498     DCHECK_NOT_NULL(expression_scope_);
1499     return expression_scope_;
1500   }
1501 
MaybeParsingArrowhead()1502   bool MaybeParsingArrowhead() const {
1503     return expression_scope_ != nullptr &&
1504            expression_scope_->has_possible_arrow_parameter_in_scope_chain();
1505   }
1506 
1507   class V8_NODISCARD AcceptINScope final {
1508    public:
AcceptINScope(ParserBase * parser,bool accept_IN)1509     AcceptINScope(ParserBase* parser, bool accept_IN)
1510         : parser_(parser), previous_accept_IN_(parser->accept_IN_) {
1511       parser_->accept_IN_ = accept_IN;
1512     }
1513 
~AcceptINScope()1514     ~AcceptINScope() { parser_->accept_IN_ = previous_accept_IN_; }
1515 
1516    private:
1517     ParserBase* parser_;
1518     bool previous_accept_IN_;
1519   };
1520 
1521   class V8_NODISCARD ParameterParsingScope {
1522    public:
ParameterParsingScope(Impl * parser,FormalParametersT * parameters)1523     ParameterParsingScope(Impl* parser, FormalParametersT* parameters)
1524         : parser_(parser), parent_parameters_(parser_->parameters_) {
1525       parser_->parameters_ = parameters;
1526     }
1527 
~ParameterParsingScope()1528     ~ParameterParsingScope() { parser_->parameters_ = parent_parameters_; }
1529 
1530    private:
1531     Impl* parser_;
1532     FormalParametersT* parent_parameters_;
1533   };
1534 
1535   class V8_NODISCARD FunctionParsingScope {
1536    public:
FunctionParsingScope(Impl * parser)1537     explicit FunctionParsingScope(Impl* parser)
1538         : parser_(parser), expression_scope_(parser_->expression_scope_) {
1539       parser_->expression_scope_ = nullptr;
1540     }
1541 
~FunctionParsingScope()1542     ~FunctionParsingScope() { parser_->expression_scope_ = expression_scope_; }
1543 
1544    private:
1545     Impl* parser_;
1546     ExpressionScope* expression_scope_;
1547   };
1548 
pointer_buffer()1549   std::vector<void*>* pointer_buffer() { return &pointer_buffer_; }
variable_buffer()1550   std::vector<std::pair<VariableProxy*, int>>* variable_buffer() {
1551     return &variable_buffer_;
1552   }
1553 
1554   // Parser base's protected field members.
1555 
1556   Scope* scope_;                   // Scope stack.
1557   // Stack of scopes for object literals we're currently parsing.
1558   Scope* object_literal_scope_ = nullptr;
1559   Scope* original_scope_;  // The top scope for the current parsing item.
1560   FunctionState* function_state_;  // Function state stack.
1561   FuncNameInferrer fni_;
1562   AstValueFactory* ast_value_factory_;  // Not owned.
1563   typename Types::Factory ast_node_factory_;
1564   RuntimeCallStats* runtime_call_stats_;
1565   internal::Logger* logger_;
1566   bool parsing_on_main_thread_;
1567   uintptr_t stack_limit_;
1568   PendingCompilationErrorHandler* pending_error_handler_;
1569 
1570   // Parser base's private field members.
1571 
1572  private:
1573   Zone* zone_;
1574   ExpressionScope* expression_scope_;
1575 
1576   std::vector<void*> pointer_buffer_;
1577   std::vector<std::pair<VariableProxy*, int>> variable_buffer_;
1578 
1579   Scanner* scanner_;
1580 
1581   const UnoptimizedCompileFlags flags_;
1582   int function_literal_id_;
1583 
1584   FunctionLiteral::EagerCompileHint default_eager_compile_hint_;
1585 
1586   // This struct is used to move information about the next arrow function from
1587   // the place where the arrow head was parsed to where the body will be parsed.
1588   // Nothing can be parsed between the head and the body, so it will be consumed
1589   // immediately after it's produced.
1590   // Preallocating the struct as part of the parser minimizes the cost of
1591   // supporting arrow functions on non-arrow expressions.
1592   struct NextArrowFunctionInfo {
1593     Scanner::Location strict_parameter_error_location =
1594         Scanner::Location::invalid();
1595     MessageTemplate strict_parameter_error_message = MessageTemplate::kNone;
1596     DeclarationScope* scope = nullptr;
1597 
HasInitialStateNextArrowFunctionInfo1598     bool HasInitialState() const { return scope == nullptr; }
1599 
ResetNextArrowFunctionInfo1600     void Reset() {
1601       scope = nullptr;
1602       ClearStrictParameterError();
1603       DCHECK(HasInitialState());
1604     }
1605 
1606     // Tracks strict-mode parameter violations of sloppy-mode arrow heads in
1607     // case the function ends up becoming strict mode. Only one global place to
1608     // track this is necessary since arrow functions with none-simple parameters
1609     // cannot become strict-mode later on.
ClearStrictParameterErrorNextArrowFunctionInfo1610     void ClearStrictParameterError() {
1611       strict_parameter_error_location = Scanner::Location::invalid();
1612       strict_parameter_error_message = MessageTemplate::kNone;
1613     }
1614   };
1615 
1616   FormalParametersT* parameters_;
1617   NextArrowFunctionInfo next_arrow_function_info_;
1618 
1619   bool accept_IN_ = true;
1620 
1621   bool allow_eval_cache_ = true;
1622 };
1623 
1624 template <typename Impl>
FunctionState(FunctionState ** function_state_stack,Scope ** scope_stack,DeclarationScope * scope)1625 ParserBase<Impl>::FunctionState::FunctionState(
1626     FunctionState** function_state_stack, Scope** scope_stack,
1627     DeclarationScope* scope)
1628     : BlockState(scope_stack, scope),
1629       expected_property_count_(0),
1630       suspend_count_(0),
1631       function_state_stack_(function_state_stack),
1632       outer_function_state_(*function_state_stack),
1633       scope_(scope),
1634       dont_optimize_reason_(BailoutReason::kNoReason),
1635       next_function_is_likely_called_(false),
1636       previous_function_was_likely_called_(false),
1637       contains_function_or_eval_(false) {
1638   *function_state_stack = this;
1639   if (outer_function_state_) {
1640     outer_function_state_->previous_function_was_likely_called_ =
1641         outer_function_state_->next_function_is_likely_called_;
1642     outer_function_state_->next_function_is_likely_called_ = false;
1643   }
1644 }
1645 
1646 template <typename Impl>
~FunctionState()1647 ParserBase<Impl>::FunctionState::~FunctionState() {
1648   *function_state_stack_ = outer_function_state_;
1649 }
1650 
1651 template <typename Impl>
ReportUnexpectedToken(Token::Value token)1652 void ParserBase<Impl>::ReportUnexpectedToken(Token::Value token) {
1653   return impl()->ReportUnexpectedTokenAt(scanner_->location(), token);
1654 }
1655 
1656 template <typename Impl>
ClassifyPropertyIdentifier(Token::Value next,ParsePropertyInfo * prop_info)1657 bool ParserBase<Impl>::ClassifyPropertyIdentifier(
1658     Token::Value next, ParsePropertyInfo* prop_info) {
1659   // Updates made here must be reflected on ParseAndClassifyIdentifier.
1660   if (V8_LIKELY(base::IsInRange(next, Token::IDENTIFIER, Token::ASYNC))) {
1661     if (V8_UNLIKELY(impl()->IsArguments(prop_info->name) &&
1662                     scope()->ShouldBanArguments())) {
1663       ReportMessage(
1664           MessageTemplate::kArgumentsDisallowedInInitializerAndStaticBlock);
1665       return false;
1666     }
1667     return true;
1668   }
1669 
1670   if (!Token::IsValidIdentifier(next, language_mode(), is_generator(),
1671                                 is_await_as_identifier_disallowed())) {
1672     ReportUnexpectedToken(next);
1673     return false;
1674   }
1675 
1676   DCHECK(!prop_info->is_computed_name);
1677 
1678   if (next == Token::AWAIT) {
1679     DCHECK(!is_async_function());
1680     expression_scope()->RecordAsyncArrowParametersError(
1681         scanner()->peek_location(), MessageTemplate::kAwaitBindingIdentifier);
1682   }
1683   return true;
1684 }
1685 
1686 template <typename Impl>
1687 typename ParserBase<Impl>::IdentifierT
ParseAndClassifyIdentifier(Token::Value next)1688 ParserBase<Impl>::ParseAndClassifyIdentifier(Token::Value next) {
1689   // Updates made here must be reflected on ClassifyPropertyIdentifier.
1690   DCHECK_EQ(scanner()->current_token(), next);
1691   if (V8_LIKELY(base::IsInRange(next, Token::IDENTIFIER, Token::ASYNC))) {
1692     IdentifierT name = impl()->GetIdentifier();
1693     if (V8_UNLIKELY(impl()->IsArguments(name) &&
1694                     scope()->ShouldBanArguments())) {
1695       ReportMessage(
1696           MessageTemplate::kArgumentsDisallowedInInitializerAndStaticBlock);
1697       return impl()->EmptyIdentifierString();
1698     }
1699     return name;
1700   }
1701 
1702   if (!Token::IsValidIdentifier(next, language_mode(), is_generator(),
1703                                 is_await_as_identifier_disallowed())) {
1704     ReportUnexpectedToken(next);
1705     return impl()->EmptyIdentifierString();
1706   }
1707 
1708   if (next == Token::AWAIT) {
1709     expression_scope()->RecordAsyncArrowParametersError(
1710         scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
1711     return impl()->GetIdentifier();
1712   }
1713 
1714   DCHECK(Token::IsStrictReservedWord(next));
1715   expression_scope()->RecordStrictModeParameterError(
1716       scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
1717   return impl()->GetIdentifier();
1718 }
1719 
1720 template <class Impl>
ParseIdentifier(FunctionKind function_kind)1721 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier(
1722     FunctionKind function_kind) {
1723   Token::Value next = Next();
1724 
1725   if (!Token::IsValidIdentifier(
1726           next, language_mode(), IsGeneratorFunction(function_kind),
1727           flags().is_module() ||
1728               IsAwaitAsIdentifierDisallowed(function_kind))) {
1729     ReportUnexpectedToken(next);
1730     return impl()->EmptyIdentifierString();
1731   }
1732 
1733   return impl()->GetIdentifier();
1734 }
1735 
1736 template <typename Impl>
1737 typename ParserBase<Impl>::IdentifierT
ParseNonRestrictedIdentifier()1738 ParserBase<Impl>::ParseNonRestrictedIdentifier() {
1739   IdentifierT result = ParseIdentifier();
1740 
1741   if (is_strict(language_mode()) &&
1742       V8_UNLIKELY(impl()->IsEvalOrArguments(result))) {
1743     impl()->ReportMessageAt(scanner()->location(),
1744                             MessageTemplate::kStrictEvalArguments);
1745   }
1746 
1747   return result;
1748 }
1749 
1750 template <typename Impl>
ParsePropertyName()1751 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParsePropertyName() {
1752   Token::Value next = Next();
1753   if (V8_LIKELY(Token::IsPropertyName(next))) {
1754     if (peek() == Token::COLON) return impl()->GetSymbol();
1755     return impl()->GetIdentifier();
1756   }
1757 
1758   ReportUnexpectedToken(next);
1759   return impl()->EmptyIdentifierString();
1760 }
1761 
1762 template <typename Impl>
1763 typename ParserBase<Impl>::ExpressionT
ParsePropertyOrPrivatePropertyName()1764 ParserBase<Impl>::ParsePropertyOrPrivatePropertyName() {
1765   int pos = position();
1766   IdentifierT name;
1767   ExpressionT key;
1768   Token::Value next = Next();
1769   if (V8_LIKELY(Token::IsPropertyName(next))) {
1770     name = impl()->GetSymbol();
1771     key = factory()->NewStringLiteral(name, pos);
1772   } else if (next == Token::PRIVATE_NAME) {
1773     // In the case of a top level function, we completely skip
1774     // analysing it's scope, meaning, we don't have a chance to
1775     // resolve private names and find that they are not enclosed in a
1776     // class body.
1777     //
1778     // Here, we check if this is a new private name reference in a top
1779     // level function and throw an error if so.
1780     PrivateNameScopeIterator private_name_scope_iter(scope());
1781     // Parse the identifier so that we can display it in the error message
1782     name = impl()->GetIdentifier();
1783     if (private_name_scope_iter.Done()) {
1784       impl()->ReportMessageAt(Scanner::Location(pos, pos + 1),
1785                               MessageTemplate::kInvalidPrivateFieldResolution,
1786                               impl()->GetRawNameFromIdentifier(name));
1787       return impl()->FailureExpression();
1788     }
1789     key =
1790         impl()->ExpressionFromPrivateName(&private_name_scope_iter, name, pos);
1791   } else {
1792     ReportUnexpectedToken(next);
1793     return impl()->FailureExpression();
1794   }
1795   impl()->PushLiteralName(name);
1796   return key;
1797 }
1798 
1799 template <typename Impl>
ValidateRegExpLiteral(const AstRawString * pattern,RegExpFlags flags,RegExpError * regexp_error)1800 bool ParserBase<Impl>::ValidateRegExpLiteral(const AstRawString* pattern,
1801                                              RegExpFlags flags,
1802                                              RegExpError* regexp_error) {
1803   // TODO(jgruber): If already validated in the preparser, skip validation in
1804   // the parser.
1805   DisallowGarbageCollection no_gc;
1806   ZoneScope zone_scope(zone());  // Free regexp parser memory after use.
1807   const unsigned char* d = pattern->raw_data();
1808   if (pattern->is_one_byte()) {
1809     return RegExp::VerifySyntax(zone(), stack_limit(),
1810                                 static_cast<const uint8_t*>(d),
1811                                 pattern->length(), flags, regexp_error, no_gc);
1812   } else {
1813     return RegExp::VerifySyntax(zone(), stack_limit(),
1814                                 reinterpret_cast<const uint16_t*>(d),
1815                                 pattern->length(), flags, regexp_error, no_gc);
1816   }
1817 }
1818 
1819 template <typename Impl>
ParseRegExpLiteral()1820 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral() {
1821   int pos = peek_position();
1822   if (!scanner()->ScanRegExpPattern()) {
1823     Next();
1824     ReportMessage(MessageTemplate::kUnterminatedRegExp);
1825     return impl()->FailureExpression();
1826   }
1827 
1828   const AstRawString* js_pattern = GetNextSymbolForRegExpLiteral();
1829   base::Optional<RegExpFlags> flags = scanner()->ScanRegExpFlags();
1830   if (!flags.has_value()) {
1831     Next();
1832     ReportMessage(MessageTemplate::kMalformedRegExpFlags);
1833     return impl()->FailureExpression();
1834   }
1835   Next();
1836   RegExpError regexp_error;
1837   if (!ValidateRegExpLiteral(js_pattern, flags.value(), &regexp_error)) {
1838     if (RegExpErrorIsStackOverflow(regexp_error)) set_stack_overflow();
1839     ReportMessage(MessageTemplate::kMalformedRegExp, js_pattern,
1840                   RegExpErrorString(regexp_error));
1841     return impl()->FailureExpression();
1842   }
1843   return factory()->NewRegExpLiteral(js_pattern, flags.value(), pos);
1844 }
1845 
1846 template <typename Impl>
ParseBindingPattern()1847 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBindingPattern() {
1848   // Pattern ::
1849   //   Identifier
1850   //   ArrayLiteral
1851   //   ObjectLiteral
1852 
1853   int beg_pos = peek_position();
1854   Token::Value token = peek();
1855   ExpressionT result;
1856 
1857   if (Token::IsAnyIdentifier(token)) {
1858     IdentifierT name = ParseAndClassifyIdentifier(Next());
1859     if (V8_UNLIKELY(is_strict(language_mode()) &&
1860                     impl()->IsEvalOrArguments(name))) {
1861       impl()->ReportMessageAt(scanner()->location(),
1862                               MessageTemplate::kStrictEvalArguments);
1863       return impl()->FailureExpression();
1864     }
1865     return impl()->ExpressionFromIdentifier(name, beg_pos);
1866   }
1867 
1868   CheckStackOverflow();
1869 
1870   if (token == Token::LBRACK) {
1871     result = ParseArrayLiteral();
1872   } else if (token == Token::LBRACE) {
1873     result = ParseObjectLiteral();
1874   } else {
1875     ReportUnexpectedToken(Next());
1876     return impl()->FailureExpression();
1877   }
1878 
1879   return result;
1880 }
1881 
1882 template <typename Impl>
1883 typename ParserBase<Impl>::ExpressionT
ParsePrimaryExpression()1884 ParserBase<Impl>::ParsePrimaryExpression() {
1885   CheckStackOverflow();
1886 
1887   // PrimaryExpression ::
1888   //   'this'
1889   //   'null'
1890   //   'true'
1891   //   'false'
1892   //   Identifier
1893   //   Number
1894   //   String
1895   //   ArrayLiteral
1896   //   ObjectLiteral
1897   //   RegExpLiteral
1898   //   ClassLiteral
1899   //   '(' Expression ')'
1900   //   TemplateLiteral
1901   //   do Block
1902   //   AsyncFunctionLiteral
1903 
1904   int beg_pos = peek_position();
1905   Token::Value token = peek();
1906 
1907   if (Token::IsAnyIdentifier(token)) {
1908     Consume(token);
1909 
1910     FunctionKind kind = FunctionKind::kArrowFunction;
1911 
1912     if (V8_UNLIKELY(token == Token::ASYNC &&
1913                     !scanner()->HasLineTerminatorBeforeNext() &&
1914                     !scanner()->literal_contains_escapes())) {
1915       // async function ...
1916       if (peek() == Token::FUNCTION) return ParseAsyncFunctionLiteral();
1917 
1918       // async Identifier => ...
1919       if (peek_any_identifier() && PeekAhead() == Token::ARROW) {
1920         token = Next();
1921         beg_pos = position();
1922         kind = FunctionKind::kAsyncArrowFunction;
1923       }
1924     }
1925 
1926     if (V8_UNLIKELY(peek() == Token::ARROW)) {
1927       ArrowHeadParsingScope parsing_scope(impl(), kind);
1928       IdentifierT name = ParseAndClassifyIdentifier(token);
1929       ClassifyParameter(name, beg_pos, end_position());
1930       ExpressionT result =
1931           impl()->ExpressionFromIdentifier(name, beg_pos, InferName::kNo);
1932       parsing_scope.SetInitializers(0, peek_position());
1933       next_arrow_function_info_.scope = parsing_scope.ValidateAndCreateScope();
1934       return result;
1935     }
1936 
1937     IdentifierT name = ParseAndClassifyIdentifier(token);
1938     return impl()->ExpressionFromIdentifier(name, beg_pos);
1939   }
1940 
1941   if (Token::IsLiteral(token)) {
1942     return impl()->ExpressionFromLiteral(Next(), beg_pos);
1943   }
1944 
1945   switch (token) {
1946     case Token::NEW:
1947       return ParseMemberWithPresentNewPrefixesExpression();
1948 
1949     case Token::THIS: {
1950       Consume(Token::THIS);
1951       return impl()->NewThisExpression(beg_pos);
1952     }
1953 
1954     case Token::ASSIGN_DIV:
1955     case Token::DIV:
1956       return ParseRegExpLiteral();
1957 
1958     case Token::FUNCTION:
1959       return ParseFunctionExpression();
1960 
1961     case Token::SUPER: {
1962       return ParseSuperExpression();
1963     }
1964     case Token::IMPORT:
1965       return ParseImportExpressions();
1966 
1967     case Token::LBRACK:
1968       return ParseArrayLiteral();
1969 
1970     case Token::LBRACE:
1971       return ParseObjectLiteral();
1972 
1973     case Token::LPAREN: {
1974       Consume(Token::LPAREN);
1975 
1976       if (Check(Token::RPAREN)) {
1977         // clear last next_arrow_function_info tracked strict parameters error.
1978         next_arrow_function_info_.ClearStrictParameterError();
1979 
1980         // ()=>x.  The continuation that consumes the => is in
1981         // ParseAssignmentExpressionCoverGrammar.
1982         if (peek() != Token::ARROW) ReportUnexpectedToken(Token::RPAREN);
1983         next_arrow_function_info_.scope =
1984             NewFunctionScope(FunctionKind::kArrowFunction);
1985         return factory()->NewEmptyParentheses(beg_pos);
1986       }
1987       Scope::Snapshot scope_snapshot(scope());
1988       ArrowHeadParsingScope maybe_arrow(impl(), FunctionKind::kArrowFunction);
1989       // Heuristically try to detect immediately called functions before
1990       // seeing the call parentheses.
1991       if (peek() == Token::FUNCTION ||
1992           (peek() == Token::ASYNC && PeekAhead() == Token::FUNCTION)) {
1993         function_state_->set_next_function_is_likely_called();
1994       }
1995       AcceptINScope scope(this, true);
1996       ExpressionT expr = ParseExpressionCoverGrammar();
1997       expr->mark_parenthesized();
1998       Expect(Token::RPAREN);
1999 
2000       if (peek() == Token::ARROW) {
2001         next_arrow_function_info_.scope = maybe_arrow.ValidateAndCreateScope();
2002         scope_snapshot.Reparent(next_arrow_function_info_.scope);
2003       } else {
2004         maybe_arrow.ValidateExpression();
2005       }
2006 
2007       return expr;
2008     }
2009 
2010     case Token::CLASS: {
2011       return ParseClassExpression(scope());
2012     }
2013 
2014     case Token::TEMPLATE_SPAN:
2015     case Token::TEMPLATE_TAIL:
2016       return ParseTemplateLiteral(impl()->NullExpression(), beg_pos, false);
2017 
2018     case Token::MOD:
2019       if (flags().allow_natives_syntax() || impl()->ParsingExtension()) {
2020         return ParseV8Intrinsic();
2021       }
2022       break;
2023 
2024     default:
2025       break;
2026   }
2027 
2028   ReportUnexpectedToken(Next());
2029   return impl()->FailureExpression();
2030 }
2031 
2032 template <typename Impl>
ParseExpression()2033 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression() {
2034   ExpressionParsingScope expression_scope(impl());
2035   AcceptINScope scope(this, true);
2036   ExpressionT result = ParseExpressionCoverGrammar();
2037   expression_scope.ValidateExpression();
2038   return result;
2039 }
2040 
2041 template <typename Impl>
2042 typename ParserBase<Impl>::ExpressionT
ParseAssignmentExpression()2043 ParserBase<Impl>::ParseAssignmentExpression() {
2044   ExpressionParsingScope expression_scope(impl());
2045   ExpressionT result = ParseAssignmentExpressionCoverGrammar();
2046   expression_scope.ValidateExpression();
2047   return result;
2048 }
2049 
2050 template <typename Impl>
2051 typename ParserBase<Impl>::ExpressionT
ParseExpressionCoverGrammar()2052 ParserBase<Impl>::ParseExpressionCoverGrammar() {
2053   // Expression ::
2054   //   AssignmentExpression
2055   //   Expression ',' AssignmentExpression
2056 
2057   ExpressionListT list(pointer_buffer());
2058   ExpressionT expression;
2059   AccumulationScope accumulation_scope(expression_scope());
2060   int variable_index = 0;
2061   while (true) {
2062     if (V8_UNLIKELY(peek() == Token::ELLIPSIS)) {
2063       return ParseArrowParametersWithRest(&list, &accumulation_scope,
2064                                           variable_index);
2065     }
2066 
2067     int expr_pos = peek_position();
2068     expression = ParseAssignmentExpressionCoverGrammar();
2069 
2070     ClassifyArrowParameter(&accumulation_scope, expr_pos, expression);
2071     list.Add(expression);
2072 
2073     variable_index =
2074         expression_scope()->SetInitializers(variable_index, peek_position());
2075 
2076     if (!Check(Token::COMMA)) break;
2077 
2078     if (peek() == Token::RPAREN && PeekAhead() == Token::ARROW) {
2079       // a trailing comma is allowed at the end of an arrow parameter list
2080       break;
2081     }
2082 
2083     // Pass on the 'set_next_function_is_likely_called' flag if we have
2084     // several function literals separated by comma.
2085     if (peek() == Token::FUNCTION &&
2086         function_state_->previous_function_was_likely_called()) {
2087       function_state_->set_next_function_is_likely_called();
2088     }
2089   }
2090 
2091   // Return the single element if the list is empty. We need to do this because
2092   // callers of this function care about the type of the result if there was
2093   // only a single assignment expression. The preparser would lose this
2094   // information otherwise.
2095   if (list.length() == 1) return expression;
2096   return impl()->ExpressionListToExpression(list);
2097 }
2098 
2099 template <typename Impl>
2100 typename ParserBase<Impl>::ExpressionT
ParseArrowParametersWithRest(typename ParserBase<Impl>::ExpressionListT * list,AccumulationScope * accumulation_scope,int seen_variables)2101 ParserBase<Impl>::ParseArrowParametersWithRest(
2102     typename ParserBase<Impl>::ExpressionListT* list,
2103     AccumulationScope* accumulation_scope, int seen_variables) {
2104   Consume(Token::ELLIPSIS);
2105 
2106   Scanner::Location ellipsis = scanner()->location();
2107   int pattern_pos = peek_position();
2108   ExpressionT pattern = ParseBindingPattern();
2109   ClassifyArrowParameter(accumulation_scope, pattern_pos, pattern);
2110 
2111   expression_scope()->RecordNonSimpleParameter();
2112 
2113   if (V8_UNLIKELY(peek() == Token::ASSIGN)) {
2114     ReportMessage(MessageTemplate::kRestDefaultInitializer);
2115     return impl()->FailureExpression();
2116   }
2117 
2118   ExpressionT spread =
2119       factory()->NewSpread(pattern, ellipsis.beg_pos, pattern_pos);
2120   if (V8_UNLIKELY(peek() == Token::COMMA)) {
2121     ReportMessage(MessageTemplate::kParamAfterRest);
2122     return impl()->FailureExpression();
2123   }
2124 
2125   expression_scope()->SetInitializers(seen_variables, peek_position());
2126 
2127   // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
2128   // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
2129   // valid expression.
2130   if (peek() != Token::RPAREN || PeekAhead() != Token::ARROW) {
2131     impl()->ReportUnexpectedTokenAt(ellipsis, Token::ELLIPSIS);
2132     return impl()->FailureExpression();
2133   }
2134 
2135   list->Add(spread);
2136   return impl()->ExpressionListToExpression(*list);
2137 }
2138 
2139 template <typename Impl>
ParseArrayLiteral()2140 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral() {
2141   // ArrayLiteral ::
2142   //   '[' Expression? (',' Expression?)* ']'
2143 
2144   int pos = peek_position();
2145   ExpressionListT values(pointer_buffer());
2146   int first_spread_index = -1;
2147   Consume(Token::LBRACK);
2148 
2149   AccumulationScope accumulation_scope(expression_scope());
2150 
2151   while (!Check(Token::RBRACK)) {
2152     ExpressionT elem;
2153     if (peek() == Token::COMMA) {
2154       elem = factory()->NewTheHoleLiteral();
2155     } else if (Check(Token::ELLIPSIS)) {
2156       int start_pos = position();
2157       int expr_pos = peek_position();
2158       AcceptINScope scope(this, true);
2159       ExpressionT argument =
2160           ParsePossibleDestructuringSubPattern(&accumulation_scope);
2161       elem = factory()->NewSpread(argument, start_pos, expr_pos);
2162 
2163       if (first_spread_index < 0) {
2164         first_spread_index = values.length();
2165       }
2166 
2167       if (argument->IsAssignment()) {
2168         expression_scope()->RecordPatternError(
2169             Scanner::Location(start_pos, end_position()),
2170             MessageTemplate::kInvalidDestructuringTarget);
2171       }
2172 
2173       if (peek() == Token::COMMA) {
2174         expression_scope()->RecordPatternError(
2175             Scanner::Location(start_pos, end_position()),
2176             MessageTemplate::kElementAfterRest);
2177       }
2178     } else {
2179       AcceptINScope scope(this, true);
2180       elem = ParsePossibleDestructuringSubPattern(&accumulation_scope);
2181     }
2182     values.Add(elem);
2183     if (peek() != Token::RBRACK) {
2184       Expect(Token::COMMA);
2185       if (elem->IsFailureExpression()) return elem;
2186     }
2187   }
2188 
2189   return factory()->NewArrayLiteral(values, first_spread_index, pos);
2190 }
2191 
2192 template <class Impl>
ParseProperty(ParsePropertyInfo * prop_info)2193 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseProperty(
2194     ParsePropertyInfo* prop_info) {
2195   DCHECK_EQ(prop_info->kind, ParsePropertyKind::kNotSet);
2196   DCHECK_EQ(prop_info->function_flags, ParseFunctionFlag::kIsNormal);
2197   DCHECK(!prop_info->is_computed_name);
2198 
2199   if (Check(Token::ASYNC)) {
2200     Token::Value token = peek();
2201     if ((token != Token::MUL && prop_info->ParsePropertyKindFromToken(token)) ||
2202         scanner()->HasLineTerminatorBeforeNext()) {
2203       prop_info->name = impl()->GetIdentifier();
2204       impl()->PushLiteralName(prop_info->name);
2205       return factory()->NewStringLiteral(prop_info->name, position());
2206     }
2207     if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
2208       impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
2209     }
2210     prop_info->function_flags = ParseFunctionFlag::kIsAsync;
2211     prop_info->kind = ParsePropertyKind::kMethod;
2212   }
2213 
2214   if (Check(Token::MUL)) {
2215     prop_info->function_flags |= ParseFunctionFlag::kIsGenerator;
2216     prop_info->kind = ParsePropertyKind::kMethod;
2217   }
2218 
2219   if (prop_info->kind == ParsePropertyKind::kNotSet &&
2220       base::IsInRange(peek(), Token::GET, Token::SET)) {
2221     Token::Value token = Next();
2222     if (prop_info->ParsePropertyKindFromToken(peek())) {
2223       prop_info->name = impl()->GetIdentifier();
2224       impl()->PushLiteralName(prop_info->name);
2225       return factory()->NewStringLiteral(prop_info->name, position());
2226     }
2227     if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
2228       impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
2229     }
2230     if (token == Token::GET) {
2231       prop_info->kind = ParsePropertyKind::kAccessorGetter;
2232     } else if (token == Token::SET) {
2233       prop_info->kind = ParsePropertyKind::kAccessorSetter;
2234     }
2235   }
2236 
2237   int pos = peek_position();
2238 
2239   // For non computed property names we normalize the name a bit:
2240   //
2241   //   "12" -> 12
2242   //   12.3 -> "12.3"
2243   //   12.30 -> "12.3"
2244   //   identifier -> "identifier"
2245   //
2246   // This is important because we use the property name as a key in a hash
2247   // table when we compute constant properties.
2248   bool is_array_index;
2249   uint32_t index;
2250   switch (peek()) {
2251     case Token::PRIVATE_NAME:
2252       prop_info->is_private = true;
2253       is_array_index = false;
2254       Consume(Token::PRIVATE_NAME);
2255       if (prop_info->kind == ParsePropertyKind::kNotSet) {
2256         prop_info->ParsePropertyKindFromToken(peek());
2257       }
2258       prop_info->name = impl()->GetIdentifier();
2259       if (V8_UNLIKELY(prop_info->position ==
2260                       PropertyPosition::kObjectLiteral)) {
2261         ReportUnexpectedToken(Token::PRIVATE_NAME);
2262         prop_info->kind = ParsePropertyKind::kNotSet;
2263         return impl()->FailureExpression();
2264       }
2265       break;
2266 
2267     case Token::STRING:
2268       Consume(Token::STRING);
2269       prop_info->name = peek() == Token::COLON ? impl()->GetSymbol()
2270                                                : impl()->GetIdentifier();
2271       is_array_index = impl()->IsArrayIndex(prop_info->name, &index);
2272       break;
2273 
2274     case Token::SMI:
2275       Consume(Token::SMI);
2276       index = scanner()->smi_value();
2277       is_array_index = true;
2278       // Token::SMI were scanned from their canonical representation.
2279       prop_info->name = impl()->GetSymbol();
2280       break;
2281 
2282     case Token::NUMBER: {
2283       Consume(Token::NUMBER);
2284       prop_info->name = impl()->GetNumberAsSymbol();
2285       is_array_index = impl()->IsArrayIndex(prop_info->name, &index);
2286       break;
2287     }
2288 
2289     case Token::BIGINT: {
2290       Consume(Token::BIGINT);
2291       prop_info->name = impl()->GetBigIntAsSymbol();
2292       is_array_index = impl()->IsArrayIndex(prop_info->name, &index);
2293       break;
2294     }
2295 
2296     case Token::LBRACK: {
2297       prop_info->name = impl()->NullIdentifier();
2298       prop_info->is_computed_name = true;
2299       Consume(Token::LBRACK);
2300       AcceptINScope scope(this, true);
2301       ExpressionT expression = ParseAssignmentExpression();
2302       Expect(Token::RBRACK);
2303       if (prop_info->kind == ParsePropertyKind::kNotSet) {
2304         prop_info->ParsePropertyKindFromToken(peek());
2305       }
2306       return expression;
2307     }
2308 
2309     case Token::ELLIPSIS:
2310       if (prop_info->kind == ParsePropertyKind::kNotSet) {
2311         prop_info->name = impl()->NullIdentifier();
2312         Consume(Token::ELLIPSIS);
2313         AcceptINScope scope(this, true);
2314         int start_pos = peek_position();
2315         ExpressionT expression =
2316             ParsePossibleDestructuringSubPattern(prop_info->accumulation_scope);
2317         prop_info->kind = ParsePropertyKind::kSpread;
2318 
2319         if (!IsValidReferenceExpression(expression)) {
2320           expression_scope()->RecordDeclarationError(
2321               Scanner::Location(start_pos, end_position()),
2322               MessageTemplate::kInvalidRestBindingPattern);
2323           expression_scope()->RecordPatternError(
2324               Scanner::Location(start_pos, end_position()),
2325               MessageTemplate::kInvalidRestAssignmentPattern);
2326         }
2327 
2328         if (peek() != Token::RBRACE) {
2329           expression_scope()->RecordPatternError(
2330               scanner()->location(), MessageTemplate::kElementAfterRest);
2331         }
2332         return expression;
2333       }
2334       V8_FALLTHROUGH;
2335 
2336     default:
2337       prop_info->name = ParsePropertyName();
2338       is_array_index = false;
2339       break;
2340   }
2341 
2342   if (prop_info->kind == ParsePropertyKind::kNotSet) {
2343     prop_info->ParsePropertyKindFromToken(peek());
2344   }
2345   impl()->PushLiteralName(prop_info->name);
2346   return is_array_index ? factory()->NewNumberLiteral(index, pos)
2347                         : factory()->NewStringLiteral(prop_info->name, pos);
2348 }
2349 
2350 template <typename Impl>
2351 typename ParserBase<Impl>::ClassLiteralPropertyT
ParseClassPropertyDefinition(ClassInfo * class_info,ParsePropertyInfo * prop_info,bool has_extends)2352 ParserBase<Impl>::ParseClassPropertyDefinition(ClassInfo* class_info,
2353                                                ParsePropertyInfo* prop_info,
2354                                                bool has_extends) {
2355   DCHECK_NOT_NULL(class_info);
2356   DCHECK_EQ(prop_info->position, PropertyPosition::kClassLiteral);
2357 
2358   Token::Value name_token = peek();
2359   int property_beg_pos = scanner()->peek_location().beg_pos;
2360   int name_token_position = property_beg_pos;
2361   ExpressionT name_expression;
2362   if (name_token == Token::STATIC) {
2363     Consume(Token::STATIC);
2364     name_token_position = scanner()->peek_location().beg_pos;
2365     if (peek() == Token::LPAREN) {
2366       prop_info->kind = ParsePropertyKind::kMethod;
2367       // TODO(bakkot) specialize on 'static'
2368       prop_info->name = impl()->GetIdentifier();
2369       name_expression =
2370           factory()->NewStringLiteral(prop_info->name, position());
2371     } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON ||
2372                peek() == Token::RBRACE) {
2373       // TODO(bakkot) specialize on 'static'
2374       prop_info->name = impl()->GetIdentifier();
2375       name_expression =
2376           factory()->NewStringLiteral(prop_info->name, position());
2377     } else {
2378       prop_info->is_static = true;
2379       name_expression = ParseProperty(prop_info);
2380     }
2381   } else {
2382     name_expression = ParseProperty(prop_info);
2383   }
2384 
2385   switch (prop_info->kind) {
2386     case ParsePropertyKind::kAssign:
2387     case ParsePropertyKind::kClassField:
2388     case ParsePropertyKind::kShorthandOrClassField:
2389     case ParsePropertyKind::kNotSet: {  // This case is a name followed by a
2390                                         // name or other property. Here we have
2391                                         // to assume that's an uninitialized
2392                                         // field followed by a linebreak
2393                                         // followed by a property, with ASI
2394                                         // adding the semicolon. If not, there
2395                                         // will be a syntax error after parsing
2396                                         // the first name as an uninitialized
2397                                         // field.
2398       prop_info->kind = ParsePropertyKind::kClassField;
2399       DCHECK_IMPLIES(prop_info->is_computed_name, !prop_info->is_private);
2400 
2401       if (!prop_info->is_computed_name) {
2402         CheckClassFieldName(prop_info->name, prop_info->is_static);
2403       }
2404 
2405       ExpressionT initializer = ParseMemberInitializer(
2406           class_info, property_beg_pos, prop_info->is_static);
2407       ExpectSemicolon();
2408 
2409       ClassLiteralPropertyT result = factory()->NewClassLiteralProperty(
2410           name_expression, initializer, ClassLiteralProperty::FIELD,
2411           prop_info->is_static, prop_info->is_computed_name,
2412           prop_info->is_private);
2413       impl()->SetFunctionNameFromPropertyName(result, prop_info->name);
2414 
2415       return result;
2416     }
2417     case ParsePropertyKind::kMethod: {
2418       // MethodDefinition
2419       //    PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2420       //    '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2421       //    async PropertyName '(' StrictFormalParameters ')'
2422       //        '{' FunctionBody '}'
2423       //    async '*' PropertyName '(' StrictFormalParameters ')'
2424       //        '{' FunctionBody '}'
2425 
2426       if (!prop_info->is_computed_name) {
2427         CheckClassMethodName(prop_info->name, ParsePropertyKind::kMethod,
2428                              prop_info->function_flags, prop_info->is_static,
2429                              &class_info->has_seen_constructor);
2430       }
2431 
2432       FunctionKind kind =
2433           MethodKindFor(prop_info->is_static, prop_info->function_flags);
2434 
2435       if (!prop_info->is_static && impl()->IsConstructor(prop_info->name)) {
2436         class_info->has_seen_constructor = true;
2437         kind = has_extends ? FunctionKind::kDerivedConstructor
2438                            : FunctionKind::kBaseConstructor;
2439       }
2440 
2441       ExpressionT value = impl()->ParseFunctionLiteral(
2442           prop_info->name, scanner()->location(), kSkipFunctionNameCheck, kind,
2443           name_token_position, FunctionSyntaxKind::kAccessorOrMethod,
2444           language_mode(), nullptr);
2445 
2446       ClassLiteralPropertyT result = factory()->NewClassLiteralProperty(
2447           name_expression, value, ClassLiteralProperty::METHOD,
2448           prop_info->is_static, prop_info->is_computed_name,
2449           prop_info->is_private);
2450       impl()->SetFunctionNameFromPropertyName(result, prop_info->name);
2451       return result;
2452     }
2453 
2454     case ParsePropertyKind::kAccessorGetter:
2455     case ParsePropertyKind::kAccessorSetter: {
2456       DCHECK_EQ(prop_info->function_flags, ParseFunctionFlag::kIsNormal);
2457       bool is_get = prop_info->kind == ParsePropertyKind::kAccessorGetter;
2458 
2459       if (!prop_info->is_computed_name) {
2460         CheckClassMethodName(prop_info->name, prop_info->kind,
2461                              ParseFunctionFlag::kIsNormal, prop_info->is_static,
2462                              &class_info->has_seen_constructor);
2463         // Make sure the name expression is a string since we need a Name for
2464         // Runtime_DefineAccessorPropertyUnchecked and since we can determine
2465         // this statically we can skip the extra runtime check.
2466         name_expression = factory()->NewStringLiteral(
2467             prop_info->name, name_expression->position());
2468       }
2469 
2470       FunctionKind kind;
2471       if (prop_info->is_static) {
2472         kind = is_get ? FunctionKind::kStaticGetterFunction
2473                       : FunctionKind::kStaticSetterFunction;
2474       } else {
2475         kind = is_get ? FunctionKind::kGetterFunction
2476                       : FunctionKind::kSetterFunction;
2477       }
2478 
2479       FunctionLiteralT value = impl()->ParseFunctionLiteral(
2480           prop_info->name, scanner()->location(), kSkipFunctionNameCheck, kind,
2481           name_token_position, FunctionSyntaxKind::kAccessorOrMethod,
2482           language_mode(), nullptr);
2483 
2484       ClassLiteralProperty::Kind property_kind =
2485           is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER;
2486       ClassLiteralPropertyT result = factory()->NewClassLiteralProperty(
2487           name_expression, value, property_kind, prop_info->is_static,
2488           prop_info->is_computed_name, prop_info->is_private);
2489       const AstRawString* prefix =
2490           is_get ? ast_value_factory()->get_space_string()
2491                  : ast_value_factory()->set_space_string();
2492       impl()->SetFunctionNameFromPropertyName(result, prop_info->name, prefix);
2493       return result;
2494     }
2495     case ParsePropertyKind::kValue:
2496     case ParsePropertyKind::kShorthand:
2497     case ParsePropertyKind::kSpread:
2498       impl()->ReportUnexpectedTokenAt(
2499           Scanner::Location(name_token_position, name_expression->position()),
2500           name_token);
2501       return impl()->NullLiteralProperty();
2502   }
2503   UNREACHABLE();
2504 }
2505 
2506 template <typename Impl>
ParseMemberInitializer(ClassInfo * class_info,int beg_pos,bool is_static)2507 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberInitializer(
2508     ClassInfo* class_info, int beg_pos, bool is_static) {
2509   FunctionParsingScope body_parsing_scope(impl());
2510   DeclarationScope* initializer_scope =
2511       is_static ? class_info->static_elements_scope
2512                 : class_info->instance_members_scope;
2513   FunctionKind function_kind =
2514       is_static ? FunctionKind::kClassStaticInitializerFunction
2515                 : FunctionKind::kClassMembersInitializerFunction;
2516 
2517   if (initializer_scope == nullptr) {
2518     initializer_scope = NewFunctionScope(function_kind);
2519     initializer_scope->SetLanguageMode(LanguageMode::kStrict);
2520   }
2521 
2522   ExpressionT initializer;
2523   if (Check(Token::ASSIGN)) {
2524     FunctionState initializer_state(&function_state_, &scope_,
2525                                     initializer_scope);
2526 
2527     AcceptINScope scope(this, true);
2528     initializer = ParseAssignmentExpression();
2529   } else {
2530     initializer = factory()->NewUndefinedLiteral(kNoSourcePosition);
2531   }
2532 
2533   if (is_static) {
2534     // For the instance initializer, we will save the positions
2535     // later with the positions of the class body so that we can reparse
2536     // it later.
2537     // TODO(joyee): Make scopes be non contiguous.
2538     initializer_scope->set_start_position(beg_pos);
2539     initializer_scope->set_end_position(end_position());
2540     class_info->static_elements_scope = initializer_scope;
2541     class_info->has_static_elements = true;
2542   } else {
2543     class_info->instance_members_scope = initializer_scope;
2544     class_info->has_instance_members = true;
2545   }
2546 
2547   return initializer;
2548 }
2549 
2550 template <typename Impl>
ParseClassStaticBlock(ClassInfo * class_info)2551 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseClassStaticBlock(
2552     ClassInfo* class_info) {
2553   Consume(Token::STATIC);
2554 
2555   DeclarationScope* initializer_scope = class_info->static_elements_scope;
2556   if (initializer_scope == nullptr) {
2557     initializer_scope =
2558         NewFunctionScope(FunctionKind::kClassStaticInitializerFunction);
2559     initializer_scope->set_start_position(position());
2560     initializer_scope->SetLanguageMode(LanguageMode::kStrict);
2561     class_info->static_elements_scope = initializer_scope;
2562   }
2563 
2564   FunctionState initializer_state(&function_state_, &scope_, initializer_scope);
2565   AcceptINScope accept_in(this, true);
2566 
2567   // Each static block has its own var and lexical scope, so make a new var
2568   // block scope instead of using the synthetic members initializer function
2569   // scope.
2570   BlockT static_block = ParseBlock(nullptr, NewVarblockScope());
2571   initializer_scope->set_end_position(end_position());
2572   class_info->has_static_elements = true;
2573   return static_block;
2574 }
2575 
2576 template <typename Impl>
2577 typename ParserBase<Impl>::ObjectLiteralPropertyT
ParseObjectPropertyDefinition(ParsePropertyInfo * prop_info,bool * has_seen_proto)2578 ParserBase<Impl>::ParseObjectPropertyDefinition(ParsePropertyInfo* prop_info,
2579                                                 bool* has_seen_proto) {
2580   DCHECK_EQ(prop_info->position, PropertyPosition::kObjectLiteral);
2581   Token::Value name_token = peek();
2582   Scanner::Location next_loc = scanner()->peek_location();
2583 
2584   ExpressionT name_expression = ParseProperty(prop_info);
2585 
2586   DCHECK_IMPLIES(name_token == Token::PRIVATE_NAME, has_error());
2587 
2588   IdentifierT name = prop_info->name;
2589   ParseFunctionFlags function_flags = prop_info->function_flags;
2590 
2591   switch (prop_info->kind) {
2592     case ParsePropertyKind::kSpread:
2593       DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2594       DCHECK(!prop_info->is_computed_name);
2595       DCHECK_EQ(Token::ELLIPSIS, name_token);
2596 
2597       prop_info->is_computed_name = true;
2598       prop_info->is_rest = true;
2599 
2600       return factory()->NewObjectLiteralProperty(
2601           factory()->NewTheHoleLiteral(), name_expression,
2602           ObjectLiteralProperty::SPREAD, true);
2603 
2604     case ParsePropertyKind::kValue: {
2605       DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2606 
2607       if (!prop_info->is_computed_name &&
2608           scanner()->CurrentLiteralEquals("__proto__")) {
2609         if (*has_seen_proto) {
2610           expression_scope()->RecordExpressionError(
2611               scanner()->location(), MessageTemplate::kDuplicateProto);
2612         }
2613         *has_seen_proto = true;
2614       }
2615       Consume(Token::COLON);
2616       AcceptINScope scope(this, true);
2617       ExpressionT value =
2618           ParsePossibleDestructuringSubPattern(prop_info->accumulation_scope);
2619 
2620       ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2621           name_expression, value, prop_info->is_computed_name);
2622       impl()->SetFunctionNameFromPropertyName(result, name);
2623       return result;
2624     }
2625 
2626     case ParsePropertyKind::kAssign:
2627     case ParsePropertyKind::kShorthandOrClassField:
2628     case ParsePropertyKind::kShorthand: {
2629       // PropertyDefinition
2630       //    IdentifierReference
2631       //    CoverInitializedName
2632       //
2633       // CoverInitializedName
2634       //    IdentifierReference Initializer?
2635       DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2636 
2637       if (!ClassifyPropertyIdentifier(name_token, prop_info)) {
2638         return impl()->NullLiteralProperty();
2639       }
2640 
2641       ExpressionT lhs =
2642           impl()->ExpressionFromIdentifier(name, next_loc.beg_pos);
2643       if (!IsAssignableIdentifier(lhs)) {
2644         expression_scope()->RecordPatternError(
2645             next_loc, MessageTemplate::kStrictEvalArguments);
2646       }
2647 
2648       ExpressionT value;
2649       if (peek() == Token::ASSIGN) {
2650         Consume(Token::ASSIGN);
2651         {
2652           AcceptINScope scope(this, true);
2653           ExpressionT rhs = ParseAssignmentExpression();
2654           value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
2655                                            kNoSourcePosition);
2656           impl()->SetFunctionNameFromIdentifierRef(rhs, lhs);
2657         }
2658         expression_scope()->RecordExpressionError(
2659             Scanner::Location(next_loc.beg_pos, end_position()),
2660             MessageTemplate::kInvalidCoverInitializedName);
2661       } else {
2662         value = lhs;
2663       }
2664 
2665       ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2666           name_expression, value, ObjectLiteralProperty::COMPUTED, false);
2667       impl()->SetFunctionNameFromPropertyName(result, name);
2668       return result;
2669     }
2670 
2671     case ParsePropertyKind::kMethod: {
2672       // MethodDefinition
2673       //    PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2674       //    '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2675 
2676       expression_scope()->RecordPatternError(
2677           Scanner::Location(next_loc.beg_pos, end_position()),
2678           MessageTemplate::kInvalidDestructuringTarget);
2679 
2680       std::unique_ptr<BlockState> block_state;
2681       if (object_literal_scope_ != nullptr) {
2682         DCHECK_EQ(object_literal_scope_->outer_scope(), scope_);
2683         block_state.reset(new BlockState(&scope_, object_literal_scope_));
2684       }
2685       constexpr bool kIsStatic = false;
2686       FunctionKind kind = MethodKindFor(kIsStatic, function_flags);
2687 
2688       ExpressionT value = impl()->ParseFunctionLiteral(
2689           name, scanner()->location(), kSkipFunctionNameCheck, kind,
2690           next_loc.beg_pos, FunctionSyntaxKind::kAccessorOrMethod,
2691           language_mode(), nullptr);
2692 
2693       ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2694           name_expression, value, ObjectLiteralProperty::COMPUTED,
2695           prop_info->is_computed_name);
2696       impl()->SetFunctionNameFromPropertyName(result, name);
2697       return result;
2698     }
2699 
2700     case ParsePropertyKind::kAccessorGetter:
2701     case ParsePropertyKind::kAccessorSetter: {
2702       DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2703       bool is_get = prop_info->kind == ParsePropertyKind::kAccessorGetter;
2704 
2705       expression_scope()->RecordPatternError(
2706           Scanner::Location(next_loc.beg_pos, end_position()),
2707           MessageTemplate::kInvalidDestructuringTarget);
2708 
2709       if (!prop_info->is_computed_name) {
2710         // Make sure the name expression is a string since we need a Name for
2711         // Runtime_DefineAccessorPropertyUnchecked and since we can determine
2712         // this statically we can skip the extra runtime check.
2713         name_expression =
2714             factory()->NewStringLiteral(name, name_expression->position());
2715       }
2716 
2717       std::unique_ptr<BlockState> block_state;
2718       if (object_literal_scope_ != nullptr) {
2719         DCHECK_EQ(object_literal_scope_->outer_scope(), scope_);
2720         block_state.reset(new BlockState(&scope_, object_literal_scope_));
2721       }
2722 
2723       FunctionKind kind = is_get ? FunctionKind::kGetterFunction
2724                                  : FunctionKind::kSetterFunction;
2725 
2726       FunctionLiteralT value = impl()->ParseFunctionLiteral(
2727           name, scanner()->location(), kSkipFunctionNameCheck, kind,
2728           next_loc.beg_pos, FunctionSyntaxKind::kAccessorOrMethod,
2729           language_mode(), nullptr);
2730 
2731       ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2732           name_expression, value,
2733           is_get ? ObjectLiteralProperty::GETTER
2734                  : ObjectLiteralProperty::SETTER,
2735           prop_info->is_computed_name);
2736       const AstRawString* prefix =
2737           is_get ? ast_value_factory()->get_space_string()
2738                  : ast_value_factory()->set_space_string();
2739       impl()->SetFunctionNameFromPropertyName(result, name, prefix);
2740       return result;
2741     }
2742 
2743     case ParsePropertyKind::kClassField:
2744     case ParsePropertyKind::kNotSet:
2745       ReportUnexpectedToken(Next());
2746       return impl()->NullLiteralProperty();
2747   }
2748   UNREACHABLE();
2749 }
2750 
2751 template <typename Impl>
ParseObjectLiteral()2752 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral() {
2753   // ObjectLiteral ::
2754   // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2755 
2756   int pos = peek_position();
2757   ObjectPropertyListT properties(pointer_buffer());
2758   int number_of_boilerplate_properties = 0;
2759 
2760   bool has_computed_names = false;
2761   bool has_rest_property = false;
2762   bool has_seen_proto = false;
2763 
2764   Consume(Token::LBRACE);
2765   AccumulationScope accumulation_scope(expression_scope());
2766 
2767   // If methods appear inside the object literal, we'll enter this scope.
2768   Scope* block_scope = NewBlockScopeForObjectLiteral();
2769   block_scope->set_start_position(pos);
2770   BlockState object_literal_scope_state(&object_literal_scope_, block_scope);
2771 
2772   while (!Check(Token::RBRACE)) {
2773     FuncNameInferrerState fni_state(&fni_);
2774 
2775     ParsePropertyInfo prop_info(this, &accumulation_scope);
2776     prop_info.position = PropertyPosition::kObjectLiteral;
2777     ObjectLiteralPropertyT property =
2778         ParseObjectPropertyDefinition(&prop_info, &has_seen_proto);
2779     if (impl()->IsNull(property)) return impl()->FailureExpression();
2780 
2781     if (prop_info.is_computed_name) {
2782       has_computed_names = true;
2783     }
2784 
2785     if (prop_info.is_rest) {
2786       has_rest_property = true;
2787     }
2788 
2789     if (impl()->IsBoilerplateProperty(property) && !has_computed_names) {
2790       // Count CONSTANT or COMPUTED properties to maintain the enumeration
2791       // order.
2792       number_of_boilerplate_properties++;
2793     }
2794 
2795     properties.Add(property);
2796 
2797     if (peek() != Token::RBRACE) {
2798       Expect(Token::COMMA);
2799     }
2800 
2801     fni_.Infer();
2802   }
2803 
2804   Variable* home_object = nullptr;
2805   if (block_scope->needs_home_object()) {
2806     home_object = block_scope->DeclareHomeObjectVariable(ast_value_factory());
2807     block_scope->set_end_position(end_position());
2808   } else {
2809     block_scope = block_scope->FinalizeBlockScope();
2810     DCHECK_NULL(block_scope);
2811   }
2812 
2813   // In pattern rewriter, we rewrite rest property to call out to a
2814   // runtime function passing all the other properties as arguments to
2815   // this runtime function. Here, we make sure that the number of
2816   // properties is less than number of arguments allowed for a runtime
2817   // call.
2818   if (has_rest_property && properties.length() > Code::kMaxArguments) {
2819     expression_scope()->RecordPatternError(Scanner::Location(pos, position()),
2820                                            MessageTemplate::kTooManyArguments);
2821   }
2822 
2823   return impl()->InitializeObjectLiteral(
2824       factory()->NewObjectLiteral(properties, number_of_boilerplate_properties,
2825                                   pos, has_rest_property, home_object));
2826 }
2827 
2828 template <typename Impl>
ParseArguments(typename ParserBase<Impl>::ExpressionListT * args,bool * has_spread,ParsingArrowHeadFlag maybe_arrow)2829 void ParserBase<Impl>::ParseArguments(
2830     typename ParserBase<Impl>::ExpressionListT* args, bool* has_spread,
2831     ParsingArrowHeadFlag maybe_arrow) {
2832   // Arguments ::
2833   //   '(' (AssignmentExpression)*[','] ')'
2834 
2835   *has_spread = false;
2836   Consume(Token::LPAREN);
2837   AccumulationScope accumulation_scope(expression_scope());
2838 
2839   int variable_index = 0;
2840   while (peek() != Token::RPAREN) {
2841     int start_pos = peek_position();
2842     bool is_spread = Check(Token::ELLIPSIS);
2843     int expr_pos = peek_position();
2844 
2845     AcceptINScope scope(this, true);
2846     ExpressionT argument = ParseAssignmentExpressionCoverGrammar();
2847 
2848     if (V8_UNLIKELY(maybe_arrow == kMaybeArrowHead)) {
2849       ClassifyArrowParameter(&accumulation_scope, expr_pos, argument);
2850       if (is_spread) {
2851         expression_scope()->RecordNonSimpleParameter();
2852         if (argument->IsAssignment()) {
2853           expression_scope()->RecordAsyncArrowParametersError(
2854               scanner()->location(), MessageTemplate::kRestDefaultInitializer);
2855         }
2856         if (peek() == Token::COMMA) {
2857           expression_scope()->RecordAsyncArrowParametersError(
2858               scanner()->peek_location(), MessageTemplate::kParamAfterRest);
2859         }
2860       }
2861     }
2862     if (is_spread) {
2863       *has_spread = true;
2864       argument = factory()->NewSpread(argument, start_pos, expr_pos);
2865     }
2866     args->Add(argument);
2867 
2868     variable_index =
2869         expression_scope()->SetInitializers(variable_index, peek_position());
2870 
2871     if (!Check(Token::COMMA)) break;
2872   }
2873 
2874   if (args->length() > Code::kMaxArguments) {
2875     ReportMessage(MessageTemplate::kTooManyArguments);
2876     return;
2877   }
2878 
2879   Scanner::Location location = scanner_->location();
2880   if (!Check(Token::RPAREN)) {
2881     impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
2882   }
2883 }
2884 
2885 // Precedence = 2
2886 template <typename Impl>
2887 typename ParserBase<Impl>::ExpressionT
ParseAssignmentExpressionCoverGrammar()2888 ParserBase<Impl>::ParseAssignmentExpressionCoverGrammar() {
2889   // AssignmentExpression ::
2890   //   ConditionalExpression
2891   //   ArrowFunction
2892   //   YieldExpression
2893   //   LeftHandSideExpression AssignmentOperator AssignmentExpression
2894   int lhs_beg_pos = peek_position();
2895 
2896   if (peek() == Token::YIELD && is_generator()) {
2897     return ParseYieldExpression();
2898   }
2899 
2900   FuncNameInferrerState fni_state(&fni_);
2901 
2902   DCHECK_IMPLIES(!has_error(), next_arrow_function_info_.HasInitialState());
2903 
2904   ExpressionT expression = ParseConditionalExpression();
2905 
2906   Token::Value op = peek();
2907 
2908   if (!Token::IsArrowOrAssignmentOp(op)) return expression;
2909 
2910   // Arrow functions.
2911   if (V8_UNLIKELY(op == Token::ARROW)) {
2912     Scanner::Location loc(lhs_beg_pos, end_position());
2913 
2914     if (!impl()->IsIdentifier(expression) && !expression->is_parenthesized()) {
2915       impl()->ReportMessageAt(
2916           Scanner::Location(expression->position(), position()),
2917           MessageTemplate::kMalformedArrowFunParamList);
2918       return impl()->FailureExpression();
2919     }
2920 
2921     DeclarationScope* scope = next_arrow_function_info_.scope;
2922     scope->set_start_position(lhs_beg_pos);
2923 
2924     FormalParametersT parameters(scope);
2925     parameters.set_strict_parameter_error(
2926         next_arrow_function_info_.strict_parameter_error_location,
2927         next_arrow_function_info_.strict_parameter_error_message);
2928     parameters.is_simple = scope->has_simple_parameters();
2929     next_arrow_function_info_.Reset();
2930 
2931     impl()->DeclareArrowFunctionFormalParameters(&parameters, expression, loc);
2932 
2933     expression = ParseArrowFunctionLiteral(parameters);
2934 
2935     return expression;
2936   }
2937 
2938   if (V8_LIKELY(impl()->IsAssignableIdentifier(expression))) {
2939     if (expression->is_parenthesized()) {
2940       expression_scope()->RecordDeclarationError(
2941           Scanner::Location(lhs_beg_pos, end_position()),
2942           MessageTemplate::kInvalidDestructuringTarget);
2943     }
2944     expression_scope()->MarkIdentifierAsAssigned();
2945   } else if (expression->IsProperty()) {
2946     expression_scope()->RecordDeclarationError(
2947         Scanner::Location(lhs_beg_pos, end_position()),
2948         MessageTemplate::kInvalidPropertyBindingPattern);
2949     expression_scope()->ValidateAsExpression();
2950   } else if (expression->IsPattern() && op == Token::ASSIGN) {
2951     // Destructuring assignmment.
2952     if (expression->is_parenthesized()) {
2953       Scanner::Location loc(lhs_beg_pos, end_position());
2954       if (expression_scope()->IsCertainlyDeclaration()) {
2955         impl()->ReportMessageAt(loc,
2956                                 MessageTemplate::kInvalidDestructuringTarget);
2957       } else {
2958         // Syntax Error if LHS is neither object literal nor an array literal
2959         // (Parenthesized literals are
2960         // CoverParenthesizedExpressionAndArrowParameterList).
2961         // #sec-assignment-operators-static-semantics-early-errors
2962         impl()->ReportMessageAt(loc, MessageTemplate::kInvalidLhsInAssignment);
2963       }
2964     }
2965     expression_scope()->ValidateAsPattern(expression, lhs_beg_pos,
2966                                           end_position());
2967   } else {
2968     DCHECK(!IsValidReferenceExpression(expression));
2969     // For web compatibility reasons, throw early errors only for logical
2970     // assignment, not for regular assignment.
2971     const bool early_error = Token::IsLogicalAssignmentOp(op);
2972     expression = RewriteInvalidReferenceExpression(
2973         expression, lhs_beg_pos, end_position(),
2974         MessageTemplate::kInvalidLhsInAssignment, early_error);
2975   }
2976 
2977   Consume(op);
2978   int op_position = position();
2979 
2980   ExpressionT right = ParseAssignmentExpression();
2981 
2982   // Anonymous function name inference applies to =, ||=, &&=, and ??=.
2983   if (op == Token::ASSIGN || Token::IsLogicalAssignmentOp(op)) {
2984     impl()->CheckAssigningFunctionLiteralToProperty(expression, right);
2985 
2986     // Check if the right hand side is a call to avoid inferring a
2987     // name if we're dealing with "a = function(){...}();"-like
2988     // expression.
2989     if (right->IsCall() || right->IsCallNew()) {
2990       fni_.RemoveLastFunction();
2991     } else {
2992       fni_.Infer();
2993     }
2994 
2995     impl()->SetFunctionNameFromIdentifierRef(right, expression);
2996   } else {
2997     fni_.RemoveLastFunction();
2998   }
2999 
3000   if (op == Token::ASSIGN) {
3001     // We try to estimate the set of properties set by constructors. We define a
3002     // new property whenever there is an assignment to a property of 'this'. We
3003     // should probably only add properties if we haven't seen them before.
3004     // Otherwise we'll probably overestimate the number of properties.
3005     if (impl()->IsThisProperty(expression)) function_state_->AddProperty();
3006   } else {
3007     // Only initializers (i.e. no compound assignments) are allowed in patterns.
3008     expression_scope()->RecordPatternError(
3009         Scanner::Location(lhs_beg_pos, end_position()),
3010         MessageTemplate::kInvalidDestructuringTarget);
3011   }
3012 
3013   return factory()->NewAssignment(op, expression, right, op_position);
3014 }
3015 
3016 template <typename Impl>
3017 typename ParserBase<Impl>::ExpressionT
ParseYieldExpression()3018 ParserBase<Impl>::ParseYieldExpression() {
3019   // YieldExpression ::
3020   //   'yield' ([no line terminator] '*'? AssignmentExpression)?
3021   int pos = peek_position();
3022   expression_scope()->RecordParameterInitializerError(
3023       scanner()->peek_location(), MessageTemplate::kYieldInParameter);
3024   Consume(Token::YIELD);
3025   if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
3026     impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
3027   }
3028 
3029   CheckStackOverflow();
3030 
3031   // The following initialization is necessary.
3032   ExpressionT expression = impl()->NullExpression();
3033   bool delegating = false;  // yield*
3034   if (!scanner()->HasLineTerminatorBeforeNext()) {
3035     if (Check(Token::MUL)) delegating = true;
3036     switch (peek()) {
3037       case Token::EOS:
3038       case Token::SEMICOLON:
3039       case Token::RBRACE:
3040       case Token::RBRACK:
3041       case Token::RPAREN:
3042       case Token::COLON:
3043       case Token::COMMA:
3044       case Token::IN:
3045         // The above set of tokens is the complete set of tokens that can appear
3046         // after an AssignmentExpression, and none of them can start an
3047         // AssignmentExpression.  This allows us to avoid looking for an RHS for
3048         // a regular yield, given only one look-ahead token.
3049         if (!delegating) break;
3050         // Delegating yields require an RHS; fall through.
3051         V8_FALLTHROUGH;
3052       default:
3053         expression = ParseAssignmentExpressionCoverGrammar();
3054         break;
3055     }
3056   }
3057 
3058   if (delegating) {
3059     ExpressionT yieldstar = factory()->NewYieldStar(expression, pos);
3060     impl()->RecordSuspendSourceRange(yieldstar, PositionAfterSemicolon());
3061     function_state_->AddSuspend();
3062     if (IsAsyncGeneratorFunction(function_state_->kind())) {
3063       // return, iterator_close and delegated_iterator_output suspend ids.
3064       function_state_->AddSuspend();
3065       function_state_->AddSuspend();
3066       function_state_->AddSuspend();
3067     }
3068     return yieldstar;
3069   }
3070 
3071   // Hackily disambiguate o from o.next and o [Symbol.iterator]().
3072   // TODO(verwaest): Come up with a better solution.
3073   ExpressionT yield =
3074       factory()->NewYield(expression, pos, Suspend::kOnExceptionThrow);
3075   impl()->RecordSuspendSourceRange(yield, PositionAfterSemicolon());
3076   function_state_->AddSuspend();
3077   return yield;
3078 }
3079 
3080 // Precedence = 3
3081 template <typename Impl>
3082 typename ParserBase<Impl>::ExpressionT
ParseConditionalExpression()3083 ParserBase<Impl>::ParseConditionalExpression() {
3084   // ConditionalExpression ::
3085   //   LogicalExpression
3086   //   LogicalExpression '?' AssignmentExpression ':' AssignmentExpression
3087   //
3088   int pos = peek_position();
3089   ExpressionT expression = ParseLogicalExpression();
3090   return peek() == Token::CONDITIONAL
3091              ? ParseConditionalContinuation(expression, pos)
3092              : expression;
3093 }
3094 
3095 template <typename Impl>
3096 typename ParserBase<Impl>::ExpressionT
ParseLogicalExpression()3097 ParserBase<Impl>::ParseLogicalExpression() {
3098   // LogicalExpression ::
3099   //   LogicalORExpression
3100   //   CoalesceExpression
3101 
3102   // Both LogicalORExpression and CoalesceExpression start with BitwiseOR.
3103   // Parse for binary expressions >= 6 (BitwiseOR);
3104   ExpressionT expression = ParseBinaryExpression(6);
3105   if (peek() == Token::AND || peek() == Token::OR) {
3106     // LogicalORExpression, pickup parsing where we left off.
3107     int prec1 = Token::Precedence(peek(), accept_IN_);
3108     expression = ParseBinaryContinuation(expression, 4, prec1);
3109   } else if (V8_UNLIKELY(peek() == Token::NULLISH)) {
3110     expression = ParseCoalesceExpression(expression);
3111   }
3112   return expression;
3113 }
3114 
3115 template <typename Impl>
3116 typename ParserBase<Impl>::ExpressionT
ParseCoalesceExpression(ExpressionT expression)3117 ParserBase<Impl>::ParseCoalesceExpression(ExpressionT expression) {
3118   // CoalesceExpression ::
3119   //   CoalesceExpressionHead ?? BitwiseORExpression
3120   //
3121   //   CoalesceExpressionHead ::
3122   //     CoalesceExpression
3123   //     BitwiseORExpression
3124 
3125   // We create a binary operation for the first nullish, otherwise collapse
3126   // into an nary expresion.
3127   bool first_nullish = true;
3128   while (peek() == Token::NULLISH) {
3129     SourceRange right_range;
3130     int pos;
3131     ExpressionT y;
3132     {
3133       SourceRangeScope right_range_scope(scanner(), &right_range);
3134       Consume(Token::NULLISH);
3135       pos = peek_position();
3136       // Parse BitwiseOR or higher.
3137       y = ParseBinaryExpression(6);
3138     }
3139     if (first_nullish) {
3140       expression =
3141           factory()->NewBinaryOperation(Token::NULLISH, expression, y, pos);
3142       impl()->RecordBinaryOperationSourceRange(expression, right_range);
3143       first_nullish = false;
3144     } else {
3145       impl()->CollapseNaryExpression(&expression, y, Token::NULLISH, pos,
3146                                      right_range);
3147     }
3148   }
3149   return expression;
3150 }
3151 
3152 template <typename Impl>
3153 typename ParserBase<Impl>::ExpressionT
ParseConditionalContinuation(ExpressionT expression,int pos)3154 ParserBase<Impl>::ParseConditionalContinuation(ExpressionT expression,
3155                                                int pos) {
3156   SourceRange then_range, else_range;
3157 
3158   ExpressionT left;
3159   {
3160     SourceRangeScope range_scope(scanner(), &then_range);
3161     Consume(Token::CONDITIONAL);
3162     // In parsing the first assignment expression in conditional
3163     // expressions we always accept the 'in' keyword; see ECMA-262,
3164     // section 11.12, page 58.
3165     AcceptINScope scope(this, true);
3166     left = ParseAssignmentExpression();
3167   }
3168   ExpressionT right;
3169   {
3170     SourceRangeScope range_scope(scanner(), &else_range);
3171     Expect(Token::COLON);
3172     right = ParseAssignmentExpression();
3173   }
3174   ExpressionT expr = factory()->NewConditional(expression, left, right, pos);
3175   impl()->RecordConditionalSourceRange(expr, then_range, else_range);
3176   return expr;
3177 }
3178 
3179 // Precedence >= 4
3180 template <typename Impl>
3181 typename ParserBase<Impl>::ExpressionT
ParseBinaryContinuation(ExpressionT x,int prec,int prec1)3182 ParserBase<Impl>::ParseBinaryContinuation(ExpressionT x, int prec, int prec1) {
3183   do {
3184     // prec1 >= 4
3185     while (Token::Precedence(peek(), accept_IN_) == prec1) {
3186       SourceRange right_range;
3187       int pos = peek_position();
3188       ExpressionT y;
3189       Token::Value op;
3190       {
3191         SourceRangeScope right_range_scope(scanner(), &right_range);
3192         op = Next();
3193 
3194         const bool is_right_associative = op == Token::EXP;
3195         const int next_prec = is_right_associative ? prec1 : prec1 + 1;
3196         y = ParseBinaryExpression(next_prec);
3197       }
3198 
3199       // For now we distinguish between comparisons and other binary
3200       // operations.  (We could combine the two and get rid of this
3201       // code and AST node eventually.)
3202       if (Token::IsCompareOp(op)) {
3203         // We have a comparison.
3204         Token::Value cmp = op;
3205         switch (op) {
3206           case Token::NE: cmp = Token::EQ; break;
3207           case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
3208           default: break;
3209         }
3210         x = factory()->NewCompareOperation(cmp, x, y, pos);
3211         if (cmp != op) {
3212           // The comparison was negated - add a NOT.
3213           x = factory()->NewUnaryOperation(Token::NOT, x, pos);
3214         }
3215       } else if (!impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op,
3216                                                                  pos) &&
3217                  !impl()->CollapseNaryExpression(&x, y, op, pos, right_range)) {
3218         // We have a "normal" binary operation.
3219         x = factory()->NewBinaryOperation(op, x, y, pos);
3220         if (op == Token::OR || op == Token::AND) {
3221           impl()->RecordBinaryOperationSourceRange(x, right_range);
3222         }
3223       }
3224     }
3225     --prec1;
3226   } while (prec1 >= prec);
3227 
3228   return x;
3229 }
3230 
3231 // Precedence >= 4
3232 template <typename Impl>
ParseBinaryExpression(int prec)3233 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
3234     int prec) {
3235   DCHECK_GE(prec, 4);
3236 
3237   // "#foo in ShiftExpression" needs to be parsed separately, since private
3238   // identifiers are not valid PrimaryExpressions.
3239   if (V8_UNLIKELY(FLAG_harmony_private_brand_checks &&
3240                   peek() == Token::PRIVATE_NAME)) {
3241     ExpressionT x = ParsePropertyOrPrivatePropertyName();
3242     int prec1 = Token::Precedence(peek(), accept_IN_);
3243     if (peek() != Token::IN || prec1 < prec) {
3244       ReportUnexpectedToken(Token::PRIVATE_NAME);
3245       return impl()->FailureExpression();
3246     }
3247     return ParseBinaryContinuation(x, prec, prec1);
3248   }
3249 
3250   ExpressionT x = ParseUnaryExpression();
3251   int prec1 = Token::Precedence(peek(), accept_IN_);
3252   if (prec1 >= prec) {
3253     return ParseBinaryContinuation(x, prec, prec1);
3254   }
3255   return x;
3256 }
3257 
3258 template <typename Impl>
3259 typename ParserBase<Impl>::ExpressionT
ParseUnaryOrPrefixExpression()3260 ParserBase<Impl>::ParseUnaryOrPrefixExpression() {
3261   Token::Value op = Next();
3262   int pos = position();
3263 
3264   // Assume "! function ..." indicates the function is likely to be called.
3265   if (op == Token::NOT && peek() == Token::FUNCTION) {
3266     function_state_->set_next_function_is_likely_called();
3267   }
3268 
3269   CheckStackOverflow();
3270 
3271   int expression_position = peek_position();
3272   ExpressionT expression = ParseUnaryExpression();
3273 
3274   if (Token::IsUnaryOp(op)) {
3275     if (op == Token::DELETE) {
3276       if (impl()->IsIdentifier(expression) && is_strict(language_mode())) {
3277         // "delete identifier" is a syntax error in strict mode.
3278         ReportMessage(MessageTemplate::kStrictDelete);
3279         return impl()->FailureExpression();
3280       }
3281 
3282       if (impl()->IsPrivateReference(expression)) {
3283         ReportMessage(MessageTemplate::kDeletePrivateField);
3284         return impl()->FailureExpression();
3285       }
3286     }
3287 
3288     if (peek() == Token::EXP) {
3289       impl()->ReportMessageAt(
3290           Scanner::Location(pos, peek_end_position()),
3291           MessageTemplate::kUnexpectedTokenUnaryExponentiation);
3292       return impl()->FailureExpression();
3293     }
3294 
3295     // Allow the parser's implementation to rewrite the expression.
3296     return impl()->BuildUnaryExpression(expression, op, pos);
3297   }
3298 
3299   DCHECK(Token::IsCountOp(op));
3300 
3301   if (V8_LIKELY(IsValidReferenceExpression(expression))) {
3302     if (impl()->IsIdentifier(expression)) {
3303       expression_scope()->MarkIdentifierAsAssigned();
3304     }
3305   } else {
3306     const bool early_error = false;
3307     expression = RewriteInvalidReferenceExpression(
3308         expression, expression_position, end_position(),
3309         MessageTemplate::kInvalidLhsInPrefixOp, early_error);
3310   }
3311 
3312   return factory()->NewCountOperation(op, true /* prefix */, expression,
3313                                       position());
3314 }
3315 
3316 template <typename Impl>
3317 typename ParserBase<Impl>::ExpressionT
ParseAwaitExpression()3318 ParserBase<Impl>::ParseAwaitExpression() {
3319   expression_scope()->RecordParameterInitializerError(
3320       scanner()->peek_location(),
3321       MessageTemplate::kAwaitExpressionFormalParameter);
3322   int await_pos = peek_position();
3323   Consume(Token::AWAIT);
3324   if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
3325     impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
3326   }
3327 
3328   CheckStackOverflow();
3329 
3330   ExpressionT value = ParseUnaryExpression();
3331 
3332   // 'await' is a unary operator according to the spec, even though it's treated
3333   // specially in the parser.
3334   if (peek() == Token::EXP) {
3335     impl()->ReportMessageAt(
3336         Scanner::Location(await_pos, peek_end_position()),
3337         MessageTemplate::kUnexpectedTokenUnaryExponentiation);
3338     return impl()->FailureExpression();
3339   }
3340 
3341   ExpressionT expr = factory()->NewAwait(value, await_pos);
3342   function_state_->AddSuspend();
3343   impl()->RecordSuspendSourceRange(expr, PositionAfterSemicolon());
3344   return expr;
3345 }
3346 
3347 template <typename Impl>
3348 typename ParserBase<Impl>::ExpressionT
ParseUnaryExpression()3349 ParserBase<Impl>::ParseUnaryExpression() {
3350   // UnaryExpression ::
3351   //   PostfixExpression
3352   //   'delete' UnaryExpression
3353   //   'void' UnaryExpression
3354   //   'typeof' UnaryExpression
3355   //   '++' UnaryExpression
3356   //   '--' UnaryExpression
3357   //   '+' UnaryExpression
3358   //   '-' UnaryExpression
3359   //   '~' UnaryExpression
3360   //   '!' UnaryExpression
3361   //   [+Await] AwaitExpression[?Yield]
3362 
3363   Token::Value op = peek();
3364   if (Token::IsUnaryOrCountOp(op)) return ParseUnaryOrPrefixExpression();
3365   if (is_await_allowed() && op == Token::AWAIT) {
3366     return ParseAwaitExpression();
3367   }
3368   return ParsePostfixExpression();
3369 }
3370 
3371 template <typename Impl>
3372 typename ParserBase<Impl>::ExpressionT
ParsePostfixExpression()3373 ParserBase<Impl>::ParsePostfixExpression() {
3374   // PostfixExpression ::
3375   //   LeftHandSideExpression ('++' | '--')?
3376 
3377   int lhs_beg_pos = peek_position();
3378   ExpressionT expression = ParseLeftHandSideExpression();
3379   if (V8_LIKELY(!Token::IsCountOp(peek()) ||
3380                 scanner()->HasLineTerminatorBeforeNext())) {
3381     return expression;
3382   }
3383   return ParsePostfixContinuation(expression, lhs_beg_pos);
3384 }
3385 
3386 template <typename Impl>
3387 typename ParserBase<Impl>::ExpressionT
ParsePostfixContinuation(ExpressionT expression,int lhs_beg_pos)3388 ParserBase<Impl>::ParsePostfixContinuation(ExpressionT expression,
3389                                            int lhs_beg_pos) {
3390   if (V8_UNLIKELY(!IsValidReferenceExpression(expression))) {
3391     const bool early_error = false;
3392     expression = RewriteInvalidReferenceExpression(
3393         expression, lhs_beg_pos, end_position(),
3394         MessageTemplate::kInvalidLhsInPostfixOp, early_error);
3395   }
3396   if (impl()->IsIdentifier(expression)) {
3397     expression_scope()->MarkIdentifierAsAssigned();
3398   }
3399 
3400   Token::Value next = Next();
3401   return factory()->NewCountOperation(next, false /* postfix */, expression,
3402                                       position());
3403 }
3404 
3405 template <typename Impl>
3406 typename ParserBase<Impl>::ExpressionT
ParseLeftHandSideExpression()3407 ParserBase<Impl>::ParseLeftHandSideExpression() {
3408   // LeftHandSideExpression ::
3409   //   (NewExpression | MemberExpression) ...
3410 
3411   ExpressionT result = ParseMemberExpression();
3412   if (!Token::IsPropertyOrCall(peek())) return result;
3413   return ParseLeftHandSideContinuation(result);
3414 }
3415 
3416 template <typename Impl>
3417 typename ParserBase<Impl>::ExpressionT
ParseLeftHandSideContinuation(ExpressionT result)3418 ParserBase<Impl>::ParseLeftHandSideContinuation(ExpressionT result) {
3419   DCHECK(Token::IsPropertyOrCall(peek()));
3420 
3421   if (V8_UNLIKELY(peek() == Token::LPAREN && impl()->IsIdentifier(result) &&
3422                   scanner()->current_token() == Token::ASYNC &&
3423                   !scanner()->HasLineTerminatorBeforeNext() &&
3424                   !scanner()->literal_contains_escapes())) {
3425     DCHECK(impl()->IsAsync(impl()->AsIdentifier(result)));
3426     int pos = position();
3427 
3428     ArrowHeadParsingScope maybe_arrow(impl(),
3429                                       FunctionKind::kAsyncArrowFunction);
3430     Scope::Snapshot scope_snapshot(scope());
3431 
3432     ExpressionListT args(pointer_buffer());
3433     bool has_spread;
3434     ParseArguments(&args, &has_spread, kMaybeArrowHead);
3435     if (V8_LIKELY(peek() == Token::ARROW)) {
3436       fni_.RemoveAsyncKeywordFromEnd();
3437       next_arrow_function_info_.scope = maybe_arrow.ValidateAndCreateScope();
3438       scope_snapshot.Reparent(next_arrow_function_info_.scope);
3439       // async () => ...
3440       if (!args.length()) return factory()->NewEmptyParentheses(pos);
3441       // async ( Arguments ) => ...
3442       result = impl()->ExpressionListToExpression(args);
3443       result->mark_parenthesized();
3444       return result;
3445     }
3446 
3447     result = factory()->NewCall(result, args, pos, has_spread);
3448 
3449     maybe_arrow.ValidateExpression();
3450 
3451     fni_.RemoveLastFunction();
3452     if (!Token::IsPropertyOrCall(peek())) return result;
3453   }
3454 
3455   bool optional_chaining = false;
3456   bool is_optional = false;
3457   int optional_link_begin;
3458   do {
3459     switch (peek()) {
3460       case Token::QUESTION_PERIOD: {
3461         if (is_optional) {
3462           ReportUnexpectedToken(peek());
3463           return impl()->FailureExpression();
3464         }
3465         // Include the ?. in the source range position.
3466         optional_link_begin = scanner()->peek_location().beg_pos;
3467         Consume(Token::QUESTION_PERIOD);
3468         is_optional = true;
3469         optional_chaining = true;
3470         if (Token::IsPropertyOrCall(peek())) continue;
3471         int pos = position();
3472         ExpressionT key = ParsePropertyOrPrivatePropertyName();
3473         result = factory()->NewProperty(result, key, pos, is_optional);
3474         break;
3475       }
3476 
3477       /* Property */
3478       case Token::LBRACK: {
3479         Consume(Token::LBRACK);
3480         int pos = position();
3481         AcceptINScope scope(this, true);
3482         ExpressionT index = ParseExpressionCoverGrammar();
3483         result = factory()->NewProperty(result, index, pos, is_optional);
3484         Expect(Token::RBRACK);
3485         break;
3486       }
3487 
3488       /* Property */
3489       case Token::PERIOD: {
3490         if (is_optional) {
3491           ReportUnexpectedToken(Next());
3492           return impl()->FailureExpression();
3493         }
3494         Consume(Token::PERIOD);
3495         int pos = position();
3496         ExpressionT key = ParsePropertyOrPrivatePropertyName();
3497         result = factory()->NewProperty(result, key, pos, is_optional);
3498         break;
3499       }
3500 
3501       /* Call */
3502       case Token::LPAREN: {
3503         int pos;
3504         if (Token::IsCallable(scanner()->current_token())) {
3505           // For call of an identifier we want to report position of
3506           // the identifier as position of the call in the stack trace.
3507           pos = position();
3508         } else {
3509           // For other kinds of calls we record position of the parenthesis as
3510           // position of the call. Note that this is extremely important for
3511           // expressions of the form function(){...}() for which call position
3512           // should not point to the closing brace otherwise it will intersect
3513           // with positions recorded for function literal and confuse debugger.
3514           pos = peek_position();
3515           // Also the trailing parenthesis are a hint that the function will
3516           // be called immediately. If we happen to have parsed a preceding
3517           // function literal eagerly, we can also compile it eagerly.
3518           if (result->IsFunctionLiteral()) {
3519             result->AsFunctionLiteral()->SetShouldEagerCompile();
3520           }
3521         }
3522         bool has_spread;
3523         ExpressionListT args(pointer_buffer());
3524         ParseArguments(&args, &has_spread);
3525 
3526         // Keep track of eval() calls since they disable all local variable
3527         // optimizations.
3528         // The calls that need special treatment are the
3529         // direct eval calls. These calls are all of the form eval(...), with
3530         // no explicit receiver.
3531         // These calls are marked as potentially direct eval calls. Whether
3532         // they are actually direct calls to eval is determined at run time.
3533         Call::PossiblyEval is_possibly_eval =
3534             CheckPossibleEvalCall(result, is_optional, scope());
3535 
3536         result = factory()->NewCall(result, args, pos, has_spread,
3537                                     is_possibly_eval, is_optional);
3538 
3539         fni_.RemoveLastFunction();
3540         break;
3541       }
3542 
3543       default:
3544         // Template literals in/after an Optional Chain not supported:
3545         if (optional_chaining) {
3546           impl()->ReportMessageAt(scanner()->peek_location(),
3547                                   MessageTemplate::kOptionalChainingNoTemplate);
3548           return impl()->FailureExpression();
3549         }
3550         /* Tagged Template */
3551         DCHECK(Token::IsTemplate(peek()));
3552         result = ParseTemplateLiteral(result, position(), true);
3553         break;
3554     }
3555     if (is_optional) {
3556       SourceRange chain_link_range(optional_link_begin, end_position());
3557       impl()->RecordExpressionSourceRange(result, chain_link_range);
3558       is_optional = false;
3559     }
3560   } while (Token::IsPropertyOrCall(peek()));
3561   if (optional_chaining) return factory()->NewOptionalChain(result);
3562   return result;
3563 }
3564 
3565 template <typename Impl>
3566 typename ParserBase<Impl>::ExpressionT
ParseMemberWithPresentNewPrefixesExpression()3567 ParserBase<Impl>::ParseMemberWithPresentNewPrefixesExpression() {
3568   // NewExpression ::
3569   //   ('new')+ MemberExpression
3570   //
3571   // NewTarget ::
3572   //   'new' '.' 'target'
3573 
3574   // The grammar for new expressions is pretty warped. We can have several 'new'
3575   // keywords following each other, and then a MemberExpression. When we see '('
3576   // after the MemberExpression, it's associated with the rightmost unassociated
3577   // 'new' to create a NewExpression with arguments. However, a NewExpression
3578   // can also occur without arguments.
3579 
3580   // Examples of new expression:
3581   // new foo.bar().baz means (new (foo.bar)()).baz
3582   // new foo()() means (new foo())()
3583   // new new foo()() means (new (new foo())())
3584   // new new foo means new (new foo)
3585   // new new foo() means new (new foo())
3586   // new new foo().bar().baz means (new (new foo()).bar()).baz
3587   // new super.x means new (super.x)
3588   Consume(Token::NEW);
3589   int new_pos = position();
3590   ExpressionT result;
3591 
3592   CheckStackOverflow();
3593 
3594   if (peek() == Token::IMPORT && PeekAhead() == Token::LPAREN) {
3595     impl()->ReportMessageAt(scanner()->peek_location(),
3596                             MessageTemplate::kImportCallNotNewExpression);
3597     return impl()->FailureExpression();
3598   } else if (peek() == Token::PERIOD) {
3599     result = ParseNewTargetExpression();
3600     return ParseMemberExpressionContinuation(result);
3601   } else {
3602     result = ParseMemberExpression();
3603     if (result->IsSuperCallReference()) {
3604       // new super() is never allowed
3605       impl()->ReportMessageAt(scanner()->location(),
3606                               MessageTemplate::kUnexpectedSuper);
3607       return impl()->FailureExpression();
3608     }
3609   }
3610   if (peek() == Token::LPAREN) {
3611     // NewExpression with arguments.
3612     {
3613       ExpressionListT args(pointer_buffer());
3614       bool has_spread;
3615       ParseArguments(&args, &has_spread);
3616 
3617       result = factory()->NewCallNew(result, args, new_pos, has_spread);
3618     }
3619     // The expression can still continue with . or [ after the arguments.
3620     return ParseMemberExpressionContinuation(result);
3621   }
3622 
3623   if (peek() == Token::QUESTION_PERIOD) {
3624     impl()->ReportMessageAt(scanner()->peek_location(),
3625                             MessageTemplate::kOptionalChainingNoNew);
3626     return impl()->FailureExpression();
3627   }
3628 
3629   // NewExpression without arguments.
3630   ExpressionListT args(pointer_buffer());
3631   return factory()->NewCallNew(result, args, new_pos, false);
3632 }
3633 
3634 template <typename Impl>
3635 typename ParserBase<Impl>::ExpressionT
ParseFunctionExpression()3636 ParserBase<Impl>::ParseFunctionExpression() {
3637   Consume(Token::FUNCTION);
3638   int function_token_position = position();
3639 
3640   FunctionKind function_kind = Check(Token::MUL)
3641                                    ? FunctionKind::kGeneratorFunction
3642                                    : FunctionKind::kNormalFunction;
3643   IdentifierT name = impl()->NullIdentifier();
3644   bool is_strict_reserved_name = Token::IsStrictReservedWord(peek());
3645   Scanner::Location function_name_location = Scanner::Location::invalid();
3646   FunctionSyntaxKind function_syntax_kind =
3647       FunctionSyntaxKind::kAnonymousExpression;
3648   if (impl()->ParsingDynamicFunctionDeclaration()) {
3649     // We don't want dynamic functions to actually declare their name
3650     // "anonymous". We just want that name in the toString().
3651     Consume(Token::IDENTIFIER);
3652     DCHECK_IMPLIES(!has_error(),
3653                    scanner()->CurrentSymbol(ast_value_factory()) ==
3654                        ast_value_factory()->anonymous_string());
3655   } else if (peek_any_identifier()) {
3656     name = ParseIdentifier(function_kind);
3657     function_name_location = scanner()->location();
3658     function_syntax_kind = FunctionSyntaxKind::kNamedExpression;
3659   }
3660   FunctionLiteralT result = impl()->ParseFunctionLiteral(
3661       name, function_name_location,
3662       is_strict_reserved_name ? kFunctionNameIsStrictReserved
3663                               : kFunctionNameValidityUnknown,
3664       function_kind, function_token_position, function_syntax_kind,
3665       language_mode(), nullptr);
3666   // TODO(verwaest): FailureFunctionLiteral?
3667   if (impl()->IsNull(result)) return impl()->FailureExpression();
3668   return result;
3669 }
3670 
3671 template <typename Impl>
3672 typename ParserBase<Impl>::ExpressionT
ParseMemberExpression()3673 ParserBase<Impl>::ParseMemberExpression() {
3674   // MemberExpression ::
3675   //   (PrimaryExpression | FunctionLiteral | ClassLiteral)
3676   //     ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
3677   //
3678   // CallExpression ::
3679   //   (SuperCall | ImportCall)
3680   //     ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
3681   //
3682   // The '[' Expression ']' and '.' Identifier parts are parsed by
3683   // ParseMemberExpressionContinuation, and everything preceeding it is merged
3684   // into ParsePrimaryExpression.
3685 
3686   // Parse the initial primary or function expression.
3687   ExpressionT result = ParsePrimaryExpression();
3688   return ParseMemberExpressionContinuation(result);
3689 }
3690 
3691 template <typename Impl>
3692 typename ParserBase<Impl>::ExpressionT
ParseImportExpressions()3693 ParserBase<Impl>::ParseImportExpressions() {
3694   Consume(Token::IMPORT);
3695   int pos = position();
3696   if (Check(Token::PERIOD)) {
3697     ExpectContextualKeyword(ast_value_factory()->meta_string(), "import.meta",
3698                             pos);
3699     if (!flags().is_module()) {
3700       impl()->ReportMessageAt(scanner()->location(),
3701                               MessageTemplate::kImportMetaOutsideModule);
3702       return impl()->FailureExpression();
3703     }
3704 
3705     return impl()->ImportMetaExpression(pos);
3706   }
3707 
3708   if (V8_UNLIKELY(peek() != Token::LPAREN)) {
3709     if (!flags().is_module()) {
3710       impl()->ReportMessageAt(scanner()->location(),
3711                               MessageTemplate::kImportOutsideModule);
3712     } else {
3713       ReportUnexpectedToken(Next());
3714     }
3715     return impl()->FailureExpression();
3716   }
3717 
3718   Consume(Token::LPAREN);
3719   if (peek() == Token::RPAREN) {
3720     impl()->ReportMessageAt(scanner()->location(),
3721                             MessageTemplate::kImportMissingSpecifier);
3722     return impl()->FailureExpression();
3723   }
3724 
3725   AcceptINScope scope(this, true);
3726   ExpressionT specifier = ParseAssignmentExpressionCoverGrammar();
3727 
3728   if (FLAG_harmony_import_assertions && Check(Token::COMMA)) {
3729     if (Check(Token::RPAREN)) {
3730       // A trailing comma allowed after the specifier.
3731       return factory()->NewImportCallExpression(specifier, pos);
3732     } else {
3733       ExpressionT import_assertions = ParseAssignmentExpressionCoverGrammar();
3734       Check(Token::COMMA);  // A trailing comma is allowed after the import
3735                             // assertions.
3736       Expect(Token::RPAREN);
3737       return factory()->NewImportCallExpression(specifier, import_assertions,
3738                                                 pos);
3739     }
3740   }
3741 
3742   Expect(Token::RPAREN);
3743   return factory()->NewImportCallExpression(specifier, pos);
3744 }
3745 
3746 template <typename Impl>
3747 typename ParserBase<Impl>::ExpressionT
ParseSuperExpression()3748 ParserBase<Impl>::ParseSuperExpression() {
3749   Consume(Token::SUPER);
3750   int pos = position();
3751 
3752   DeclarationScope* scope = GetReceiverScope();
3753   FunctionKind kind = scope->function_kind();
3754   if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
3755       IsClassConstructor(kind)) {
3756     if (Token::IsProperty(peek())) {
3757       if (peek() == Token::PERIOD && PeekAhead() == Token::PRIVATE_NAME) {
3758         Consume(Token::PERIOD);
3759         Consume(Token::PRIVATE_NAME);
3760 
3761         impl()->ReportMessage(MessageTemplate::kUnexpectedPrivateField);
3762         return impl()->FailureExpression();
3763       }
3764       if (peek() == Token::QUESTION_PERIOD) {
3765         Consume(Token::QUESTION_PERIOD);
3766         impl()->ReportMessage(MessageTemplate::kOptionalChainingNoSuper);
3767         return impl()->FailureExpression();
3768       }
3769       Scope* home_object_scope = scope->RecordSuperPropertyUsage();
3770       UseThis();
3771       return impl()->NewSuperPropertyReference(home_object_scope, pos);
3772     }
3773     // super() is only allowed in derived constructor. new super() is never
3774     // allowed; it's reported as an error by
3775     // ParseMemberWithPresentNewPrefixesExpression.
3776     if (peek() == Token::LPAREN && IsDerivedConstructor(kind)) {
3777       // TODO(rossberg): This might not be the correct FunctionState for the
3778       // method here.
3779       expression_scope()->RecordThisUse();
3780       UseThis();
3781       return impl()->NewSuperCallReference(pos);
3782     }
3783   }
3784 
3785   impl()->ReportMessageAt(scanner()->location(),
3786                           MessageTemplate::kUnexpectedSuper);
3787   return impl()->FailureExpression();
3788 }
3789 
3790 template <typename Impl>
3791 typename ParserBase<Impl>::ExpressionT
ParseNewTargetExpression()3792 ParserBase<Impl>::ParseNewTargetExpression() {
3793   int pos = position();
3794   Consume(Token::PERIOD);
3795   ExpectContextualKeyword(ast_value_factory()->target_string(), "new.target",
3796                           pos);
3797 
3798   if (!GetReceiverScope()->is_function_scope()) {
3799     impl()->ReportMessageAt(scanner()->location(),
3800                             MessageTemplate::kUnexpectedNewTarget);
3801     return impl()->FailureExpression();
3802   }
3803 
3804   return impl()->NewTargetExpression(pos);
3805 }
3806 
3807 template <typename Impl>
3808 typename ParserBase<Impl>::ExpressionT
DoParseMemberExpressionContinuation(ExpressionT expression)3809 ParserBase<Impl>::DoParseMemberExpressionContinuation(ExpressionT expression) {
3810   DCHECK(Token::IsMember(peek()));
3811   // Parses this part of MemberExpression:
3812   // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3813   do {
3814     switch (peek()) {
3815       case Token::LBRACK: {
3816         Consume(Token::LBRACK);
3817         int pos = position();
3818         AcceptINScope scope(this, true);
3819         ExpressionT index = ParseExpressionCoverGrammar();
3820         expression = factory()->NewProperty(expression, index, pos);
3821         impl()->PushPropertyName(index);
3822         Expect(Token::RBRACK);
3823         break;
3824       }
3825       case Token::PERIOD: {
3826         Consume(Token::PERIOD);
3827         int pos = peek_position();
3828         ExpressionT key = ParsePropertyOrPrivatePropertyName();
3829         expression = factory()->NewProperty(expression, key, pos);
3830         break;
3831       }
3832       default: {
3833         DCHECK(Token::IsTemplate(peek()));
3834         int pos;
3835         if (scanner()->current_token() == Token::IDENTIFIER) {
3836           pos = position();
3837         } else {
3838           pos = peek_position();
3839           if (expression->IsFunctionLiteral()) {
3840             // If the tag function looks like an IIFE, set_parenthesized() to
3841             // force eager compilation.
3842             expression->AsFunctionLiteral()->SetShouldEagerCompile();
3843           }
3844         }
3845         expression = ParseTemplateLiteral(expression, pos, true);
3846         break;
3847       }
3848     }
3849   } while (Token::IsMember(peek()));
3850   return expression;
3851 }
3852 
3853 template <typename Impl>
ParseFormalParameter(FormalParametersT * parameters)3854 void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters) {
3855   // FormalParameter[Yield,GeneratorParameter] :
3856   //   BindingElement[?Yield, ?GeneratorParameter]
3857   FuncNameInferrerState fni_state(&fni_);
3858   int pos = peek_position();
3859   auto declaration_it = scope()->declarations()->end();
3860   ExpressionT pattern = ParseBindingPattern();
3861   if (impl()->IsIdentifier(pattern)) {
3862     ClassifyParameter(impl()->AsIdentifier(pattern), pos, end_position());
3863   } else {
3864     parameters->is_simple = false;
3865   }
3866 
3867   ExpressionT initializer = impl()->NullExpression();
3868   if (Check(Token::ASSIGN)) {
3869     parameters->is_simple = false;
3870 
3871     if (parameters->has_rest) {
3872       ReportMessage(MessageTemplate::kRestDefaultInitializer);
3873       return;
3874     }
3875 
3876     AcceptINScope accept_in_scope(this, true);
3877     initializer = ParseAssignmentExpression();
3878     impl()->SetFunctionNameFromIdentifierRef(initializer, pattern);
3879   }
3880 
3881   auto declaration_end = scope()->declarations()->end();
3882   int initializer_end = end_position();
3883   for (; declaration_it != declaration_end; ++declaration_it) {
3884     Variable* var = declaration_it->var();
3885 
3886     // The first time a variable is initialized (i.e. when the initializer
3887     // position is unset), clear its maybe_assigned flag as it is not a true
3888     // assignment. Since this is done directly on the Variable objects, it has
3889     // no effect on VariableProxy objects appearing on the left-hand side of
3890     // true assignments, so x will be still be marked as maybe_assigned for:
3891     // (x = 1, y = (x = 2)) => {}
3892     // and even:
3893     // (x = (x = 2)) => {}.
3894     if (var->initializer_position() == kNoSourcePosition)
3895       var->clear_maybe_assigned();
3896     var->set_initializer_position(initializer_end);
3897   }
3898 
3899   impl()->AddFormalParameter(parameters, pattern, initializer, end_position(),
3900                              parameters->has_rest);
3901 }
3902 
3903 template <typename Impl>
ParseFormalParameterList(FormalParametersT * parameters)3904 void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters) {
3905   // FormalParameters[Yield] :
3906   //   [empty]
3907   //   FunctionRestParameter[?Yield]
3908   //   FormalParameterList[?Yield]
3909   //   FormalParameterList[?Yield] ,
3910   //   FormalParameterList[?Yield] , FunctionRestParameter[?Yield]
3911   //
3912   // FormalParameterList[Yield] :
3913   //   FormalParameter[?Yield]
3914   //   FormalParameterList[?Yield] , FormalParameter[?Yield]
3915   ParameterParsingScope scope(impl(), parameters);
3916 
3917   DCHECK_EQ(0, parameters->arity);
3918 
3919   if (peek() != Token::RPAREN) {
3920     while (true) {
3921       // Add one since we're going to be adding a parameter.
3922       if (parameters->arity + 1 > Code::kMaxArguments) {
3923         ReportMessage(MessageTemplate::kTooManyParameters);
3924         return;
3925       }
3926       parameters->has_rest = Check(Token::ELLIPSIS);
3927       ParseFormalParameter(parameters);
3928 
3929       if (parameters->has_rest) {
3930         parameters->is_simple = false;
3931         if (peek() == Token::COMMA) {
3932           impl()->ReportMessageAt(scanner()->peek_location(),
3933                                   MessageTemplate::kParamAfterRest);
3934           return;
3935         }
3936         break;
3937       }
3938       if (!Check(Token::COMMA)) break;
3939       if (peek() == Token::RPAREN) {
3940         // allow the trailing comma
3941         break;
3942       }
3943     }
3944   }
3945 
3946   impl()->DeclareFormalParameters(parameters);
3947 }
3948 
3949 template <typename Impl>
ParseVariableDeclarations(VariableDeclarationContext var_context,DeclarationParsingResult * parsing_result,ZonePtrList<const AstRawString> * names)3950 void ParserBase<Impl>::ParseVariableDeclarations(
3951     VariableDeclarationContext var_context,
3952     DeclarationParsingResult* parsing_result,
3953     ZonePtrList<const AstRawString>* names) {
3954   // VariableDeclarations ::
3955   //   ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
3956   //
3957   // ES6:
3958   // FIXME(marja, nikolaos): Add an up-to-date comment about ES6 variable
3959   // declaration syntax.
3960 
3961   DCHECK_NOT_NULL(parsing_result);
3962   parsing_result->descriptor.kind = NORMAL_VARIABLE;
3963   parsing_result->descriptor.declaration_pos = peek_position();
3964   parsing_result->descriptor.initialization_pos = peek_position();
3965 
3966   switch (peek()) {
3967     case Token::VAR:
3968       parsing_result->descriptor.mode = VariableMode::kVar;
3969       Consume(Token::VAR);
3970       break;
3971     case Token::CONST:
3972       Consume(Token::CONST);
3973       DCHECK_NE(var_context, kStatement);
3974       parsing_result->descriptor.mode = VariableMode::kConst;
3975       break;
3976     case Token::LET:
3977       Consume(Token::LET);
3978       DCHECK_NE(var_context, kStatement);
3979       parsing_result->descriptor.mode = VariableMode::kLet;
3980       break;
3981     default:
3982       UNREACHABLE();  // by current callers
3983       break;
3984   }
3985 
3986   VariableDeclarationParsingScope declaration(
3987       impl(), parsing_result->descriptor.mode, names);
3988   Scope* target_scope = IsLexicalVariableMode(parsing_result->descriptor.mode)
3989                             ? scope()
3990                             : scope()->GetDeclarationScope();
3991 
3992   auto declaration_it = target_scope->declarations()->end();
3993 
3994   int bindings_start = peek_position();
3995   do {
3996     // Parse binding pattern.
3997     FuncNameInferrerState fni_state(&fni_);
3998 
3999     int decl_pos = peek_position();
4000 
4001     IdentifierT name;
4002     ExpressionT pattern;
4003     // Check for an identifier first, so that we can elide the pattern in cases
4004     // where there is no initializer (and so no proxy needs to be created).
4005     if (V8_LIKELY(Token::IsAnyIdentifier(peek()))) {
4006       name = ParseAndClassifyIdentifier(Next());
4007       if (V8_UNLIKELY(is_strict(language_mode()) &&
4008                       impl()->IsEvalOrArguments(name))) {
4009         impl()->ReportMessageAt(scanner()->location(),
4010                                 MessageTemplate::kStrictEvalArguments);
4011         return;
4012       }
4013       if (peek() == Token::ASSIGN ||
4014           (var_context == kForStatement && PeekInOrOf()) ||
4015           parsing_result->descriptor.mode == VariableMode::kLet) {
4016         // Assignments need the variable expression for the assignment LHS, and
4017         // for of/in will need it later, so create the expression now.
4018         pattern = impl()->ExpressionFromIdentifier(name, decl_pos);
4019       } else {
4020         // Otherwise, elide the variable expression and just declare it.
4021         impl()->DeclareIdentifier(name, decl_pos);
4022         pattern = impl()->NullExpression();
4023       }
4024     } else {
4025       name = impl()->NullIdentifier();
4026       pattern = ParseBindingPattern();
4027       DCHECK(!impl()->IsIdentifier(pattern));
4028     }
4029 
4030     Scanner::Location variable_loc = scanner()->location();
4031 
4032     ExpressionT value = impl()->NullExpression();
4033     int value_beg_pos = kNoSourcePosition;
4034     if (Check(Token::ASSIGN)) {
4035       DCHECK(!impl()->IsNull(pattern));
4036       {
4037         value_beg_pos = peek_position();
4038         AcceptINScope scope(this, var_context != kForStatement);
4039         value = ParseAssignmentExpression();
4040       }
4041       variable_loc.end_pos = end_position();
4042 
4043       if (!parsing_result->first_initializer_loc.IsValid()) {
4044         parsing_result->first_initializer_loc = variable_loc;
4045       }
4046 
4047       // Don't infer if it is "a = function(){...}();"-like expression.
4048       if (impl()->IsIdentifier(pattern)) {
4049         if (!value->IsCall() && !value->IsCallNew()) {
4050           fni_.Infer();
4051         } else {
4052           fni_.RemoveLastFunction();
4053         }
4054       }
4055 
4056       impl()->SetFunctionNameFromIdentifierRef(value, pattern);
4057     } else {
4058 #ifdef DEBUG
4059       // We can fall through into here on error paths, so don't DCHECK those.
4060       if (!has_error()) {
4061         // We should never get identifier patterns for the non-initializer path,
4062         // as those expressions should be elided.
4063         DCHECK_EQ(!impl()->IsNull(name),
4064                   Token::IsAnyIdentifier(scanner()->current_token()));
4065         DCHECK_IMPLIES(impl()->IsNull(pattern), !impl()->IsNull(name));
4066         // The only times we have a non-null pattern are:
4067         //   1. This is a destructuring declaration (with no initializer, which
4068         //      is immediately an error),
4069         //   2. This is a declaration in a for in/of loop, or
4070         //   3. This is a let (which has an implicit undefined initializer)
4071         DCHECK_IMPLIES(
4072             !impl()->IsNull(pattern),
4073             !impl()->IsIdentifier(pattern) ||
4074                 (var_context == kForStatement && PeekInOrOf()) ||
4075                 parsing_result->descriptor.mode == VariableMode::kLet);
4076       }
4077 #endif
4078 
4079       if (var_context != kForStatement || !PeekInOrOf()) {
4080         // ES6 'const' and binding patterns require initializers.
4081         if (parsing_result->descriptor.mode == VariableMode::kConst ||
4082             impl()->IsNull(name)) {
4083           impl()->ReportMessageAt(
4084               Scanner::Location(decl_pos, end_position()),
4085               MessageTemplate::kDeclarationMissingInitializer,
4086               impl()->IsNull(name) ? "destructuring" : "const");
4087           return;
4088         }
4089         // 'let x' initializes 'x' to undefined.
4090         if (parsing_result->descriptor.mode == VariableMode::kLet) {
4091           value = factory()->NewUndefinedLiteral(position());
4092         }
4093       }
4094     }
4095 
4096     int initializer_position = end_position();
4097     auto declaration_end = target_scope->declarations()->end();
4098     for (; declaration_it != declaration_end; ++declaration_it) {
4099       declaration_it->var()->set_initializer_position(initializer_position);
4100     }
4101 
4102     // Patterns should be elided iff. they don't have an initializer.
4103     DCHECK_IMPLIES(impl()->IsNull(pattern),
4104                    impl()->IsNull(value) ||
4105                        (var_context == kForStatement && PeekInOrOf()));
4106 
4107     typename DeclarationParsingResult::Declaration decl(pattern, value);
4108     decl.value_beg_pos = value_beg_pos;
4109 
4110     parsing_result->declarations.push_back(decl);
4111   } while (Check(Token::COMMA));
4112 
4113   parsing_result->bindings_loc =
4114       Scanner::Location(bindings_start, end_position());
4115 }
4116 
4117 template <typename Impl>
4118 typename ParserBase<Impl>::StatementT
ParseFunctionDeclaration()4119 ParserBase<Impl>::ParseFunctionDeclaration() {
4120   Consume(Token::FUNCTION);
4121 
4122   int pos = position();
4123   ParseFunctionFlags flags = ParseFunctionFlag::kIsNormal;
4124   if (Check(Token::MUL)) {
4125     impl()->ReportMessageAt(
4126         scanner()->location(),
4127         MessageTemplate::kGeneratorInSingleStatementContext);
4128     return impl()->NullStatement();
4129   }
4130   return ParseHoistableDeclaration(pos, flags, nullptr, false);
4131 }
4132 
4133 template <typename Impl>
4134 typename ParserBase<Impl>::StatementT
ParseHoistableDeclaration(ZonePtrList<const AstRawString> * names,bool default_export)4135 ParserBase<Impl>::ParseHoistableDeclaration(
4136     ZonePtrList<const AstRawString>* names, bool default_export) {
4137   Consume(Token::FUNCTION);
4138 
4139   int pos = position();
4140   ParseFunctionFlags flags = ParseFunctionFlag::kIsNormal;
4141   if (Check(Token::MUL)) {
4142     flags |= ParseFunctionFlag::kIsGenerator;
4143   }
4144   return ParseHoistableDeclaration(pos, flags, names, default_export);
4145 }
4146 
4147 template <typename Impl>
4148 typename ParserBase<Impl>::StatementT
ParseHoistableDeclaration(int pos,ParseFunctionFlags flags,ZonePtrList<const AstRawString> * names,bool default_export)4149 ParserBase<Impl>::ParseHoistableDeclaration(
4150     int pos, ParseFunctionFlags flags, ZonePtrList<const AstRawString>* names,
4151     bool default_export) {
4152   CheckStackOverflow();
4153 
4154   // FunctionDeclaration ::
4155   //   'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
4156   //   'function' '(' FormalParameters ')' '{' FunctionBody '}'
4157   // GeneratorDeclaration ::
4158   //   'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
4159   //   'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
4160   //
4161   // The anonymous forms are allowed iff [default_export] is true.
4162   //
4163   // 'function' and '*' (if present) have been consumed by the caller.
4164 
4165   DCHECK_IMPLIES((flags & ParseFunctionFlag::kIsAsync) != 0,
4166                  (flags & ParseFunctionFlag::kIsGenerator) == 0);
4167 
4168   if ((flags & ParseFunctionFlag::kIsAsync) != 0 && Check(Token::MUL)) {
4169     // Async generator
4170     flags |= ParseFunctionFlag::kIsGenerator;
4171   }
4172 
4173   IdentifierT name;
4174   FunctionNameValidity name_validity;
4175   IdentifierT variable_name;
4176   if (peek() == Token::LPAREN) {
4177     if (default_export) {
4178       impl()->GetDefaultStrings(&name, &variable_name);
4179       name_validity = kSkipFunctionNameCheck;
4180     } else {
4181       ReportMessage(MessageTemplate::kMissingFunctionName);
4182       return impl()->NullStatement();
4183     }
4184   } else {
4185     bool is_strict_reserved = Token::IsStrictReservedWord(peek());
4186     name = ParseIdentifier();
4187     name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved
4188                                        : kFunctionNameValidityUnknown;
4189     variable_name = name;
4190   }
4191 
4192   FuncNameInferrerState fni_state(&fni_);
4193   impl()->PushEnclosingName(name);
4194 
4195   FunctionKind function_kind = FunctionKindFor(flags);
4196 
4197   FunctionLiteralT function = impl()->ParseFunctionLiteral(
4198       name, scanner()->location(), name_validity, function_kind, pos,
4199       FunctionSyntaxKind::kDeclaration, language_mode(), nullptr);
4200 
4201   // In ES6, a function behaves as a lexical binding, except in
4202   // a script scope, or the initial scope of eval or another function.
4203   VariableMode mode =
4204       (!scope()->is_declaration_scope() || scope()->is_module_scope())
4205           ? VariableMode::kLet
4206           : VariableMode::kVar;
4207   // Async functions don't undergo sloppy mode block scoped hoisting, and don't
4208   // allow duplicates in a block. Both are represented by the
4209   // sloppy_block_functions_. Don't add them to the map for async functions.
4210   // Generators are also supposed to be prohibited; currently doing this behind
4211   // a flag and UseCounting violations to assess web compatibility.
4212   VariableKind kind = is_sloppy(language_mode()) &&
4213                               !scope()->is_declaration_scope() &&
4214                               flags == ParseFunctionFlag::kIsNormal
4215                           ? SLOPPY_BLOCK_FUNCTION_VARIABLE
4216                           : NORMAL_VARIABLE;
4217 
4218   return impl()->DeclareFunction(variable_name, function, mode, kind, pos,
4219                                  end_position(), names);
4220 }
4221 
4222 template <typename Impl>
ParseClassDeclaration(ZonePtrList<const AstRawString> * names,bool default_export)4223 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration(
4224     ZonePtrList<const AstRawString>* names, bool default_export) {
4225   // ClassDeclaration ::
4226   //   'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
4227   //   'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
4228   //
4229   // The anonymous form is allowed iff [default_export] is true.
4230   //
4231   // 'class' is expected to be consumed by the caller.
4232   //
4233   // A ClassDeclaration
4234   //
4235   //   class C { ... }
4236   //
4237   // has the same semantics as:
4238   //
4239   //   let C = class C { ... };
4240   //
4241   // so rewrite it as such.
4242 
4243   int class_token_pos = position();
4244   IdentifierT name = impl()->NullIdentifier();
4245   bool is_strict_reserved = Token::IsStrictReservedWord(peek());
4246   IdentifierT variable_name = impl()->NullIdentifier();
4247   if (default_export && (peek() == Token::EXTENDS || peek() == Token::LBRACE)) {
4248     impl()->GetDefaultStrings(&name, &variable_name);
4249   } else {
4250     name = ParseIdentifier();
4251     variable_name = name;
4252   }
4253 
4254   ExpressionParsingScope no_expression_scope(impl());
4255   ExpressionT value = ParseClassLiteral(scope(), name, scanner()->location(),
4256                                         is_strict_reserved, class_token_pos);
4257   no_expression_scope.ValidateExpression();
4258   int end_pos = position();
4259   return impl()->DeclareClass(variable_name, value, names, class_token_pos,
4260                               end_pos);
4261 }
4262 
4263 // Language extension which is only enabled for source files loaded
4264 // through the API's extension mechanism.  A native function
4265 // declaration is resolved by looking up the function through a
4266 // callback provided by the extension.
4267 template <typename Impl>
4268 typename ParserBase<Impl>::StatementT
ParseNativeDeclaration()4269 ParserBase<Impl>::ParseNativeDeclaration() {
4270   function_state_->DisableOptimization(BailoutReason::kNativeFunctionLiteral);
4271 
4272   int pos = peek_position();
4273   Consume(Token::FUNCTION);
4274   // Allow "eval" or "arguments" for backward compatibility.
4275   IdentifierT name = ParseIdentifier();
4276   Expect(Token::LPAREN);
4277   if (peek() != Token::RPAREN) {
4278     do {
4279       ParseIdentifier();
4280     } while (Check(Token::COMMA));
4281   }
4282   Expect(Token::RPAREN);
4283   Expect(Token::SEMICOLON);
4284   return impl()->DeclareNative(name, pos);
4285 }
4286 
4287 template <typename Impl>
4288 typename ParserBase<Impl>::StatementT
ParseAsyncFunctionDeclaration(ZonePtrList<const AstRawString> * names,bool default_export)4289 ParserBase<Impl>::ParseAsyncFunctionDeclaration(
4290     ZonePtrList<const AstRawString>* names, bool default_export) {
4291   // AsyncFunctionDeclaration ::
4292   //   async [no LineTerminator here] function BindingIdentifier[Await]
4293   //       ( FormalParameters[Await] ) { AsyncFunctionBody }
4294   DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
4295   if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
4296     impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
4297   }
4298   int pos = position();
4299   DCHECK(!scanner()->HasLineTerminatorBeforeNext());
4300   Consume(Token::FUNCTION);
4301   ParseFunctionFlags flags = ParseFunctionFlag::kIsAsync;
4302   return ParseHoistableDeclaration(pos, flags, names, default_export);
4303 }
4304 
4305 template <typename Impl>
ParseFunctionBody(StatementListT * body,IdentifierT function_name,int pos,const FormalParametersT & parameters,FunctionKind kind,FunctionSyntaxKind function_syntax_kind,FunctionBodyType body_type)4306 void ParserBase<Impl>::ParseFunctionBody(
4307     StatementListT* body, IdentifierT function_name, int pos,
4308     const FormalParametersT& parameters, FunctionKind kind,
4309     FunctionSyntaxKind function_syntax_kind, FunctionBodyType body_type) {
4310   if (IsResumableFunction(kind)) impl()->PrepareGeneratorVariables();
4311 
4312   DeclarationScope* function_scope = parameters.scope;
4313   DeclarationScope* inner_scope = function_scope;
4314 
4315   // Building the parameter initialization block declares the parameters.
4316   // TODO(verwaest): Rely on ArrowHeadParsingScope instead.
4317   if (V8_UNLIKELY(!parameters.is_simple)) {
4318     if (has_error()) return;
4319     BlockT init_block = impl()->BuildParameterInitializationBlock(parameters);
4320     if (IsAsyncFunction(kind) && !IsAsyncGeneratorFunction(kind)) {
4321       init_block = impl()->BuildRejectPromiseOnException(init_block);
4322     }
4323     body->Add(init_block);
4324     if (has_error()) return;
4325 
4326     inner_scope = NewVarblockScope();
4327     inner_scope->set_start_position(scanner()->location().beg_pos);
4328   }
4329 
4330   StatementListT inner_body(pointer_buffer());
4331 
4332   {
4333     BlockState block_state(&scope_, inner_scope);
4334 
4335     if (body_type == FunctionBodyType::kExpression) {
4336       ExpressionT expression = ParseAssignmentExpression();
4337 
4338       if (IsAsyncFunction(kind)) {
4339         BlockT block = factory()->NewBlock(1, true);
4340         impl()->RewriteAsyncFunctionBody(&inner_body, block, expression);
4341       } else {
4342         inner_body.Add(
4343             BuildReturnStatement(expression, expression->position()));
4344       }
4345     } else {
4346       DCHECK(accept_IN_);
4347       DCHECK_EQ(FunctionBodyType::kBlock, body_type);
4348       // If we are parsing the source as if it is wrapped in a function, the
4349       // source ends without a closing brace.
4350       Token::Value closing_token =
4351           function_syntax_kind == FunctionSyntaxKind::kWrapped ? Token::EOS
4352                                                                : Token::RBRACE;
4353 
4354       if (IsAsyncGeneratorFunction(kind)) {
4355         impl()->ParseAndRewriteAsyncGeneratorFunctionBody(pos, kind,
4356                                                           &inner_body);
4357       } else if (IsGeneratorFunction(kind)) {
4358         impl()->ParseAndRewriteGeneratorFunctionBody(pos, kind, &inner_body);
4359       } else if (IsAsyncFunction(kind)) {
4360         ParseAsyncFunctionBody(inner_scope, &inner_body);
4361       } else {
4362         ParseStatementList(&inner_body, closing_token);
4363       }
4364 
4365       if (IsDerivedConstructor(kind)) {
4366         ExpressionParsingScope expression_scope(impl());
4367         inner_body.Add(factory()->NewReturnStatement(impl()->ThisExpression(),
4368                                                      kNoSourcePosition));
4369         expression_scope.ValidateExpression();
4370       }
4371       Expect(closing_token);
4372     }
4373   }
4374 
4375   scope()->set_end_position(end_position());
4376 
4377   bool allow_duplicate_parameters = false;
4378 
4379   CheckConflictingVarDeclarations(inner_scope);
4380 
4381   if (V8_LIKELY(parameters.is_simple)) {
4382     DCHECK_EQ(inner_scope, function_scope);
4383     if (is_sloppy(function_scope->language_mode())) {
4384       impl()->InsertSloppyBlockFunctionVarBindings(function_scope);
4385     }
4386     allow_duplicate_parameters =
4387         is_sloppy(function_scope->language_mode()) && !IsConciseMethod(kind);
4388   } else {
4389     DCHECK_NOT_NULL(inner_scope);
4390     DCHECK_EQ(function_scope, scope());
4391     DCHECK_EQ(function_scope, inner_scope->outer_scope());
4392     impl()->SetLanguageMode(function_scope, inner_scope->language_mode());
4393 
4394     if (is_sloppy(inner_scope->language_mode())) {
4395       impl()->InsertSloppyBlockFunctionVarBindings(inner_scope);
4396     }
4397 
4398     inner_scope->set_end_position(end_position());
4399     if (inner_scope->FinalizeBlockScope() != nullptr) {
4400       BlockT inner_block = factory()->NewBlock(true, inner_body);
4401       inner_body.Rewind();
4402       inner_body.Add(inner_block);
4403       inner_block->set_scope(inner_scope);
4404       impl()->RecordBlockSourceRange(inner_block, scope()->end_position());
4405       if (!impl()->HasCheckedSyntax()) {
4406         const AstRawString* conflict = inner_scope->FindVariableDeclaredIn(
4407             function_scope, VariableMode::kLastLexicalVariableMode);
4408         if (conflict != nullptr) {
4409           impl()->ReportVarRedeclarationIn(conflict, inner_scope);
4410         }
4411       }
4412 
4413       // According to ES#sec-functiondeclarationinstantiation step 27,28
4414       // when hasParameterExpressions is true, we need bind var declared
4415       // arguments to "arguments exotic object", so we here first declare
4416       // "arguments exotic object", then var declared arguments will be
4417       // initialized with "arguments exotic object"
4418       if (!IsArrowFunction(kind)) {
4419         function_scope->DeclareArguments(ast_value_factory());
4420       }
4421 
4422       impl()->InsertShadowingVarBindingInitializers(inner_block);
4423     }
4424   }
4425 
4426   ValidateFormalParameters(language_mode(), parameters,
4427                            allow_duplicate_parameters);
4428 
4429   if (!IsArrowFunction(kind)) {
4430     function_scope->DeclareArguments(ast_value_factory());
4431   }
4432 
4433   impl()->DeclareFunctionNameVar(function_name, function_syntax_kind,
4434                                  function_scope);
4435 
4436   inner_body.MergeInto(body);
4437 }
4438 
4439 template <typename Impl>
CheckArityRestrictions(int param_count,FunctionKind function_kind,bool has_rest,int formals_start_pos,int formals_end_pos)4440 void ParserBase<Impl>::CheckArityRestrictions(int param_count,
4441                                               FunctionKind function_kind,
4442                                               bool has_rest,
4443                                               int formals_start_pos,
4444                                               int formals_end_pos) {
4445   if (impl()->HasCheckedSyntax()) return;
4446   if (IsGetterFunction(function_kind)) {
4447     if (param_count != 0) {
4448       impl()->ReportMessageAt(
4449           Scanner::Location(formals_start_pos, formals_end_pos),
4450           MessageTemplate::kBadGetterArity);
4451     }
4452   } else if (IsSetterFunction(function_kind)) {
4453     if (param_count != 1) {
4454       impl()->ReportMessageAt(
4455           Scanner::Location(formals_start_pos, formals_end_pos),
4456           MessageTemplate::kBadSetterArity);
4457     }
4458     if (has_rest) {
4459       impl()->ReportMessageAt(
4460           Scanner::Location(formals_start_pos, formals_end_pos),
4461           MessageTemplate::kBadSetterRestParameter);
4462     }
4463   }
4464 }
4465 
4466 template <typename Impl>
IsNextLetKeyword()4467 bool ParserBase<Impl>::IsNextLetKeyword() {
4468   DCHECK_EQ(Token::LET, peek());
4469   Token::Value next_next = PeekAhead();
4470   switch (next_next) {
4471     case Token::LBRACE:
4472     case Token::LBRACK:
4473     case Token::IDENTIFIER:
4474     case Token::STATIC:
4475     case Token::LET:  // `let let;` is disallowed by static semantics, but the
4476                       // token must be first interpreted as a keyword in order
4477                       // for those semantics to apply. This ensures that ASI is
4478                       // not honored when a LineTerminator separates the
4479                       // tokens.
4480     case Token::YIELD:
4481     case Token::AWAIT:
4482     case Token::GET:
4483     case Token::SET:
4484     case Token::ASYNC:
4485       return true;
4486     case Token::FUTURE_STRICT_RESERVED_WORD:
4487     case Token::ESCAPED_STRICT_RESERVED_WORD:
4488       // The early error rule for future reserved keywords
4489       // (ES#sec-identifiers-static-semantics-early-errors) uses the static
4490       // semantics StringValue of IdentifierName, which normalizes escape
4491       // sequences. So, both escaped and unescaped future reserved keywords are
4492       // allowed as identifiers in sloppy mode.
4493       return is_sloppy(language_mode());
4494     default:
4495       return false;
4496   }
4497 }
4498 
4499 template <typename Impl>
4500 typename ParserBase<Impl>::ExpressionT
ParseArrowFunctionLiteral(const FormalParametersT & formal_parameters)4501 ParserBase<Impl>::ParseArrowFunctionLiteral(
4502     const FormalParametersT& formal_parameters) {
4503   RCS_SCOPE(runtime_call_stats_,
4504             Impl::IsPreParser()
4505                 ? RuntimeCallCounterId::kPreParseArrowFunctionLiteral
4506                 : RuntimeCallCounterId::kParseArrowFunctionLiteral,
4507             RuntimeCallStats::kThreadSpecific);
4508   base::ElapsedTimer timer;
4509   if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
4510 
4511   DCHECK_IMPLIES(!has_error(), peek() == Token::ARROW);
4512   if (!impl()->HasCheckedSyntax() && scanner_->HasLineTerminatorBeforeNext()) {
4513     // ASI inserts `;` after arrow parameters if a line terminator is found.
4514     // `=> ...` is never a valid expression, so report as syntax error.
4515     // If next token is not `=>`, it's a syntax error anyways.
4516     impl()->ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
4517     return impl()->FailureExpression();
4518   }
4519 
4520   int expected_property_count = 0;
4521   int suspend_count = 0;
4522   int function_literal_id = GetNextFunctionLiteralId();
4523 
4524   FunctionKind kind = formal_parameters.scope->function_kind();
4525   FunctionLiteral::EagerCompileHint eager_compile_hint =
4526       default_eager_compile_hint_;
4527   bool can_preparse = impl()->parse_lazily() &&
4528                       eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
4529   // TODO(marja): consider lazy-parsing inner arrow functions too. is_this
4530   // handling in Scope::ResolveVariable needs to change.
4531   bool is_lazy_top_level_function =
4532       can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables();
4533   bool has_braces = true;
4534   ProducedPreparseData* produced_preparse_data = nullptr;
4535   StatementListT body(pointer_buffer());
4536   {
4537     FunctionState function_state(&function_state_, &scope_,
4538                                  formal_parameters.scope);
4539 
4540     Consume(Token::ARROW);
4541 
4542     if (peek() == Token::LBRACE) {
4543       // Multiple statement body
4544       DCHECK_EQ(scope(), formal_parameters.scope);
4545 
4546       if (is_lazy_top_level_function) {
4547         // FIXME(marja): Arrow function parameters will be parsed even if the
4548         // body is preparsed; move relevant parts of parameter handling to
4549         // simulate consistent parameter handling.
4550 
4551         // Building the parameter initialization block declares the parameters.
4552         // TODO(verwaest): Rely on ArrowHeadParsingScope instead.
4553         if (!formal_parameters.is_simple) {
4554           impl()->BuildParameterInitializationBlock(formal_parameters);
4555           if (has_error()) return impl()->FailureExpression();
4556         }
4557 
4558         // For arrow functions, we don't need to retrieve data about function
4559         // parameters.
4560         int dummy_num_parameters = -1;
4561         int dummy_function_length = -1;
4562         DCHECK(IsArrowFunction(kind));
4563         bool did_preparse_successfully = impl()->SkipFunction(
4564             nullptr, kind, FunctionSyntaxKind::kAnonymousExpression,
4565             formal_parameters.scope, &dummy_num_parameters,
4566             &dummy_function_length, &produced_preparse_data);
4567 
4568         DCHECK_NULL(produced_preparse_data);
4569 
4570         if (did_preparse_successfully) {
4571           // Validate parameter names. We can do this only after preparsing the
4572           // function, since the function can declare itself strict.
4573           ValidateFormalParameters(language_mode(), formal_parameters, false);
4574         } else {
4575           // In case we did not sucessfully preparse the function because of an
4576           // unidentified error we do a full reparse to return the error.
4577           // Parse again in the outer scope, since the language mode may change.
4578           BlockState block_state(&scope_, scope()->outer_scope());
4579           ExpressionT expression = ParseConditionalExpression();
4580           // Reparsing the head may have caused a stack overflow.
4581           if (has_error()) return impl()->FailureExpression();
4582 
4583           DeclarationScope* function_scope = next_arrow_function_info_.scope;
4584           FunctionState inner_function_state(&function_state_, &scope_,
4585                                              function_scope);
4586           Scanner::Location loc(function_scope->start_position(),
4587                                 end_position());
4588           FormalParametersT parameters(function_scope);
4589           parameters.is_simple = function_scope->has_simple_parameters();
4590           impl()->DeclareArrowFunctionFormalParameters(&parameters, expression,
4591                                                        loc);
4592           next_arrow_function_info_.Reset();
4593 
4594           Consume(Token::ARROW);
4595           Consume(Token::LBRACE);
4596 
4597           AcceptINScope scope(this, true);
4598           FunctionParsingScope body_parsing_scope(impl());
4599           ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
4600                             parameters, kind,
4601                             FunctionSyntaxKind::kAnonymousExpression,
4602                             FunctionBodyType::kBlock);
4603           CHECK(has_error());
4604           return impl()->FailureExpression();
4605         }
4606       } else {
4607         Consume(Token::LBRACE);
4608         AcceptINScope scope(this, true);
4609         FunctionParsingScope body_parsing_scope(impl());
4610         ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
4611                           formal_parameters, kind,
4612                           FunctionSyntaxKind::kAnonymousExpression,
4613                           FunctionBodyType::kBlock);
4614         expected_property_count = function_state.expected_property_count();
4615       }
4616     } else {
4617       // Single-expression body
4618       has_braces = false;
4619       FunctionParsingScope body_parsing_scope(impl());
4620       ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
4621                         formal_parameters, kind,
4622                         FunctionSyntaxKind::kAnonymousExpression,
4623                         FunctionBodyType::kExpression);
4624       expected_property_count = function_state.expected_property_count();
4625     }
4626 
4627     formal_parameters.scope->set_end_position(end_position());
4628 
4629     // Validate strict mode.
4630     if (is_strict(language_mode())) {
4631       CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
4632                               end_position());
4633     }
4634     suspend_count = function_state.suspend_count();
4635   }
4636 
4637   FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
4638       impl()->EmptyIdentifierString(), formal_parameters.scope, body,
4639       expected_property_count, formal_parameters.num_parameters(),
4640       formal_parameters.function_length,
4641       FunctionLiteral::kNoDuplicateParameters,
4642       FunctionSyntaxKind::kAnonymousExpression, eager_compile_hint,
4643       formal_parameters.scope->start_position(), has_braces,
4644       function_literal_id, produced_preparse_data);
4645 
4646   function_literal->set_suspend_count(suspend_count);
4647   function_literal->set_function_token_position(
4648       formal_parameters.scope->start_position());
4649 
4650   impl()->RecordFunctionLiteralSourceRange(function_literal);
4651   impl()->AddFunctionForNameInference(function_literal);
4652 
4653   if (V8_UNLIKELY((FLAG_log_function_events))) {
4654     Scope* scope = formal_parameters.scope;
4655     double ms = timer.Elapsed().InMillisecondsF();
4656     const char* event_name =
4657         is_lazy_top_level_function ? "preparse-no-resolution" : "parse";
4658     const char* name = "arrow function";
4659     logger_->FunctionEvent(event_name, flags().script_id(), ms,
4660                            scope->start_position(), scope->end_position(), name,
4661                            strlen(name));
4662   }
4663 
4664   return function_literal;
4665 }
4666 
4667 template <typename Impl>
ParseClassExpression(Scope * outer_scope)4668 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassExpression(
4669     Scope* outer_scope) {
4670   Consume(Token::CLASS);
4671   int class_token_pos = position();
4672   IdentifierT name = impl()->NullIdentifier();
4673   bool is_strict_reserved_name = false;
4674   Scanner::Location class_name_location = Scanner::Location::invalid();
4675   if (peek_any_identifier()) {
4676     name = ParseAndClassifyIdentifier(Next());
4677     class_name_location = scanner()->location();
4678     is_strict_reserved_name =
4679         Token::IsStrictReservedWord(scanner()->current_token());
4680   }
4681   return ParseClassLiteral(outer_scope, name, class_name_location,
4682                            is_strict_reserved_name, class_token_pos);
4683 }
4684 
4685 template <typename Impl>
ParseClassLiteral(Scope * outer_scope,IdentifierT name,Scanner::Location class_name_location,bool name_is_strict_reserved,int class_token_pos)4686 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
4687     Scope* outer_scope, IdentifierT name, Scanner::Location class_name_location,
4688     bool name_is_strict_reserved, int class_token_pos) {
4689   bool is_anonymous = impl()->IsNull(name);
4690 
4691   // All parts of a ClassDeclaration and ClassExpression are strict code.
4692   if (!impl()->HasCheckedSyntax() && !is_anonymous) {
4693     if (name_is_strict_reserved) {
4694       impl()->ReportMessageAt(class_name_location,
4695                               MessageTemplate::kUnexpectedStrictReserved);
4696       return impl()->FailureExpression();
4697     }
4698     if (impl()->IsEvalOrArguments(name)) {
4699       impl()->ReportMessageAt(class_name_location,
4700                               MessageTemplate::kStrictEvalArguments);
4701       return impl()->FailureExpression();
4702     }
4703   }
4704 
4705   ClassScope* class_scope = NewClassScope(outer_scope, is_anonymous);
4706   BlockState block_state(&scope_, class_scope);
4707   RaiseLanguageMode(LanguageMode::kStrict);
4708 
4709   BlockState object_literal_scope_state(&object_literal_scope_, nullptr);
4710 
4711   ClassInfo class_info(this);
4712   class_info.is_anonymous = is_anonymous;
4713 
4714   scope()->set_start_position(class_token_pos);
4715   if (Check(Token::EXTENDS)) {
4716     ClassScope::HeritageParsingScope heritage(class_scope);
4717     FuncNameInferrerState fni_state(&fni_);
4718     ExpressionParsingScope scope(impl());
4719     class_info.extends = ParseLeftHandSideExpression();
4720     scope.ValidateExpression();
4721   }
4722 
4723   Expect(Token::LBRACE);
4724 
4725   const bool has_extends = !impl()->IsNull(class_info.extends);
4726   while (peek() != Token::RBRACE) {
4727     if (Check(Token::SEMICOLON)) continue;
4728 
4729     // Either we're parsing a `static { }` initialization block or a property.
4730     if (FLAG_harmony_class_static_blocks && peek() == Token::STATIC &&
4731         PeekAhead() == Token::LBRACE) {
4732       BlockT static_block = ParseClassStaticBlock(&class_info);
4733       impl()->AddClassStaticBlock(static_block, &class_info);
4734       continue;
4735     }
4736 
4737     FuncNameInferrerState fni_state(&fni_);
4738     // If we haven't seen the constructor yet, it potentially is the next
4739     // property.
4740     bool is_constructor = !class_info.has_seen_constructor;
4741     ParsePropertyInfo prop_info(this);
4742     prop_info.position = PropertyPosition::kClassLiteral;
4743 
4744     ClassLiteralPropertyT property =
4745         ParseClassPropertyDefinition(&class_info, &prop_info, has_extends);
4746 
4747     if (has_error()) return impl()->FailureExpression();
4748 
4749     ClassLiteralProperty::Kind property_kind =
4750         ClassPropertyKindFor(prop_info.kind);
4751     if (!class_info.has_static_computed_names && prop_info.is_static &&
4752         prop_info.is_computed_name) {
4753       class_info.has_static_computed_names = true;
4754     }
4755     is_constructor &= class_info.has_seen_constructor;
4756 
4757     bool is_field = property_kind == ClassLiteralProperty::FIELD;
4758 
4759     if (V8_UNLIKELY(prop_info.is_private)) {
4760       DCHECK(!is_constructor);
4761       class_info.requires_brand |= (!is_field && !prop_info.is_static);
4762       bool is_method = property_kind == ClassLiteralProperty::METHOD;
4763       class_info.has_private_methods |= is_method;
4764       class_info.has_static_private_methods |= is_method && prop_info.is_static;
4765       impl()->DeclarePrivateClassMember(class_scope, prop_info.name, property,
4766                                         property_kind, prop_info.is_static,
4767                                         &class_info);
4768       impl()->InferFunctionName();
4769       continue;
4770     }
4771 
4772     if (V8_UNLIKELY(is_field)) {
4773       DCHECK(!prop_info.is_private);
4774       if (prop_info.is_computed_name) {
4775         class_info.computed_field_count++;
4776       }
4777       impl()->DeclarePublicClassField(class_scope, property,
4778                                       prop_info.is_static,
4779                                       prop_info.is_computed_name, &class_info);
4780       impl()->InferFunctionName();
4781       continue;
4782     }
4783 
4784     impl()->DeclarePublicClassMethod(name, property, is_constructor,
4785                                      &class_info);
4786     impl()->InferFunctionName();
4787   }
4788 
4789   Expect(Token::RBRACE);
4790   int end_pos = end_position();
4791   class_scope->set_end_position(end_pos);
4792   if (class_info.instance_members_scope != nullptr) {
4793     // Use the positions of the class body for the instance initializer
4794     // function so that we can reparse it later.
4795     class_info.instance_members_scope->set_start_position(class_token_pos);
4796     class_info.instance_members_scope->set_end_position(end_pos);
4797   }
4798 
4799   VariableProxy* unresolvable = class_scope->ResolvePrivateNamesPartially();
4800   if (unresolvable != nullptr) {
4801     impl()->ReportMessageAt(Scanner::Location(unresolvable->position(),
4802                                               unresolvable->position() + 1),
4803                             MessageTemplate::kInvalidPrivateFieldResolution,
4804                             unresolvable->raw_name());
4805     return impl()->FailureExpression();
4806   }
4807 
4808   if (class_info.requires_brand) {
4809     class_scope->DeclareBrandVariable(
4810         ast_value_factory(), IsStaticFlag::kNotStatic, kNoSourcePosition);
4811   }
4812 
4813   if (class_scope->needs_home_object()) {
4814     class_info.home_object_variable =
4815         class_scope->DeclareHomeObjectVariable(ast_value_factory());
4816     class_info.static_home_object_variable =
4817         class_scope->DeclareStaticHomeObjectVariable(ast_value_factory());
4818   }
4819 
4820   bool should_save_class_variable_index =
4821       class_scope->should_save_class_variable_index();
4822   if (!is_anonymous || should_save_class_variable_index) {
4823     impl()->DeclareClassVariable(class_scope, name, &class_info,
4824                                  class_token_pos);
4825     if (should_save_class_variable_index) {
4826       class_scope->class_variable()->set_is_used();
4827       class_scope->class_variable()->ForceContextAllocation();
4828     }
4829   }
4830 
4831   return impl()->RewriteClassLiteral(class_scope, name, &class_info,
4832                                      class_token_pos, end_pos);
4833 }
4834 
4835 template <typename Impl>
ParseAsyncFunctionBody(Scope * scope,StatementListT * body)4836 void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope,
4837                                               StatementListT* body) {
4838   BlockT block = impl()->NullBlock();
4839   {
4840     StatementListT statements(pointer_buffer());
4841     ParseStatementList(&statements, Token::RBRACE);
4842     block = factory()->NewBlock(true, statements);
4843   }
4844   impl()->RewriteAsyncFunctionBody(
4845       body, block, factory()->NewUndefinedLiteral(kNoSourcePosition));
4846   scope->set_end_position(end_position());
4847 }
4848 
4849 template <typename Impl>
4850 typename ParserBase<Impl>::ExpressionT
ParseAsyncFunctionLiteral()4851 ParserBase<Impl>::ParseAsyncFunctionLiteral() {
4852   // AsyncFunctionLiteral ::
4853   //   async [no LineTerminator here] function ( FormalParameters[Await] )
4854   //       { AsyncFunctionBody }
4855   //
4856   //   async [no LineTerminator here] function BindingIdentifier[Await]
4857   //       ( FormalParameters[Await] ) { AsyncFunctionBody }
4858   DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
4859   if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
4860     impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
4861   }
4862   int pos = position();
4863   Consume(Token::FUNCTION);
4864   IdentifierT name = impl()->NullIdentifier();
4865   FunctionSyntaxKind syntax_kind = FunctionSyntaxKind::kAnonymousExpression;
4866 
4867   ParseFunctionFlags flags = ParseFunctionFlag::kIsAsync;
4868   if (Check(Token::MUL)) flags |= ParseFunctionFlag::kIsGenerator;
4869   const FunctionKind kind = FunctionKindFor(flags);
4870   bool is_strict_reserved = Token::IsStrictReservedWord(peek());
4871 
4872   if (impl()->ParsingDynamicFunctionDeclaration()) {
4873     // We don't want dynamic functions to actually declare their name
4874     // "anonymous". We just want that name in the toString().
4875 
4876     // Consuming token we did not peek yet, which could lead to a ILLEGAL token
4877     // in the case of a stackoverflow.
4878     Consume(Token::IDENTIFIER);
4879     DCHECK_IMPLIES(!has_error(),
4880                    scanner()->CurrentSymbol(ast_value_factory()) ==
4881                        ast_value_factory()->anonymous_string());
4882   } else if (peek_any_identifier()) {
4883     syntax_kind = FunctionSyntaxKind::kNamedExpression;
4884     name = ParseIdentifier(kind);
4885   }
4886   FunctionLiteralT result = impl()->ParseFunctionLiteral(
4887       name, scanner()->location(),
4888       is_strict_reserved ? kFunctionNameIsStrictReserved
4889                          : kFunctionNameValidityUnknown,
4890       kind, pos, syntax_kind, language_mode(), nullptr);
4891   if (impl()->IsNull(result)) return impl()->FailureExpression();
4892   return result;
4893 }
4894 
4895 template <typename Impl>
ParseTemplateLiteral(ExpressionT tag,int start,bool tagged)4896 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
4897     ExpressionT tag, int start, bool tagged) {
4898   // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
4899   // text followed by a substitution expression), finalized by a single
4900   // TEMPLATE_TAIL.
4901   //
4902   // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
4903   // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
4904   // NoSubstitutionTemplate.
4905   //
4906   // When parsing a TemplateLiteral, we must have scanned either an initial
4907   // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
4908   DCHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
4909 
4910   if (tagged) {
4911     // TaggedTemplate expressions prevent the eval compilation cache from being
4912     // used. This flag is only used if an eval is being parsed.
4913     set_allow_eval_cache(false);
4914   }
4915 
4916   bool forbid_illegal_escapes = !tagged;
4917 
4918   // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
4919   // In this case we may simply consume the token and build a template with a
4920   // single TEMPLATE_SPAN and no expressions.
4921   if (peek() == Token::TEMPLATE_TAIL) {
4922     Consume(Token::TEMPLATE_TAIL);
4923     int pos = position();
4924     typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
4925     bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes);
4926     impl()->AddTemplateSpan(&ts, is_valid, true);
4927     return impl()->CloseTemplateLiteral(&ts, start, tag);
4928   }
4929 
4930   Consume(Token::TEMPLATE_SPAN);
4931   int pos = position();
4932   typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
4933   bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes);
4934   impl()->AddTemplateSpan(&ts, is_valid, false);
4935   Token::Value next;
4936 
4937   // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
4938   // and repeat if the following token is a TEMPLATE_SPAN as well (in this
4939   // case, representing a TemplateMiddle).
4940 
4941   do {
4942     next = peek();
4943 
4944     int expr_pos = peek_position();
4945     AcceptINScope scope(this, true);
4946     ExpressionT expression = ParseExpressionCoverGrammar();
4947     impl()->AddTemplateExpression(&ts, expression);
4948 
4949     if (peek() != Token::RBRACE) {
4950       impl()->ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
4951                               MessageTemplate::kUnterminatedTemplateExpr);
4952       return impl()->FailureExpression();
4953     }
4954 
4955     // If we didn't die parsing that expression, our next token should be a
4956     // TEMPLATE_SPAN or TEMPLATE_TAIL.
4957     next = scanner()->ScanTemplateContinuation();
4958     Next();
4959     pos = position();
4960 
4961     is_valid = CheckTemplateEscapes(forbid_illegal_escapes);
4962     impl()->AddTemplateSpan(&ts, is_valid, next == Token::TEMPLATE_TAIL);
4963   } while (next == Token::TEMPLATE_SPAN);
4964 
4965   DCHECK_IMPLIES(!has_error(), next == Token::TEMPLATE_TAIL);
4966   // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
4967   return impl()->CloseTemplateLiteral(&ts, start, tag);
4968 }
4969 
4970 template <typename Impl>
4971 typename ParserBase<Impl>::ExpressionT
RewriteInvalidReferenceExpression(ExpressionT expression,int beg_pos,int end_pos,MessageTemplate message,bool early_error)4972 ParserBase<Impl>::RewriteInvalidReferenceExpression(ExpressionT expression,
4973                                                     int beg_pos, int end_pos,
4974                                                     MessageTemplate message,
4975                                                     bool early_error) {
4976   DCHECK(!IsValidReferenceExpression(expression));
4977   if (impl()->IsIdentifier(expression)) {
4978     DCHECK(is_strict(language_mode()));
4979     DCHECK(impl()->IsEvalOrArguments(impl()->AsIdentifier(expression)));
4980 
4981     ReportMessageAt(Scanner::Location(beg_pos, end_pos),
4982                     MessageTemplate::kStrictEvalArguments);
4983     return impl()->FailureExpression();
4984   }
4985   if (expression->IsCall() && !expression->AsCall()->is_tagged_template() &&
4986       !early_error) {
4987     expression_scope()->RecordPatternError(
4988         Scanner::Location(beg_pos, end_pos),
4989         MessageTemplate::kInvalidDestructuringTarget);
4990     // If it is a call, make it a runtime error for legacy web compatibility.
4991     // Bug: https://bugs.chromium.org/p/v8/issues/detail?id=4480
4992     // Rewrite `expr' to `expr[throw ReferenceError]'.
4993     impl()->CountUsage(
4994         is_strict(language_mode())
4995             ? v8::Isolate::kAssigmentExpressionLHSIsCallInStrict
4996             : v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy);
4997     ExpressionT error = impl()->NewThrowReferenceError(message, beg_pos);
4998     return factory()->NewProperty(expression, error, beg_pos);
4999   }
5000   // Tagged templates and other modern language features (which pass early_error
5001   // = true) are exempt from the web compatibility hack. Throw a regular early
5002   // error.
5003   ReportMessageAt(Scanner::Location(beg_pos, end_pos), message);
5004   return impl()->FailureExpression();
5005 }
5006 
5007 template <typename Impl>
ClassifyParameter(IdentifierT parameter,int begin,int end)5008 void ParserBase<Impl>::ClassifyParameter(IdentifierT parameter, int begin,
5009                                          int end) {
5010   if (impl()->IsEvalOrArguments(parameter)) {
5011     expression_scope()->RecordStrictModeParameterError(
5012         Scanner::Location(begin, end), MessageTemplate::kStrictEvalArguments);
5013   }
5014 }
5015 
5016 template <typename Impl>
ClassifyArrowParameter(AccumulationScope * accumulation_scope,int position,ExpressionT parameter)5017 void ParserBase<Impl>::ClassifyArrowParameter(
5018     AccumulationScope* accumulation_scope, int position,
5019     ExpressionT parameter) {
5020   accumulation_scope->Accumulate();
5021   if (parameter->is_parenthesized() ||
5022       !(impl()->IsIdentifier(parameter) || parameter->IsPattern() ||
5023         parameter->IsAssignment())) {
5024     expression_scope()->RecordDeclarationError(
5025         Scanner::Location(position, end_position()),
5026         MessageTemplate::kInvalidDestructuringTarget);
5027   } else if (impl()->IsIdentifier(parameter)) {
5028     ClassifyParameter(impl()->AsIdentifier(parameter), position,
5029                       end_position());
5030   } else {
5031     expression_scope()->RecordNonSimpleParameter();
5032   }
5033 }
5034 
5035 template <typename Impl>
IsValidReferenceExpression(ExpressionT expression)5036 bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) {
5037   return IsAssignableIdentifier(expression) || expression->IsProperty();
5038 }
5039 
5040 template <typename Impl>
5041 typename ParserBase<Impl>::ExpressionT
ParsePossibleDestructuringSubPattern(AccumulationScope * scope)5042 ParserBase<Impl>::ParsePossibleDestructuringSubPattern(
5043     AccumulationScope* scope) {
5044   if (scope) scope->Accumulate();
5045   int begin = peek_position();
5046   ExpressionT result = ParseAssignmentExpressionCoverGrammar();
5047 
5048   if (IsValidReferenceExpression(result)) {
5049     // Parenthesized identifiers and property references are allowed as part of
5050     // a larger assignment pattern, even though parenthesized patterns
5051     // themselves are not allowed, e.g., "[(x)] = []". Only accumulate
5052     // assignment pattern errors if the parsed expression is more complex.
5053     if (impl()->IsIdentifier(result)) {
5054       if (result->is_parenthesized()) {
5055         expression_scope()->RecordDeclarationError(
5056             Scanner::Location(begin, end_position()),
5057             MessageTemplate::kInvalidDestructuringTarget);
5058       }
5059       IdentifierT identifier = impl()->AsIdentifier(result);
5060       ClassifyParameter(identifier, begin, end_position());
5061     } else {
5062       DCHECK(result->IsProperty());
5063       expression_scope()->RecordDeclarationError(
5064           Scanner::Location(begin, end_position()),
5065           MessageTemplate::kInvalidPropertyBindingPattern);
5066       if (scope != nullptr) scope->ValidateExpression();
5067     }
5068   } else if (result->is_parenthesized() ||
5069              (!result->IsPattern() && !result->IsAssignment())) {
5070     expression_scope()->RecordPatternError(
5071         Scanner::Location(begin, end_position()),
5072         MessageTemplate::kInvalidDestructuringTarget);
5073   }
5074 
5075   return result;
5076 }
5077 
5078 template <typename Impl>
ParseV8Intrinsic()5079 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseV8Intrinsic() {
5080   // CallRuntime ::
5081   //   '%' Identifier Arguments
5082 
5083   int pos = peek_position();
5084   Consume(Token::MOD);
5085   // Allow "eval" or "arguments" for backward compatibility.
5086   IdentifierT name = ParseIdentifier();
5087   if (peek() != Token::LPAREN) {
5088     impl()->ReportUnexpectedToken(peek());
5089     return impl()->FailureExpression();
5090   }
5091   bool has_spread;
5092   ExpressionListT args(pointer_buffer());
5093   ParseArguments(&args, &has_spread);
5094 
5095   if (has_spread) {
5096     ReportMessageAt(Scanner::Location(pos, position()),
5097                     MessageTemplate::kIntrinsicWithSpread);
5098     return impl()->FailureExpression();
5099   }
5100 
5101   return impl()->NewV8Intrinsic(name, args, pos);
5102 }
5103 
5104 template <typename Impl>
ParseStatementList(StatementListT * body,Token::Value end_token)5105 void ParserBase<Impl>::ParseStatementList(StatementListT* body,
5106                                           Token::Value end_token) {
5107   // StatementList ::
5108   //   (StatementListItem)* <end_token>
5109   DCHECK_NOT_NULL(body);
5110 
5111   while (peek() == Token::STRING) {
5112     bool use_strict = false;
5113 #if V8_ENABLE_WEBASSEMBLY
5114     bool use_asm = false;
5115 #endif  // V8_ENABLE_WEBASSEMBLY
5116 
5117     Scanner::Location token_loc = scanner()->peek_location();
5118 
5119     if (scanner()->NextLiteralExactlyEquals("use strict")) {
5120       use_strict = true;
5121 #if V8_ENABLE_WEBASSEMBLY
5122     } else if (scanner()->NextLiteralExactlyEquals("use asm")) {
5123       use_asm = true;
5124 #endif  // V8_ENABLE_WEBASSEMBLY
5125     }
5126 
5127     StatementT stat = ParseStatementListItem();
5128     if (impl()->IsNull(stat)) return;
5129 
5130     body->Add(stat);
5131 
5132     if (!impl()->IsStringLiteral(stat)) break;
5133 
5134     if (use_strict) {
5135       // Directive "use strict" (ES5 14.1).
5136       RaiseLanguageMode(LanguageMode::kStrict);
5137       if (!scope()->HasSimpleParameters()) {
5138         // TC39 deemed "use strict" directives to be an error when occurring
5139         // in the body of a function with non-simple parameter list, on
5140         // 29/7/2015. https://goo.gl/ueA7Ln
5141         impl()->ReportMessageAt(token_loc,
5142                                 MessageTemplate::kIllegalLanguageModeDirective,
5143                                 "use strict");
5144         return;
5145       }
5146 #if V8_ENABLE_WEBASSEMBLY
5147     } else if (use_asm) {
5148       // Directive "use asm".
5149       impl()->SetAsmModule();
5150 #endif  // V8_ENABLE_WEBASSEMBLY
5151     } else {
5152       // Possibly an unknown directive.
5153       // Should not change mode, but will increment usage counters
5154       // as appropriate. Ditto usages below.
5155       RaiseLanguageMode(LanguageMode::kSloppy);
5156     }
5157   }
5158 
5159   while (peek() != end_token) {
5160     StatementT stat = ParseStatementListItem();
5161     if (impl()->IsNull(stat)) return;
5162     if (stat->IsEmptyStatement()) continue;
5163     body->Add(stat);
5164   }
5165 }
5166 
5167 template <typename Impl>
5168 typename ParserBase<Impl>::StatementT
ParseStatementListItem()5169 ParserBase<Impl>::ParseStatementListItem() {
5170   // ECMA 262 6th Edition
5171   // StatementListItem[Yield, Return] :
5172   //   Statement[?Yield, ?Return]
5173   //   Declaration[?Yield]
5174   //
5175   // Declaration[Yield] :
5176   //   HoistableDeclaration[?Yield]
5177   //   ClassDeclaration[?Yield]
5178   //   LexicalDeclaration[In, ?Yield]
5179   //
5180   // HoistableDeclaration[Yield, Default] :
5181   //   FunctionDeclaration[?Yield, ?Default]
5182   //   GeneratorDeclaration[?Yield, ?Default]
5183   //
5184   // LexicalDeclaration[In, Yield] :
5185   //   LetOrConst BindingList[?In, ?Yield] ;
5186 
5187   switch (peek()) {
5188     case Token::FUNCTION:
5189       return ParseHoistableDeclaration(nullptr, false);
5190     case Token::CLASS:
5191       Consume(Token::CLASS);
5192       return ParseClassDeclaration(nullptr, false);
5193     case Token::VAR:
5194     case Token::CONST:
5195       return ParseVariableStatement(kStatementListItem, nullptr);
5196     case Token::LET:
5197       if (IsNextLetKeyword()) {
5198         return ParseVariableStatement(kStatementListItem, nullptr);
5199       }
5200       break;
5201     case Token::ASYNC:
5202       if (PeekAhead() == Token::FUNCTION &&
5203           !scanner()->HasLineTerminatorAfterNext()) {
5204         Consume(Token::ASYNC);
5205         return ParseAsyncFunctionDeclaration(nullptr, false);
5206       }
5207       break;
5208     default:
5209       break;
5210   }
5211   return ParseStatement(nullptr, nullptr, kAllowLabelledFunctionStatement);
5212 }
5213 
5214 template <typename Impl>
ParseStatement(ZonePtrList<const AstRawString> * labels,ZonePtrList<const AstRawString> * own_labels,AllowLabelledFunctionStatement allow_function)5215 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement(
5216     ZonePtrList<const AstRawString>* labels,
5217     ZonePtrList<const AstRawString>* own_labels,
5218     AllowLabelledFunctionStatement allow_function) {
5219   // Statement ::
5220   //   Block
5221   //   VariableStatement
5222   //   EmptyStatement
5223   //   ExpressionStatement
5224   //   IfStatement
5225   //   IterationStatement
5226   //   ContinueStatement
5227   //   BreakStatement
5228   //   ReturnStatement
5229   //   WithStatement
5230   //   LabelledStatement
5231   //   SwitchStatement
5232   //   ThrowStatement
5233   //   TryStatement
5234   //   DebuggerStatement
5235 
5236   // {own_labels} is always a subset of {labels}.
5237   DCHECK_IMPLIES(labels == nullptr, own_labels == nullptr);
5238 
5239   // Note: Since labels can only be used by 'break' and 'continue'
5240   // statements, which themselves are only valid within blocks,
5241   // iterations or 'switch' statements (i.e., BreakableStatements),
5242   // labels can be simply ignored in all other cases; except for
5243   // trivial labeled break statements 'label: break label' which is
5244   // parsed into an empty statement.
5245   switch (peek()) {
5246     case Token::LBRACE:
5247       return ParseBlock(labels);
5248     case Token::SEMICOLON:
5249       Next();
5250       return factory()->EmptyStatement();
5251     case Token::IF:
5252       return ParseIfStatement(labels);
5253     case Token::DO:
5254       return ParseDoWhileStatement(labels, own_labels);
5255     case Token::WHILE:
5256       return ParseWhileStatement(labels, own_labels);
5257     case Token::FOR:
5258       if (V8_UNLIKELY(is_await_allowed() && PeekAhead() == Token::AWAIT)) {
5259         return ParseForAwaitStatement(labels, own_labels);
5260       }
5261       return ParseForStatement(labels, own_labels);
5262     case Token::CONTINUE:
5263       return ParseContinueStatement();
5264     case Token::BREAK:
5265       return ParseBreakStatement(labels);
5266     case Token::RETURN:
5267       return ParseReturnStatement();
5268     case Token::THROW:
5269       return ParseThrowStatement();
5270     case Token::TRY: {
5271       // It is somewhat complicated to have labels on try-statements.
5272       // When breaking out of a try-finally statement, one must take
5273       // great care not to treat it as a fall-through. It is much easier
5274       // just to wrap the entire try-statement in a statement block and
5275       // put the labels there.
5276       if (labels == nullptr) return ParseTryStatement();
5277       StatementListT statements(pointer_buffer());
5278       BlockT result = factory()->NewBlock(false, true);
5279       Target target(this, result, labels, nullptr,
5280                     Target::TARGET_FOR_NAMED_ONLY);
5281       StatementT statement = ParseTryStatement();
5282       statements.Add(statement);
5283       result->InitializeStatements(statements, zone());
5284       return result;
5285     }
5286     case Token::WITH:
5287       return ParseWithStatement(labels);
5288     case Token::SWITCH:
5289       return ParseSwitchStatement(labels);
5290     case Token::FUNCTION:
5291       // FunctionDeclaration only allowed as a StatementListItem, not in
5292       // an arbitrary Statement position. Exceptions such as
5293       // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
5294       // are handled by calling ParseScopedStatement rather than
5295       // ParseStatement directly.
5296       impl()->ReportMessageAt(scanner()->peek_location(),
5297                               is_strict(language_mode())
5298                                   ? MessageTemplate::kStrictFunction
5299                                   : MessageTemplate::kSloppyFunction);
5300       return impl()->NullStatement();
5301     case Token::DEBUGGER:
5302       return ParseDebuggerStatement();
5303     case Token::VAR:
5304       return ParseVariableStatement(kStatement, nullptr);
5305     case Token::ASYNC:
5306       if (!impl()->HasCheckedSyntax() &&
5307           !scanner()->HasLineTerminatorAfterNext() &&
5308           PeekAhead() == Token::FUNCTION) {
5309         impl()->ReportMessageAt(
5310             scanner()->peek_location(),
5311             MessageTemplate::kAsyncFunctionInSingleStatementContext);
5312         return impl()->NullStatement();
5313       }
5314       V8_FALLTHROUGH;
5315     default:
5316       return ParseExpressionOrLabelledStatement(labels, own_labels,
5317                                                 allow_function);
5318   }
5319 }
5320 
5321 template <typename Impl>
ParseBlock(ZonePtrList<const AstRawString> * labels,Scope * block_scope)5322 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock(
5323     ZonePtrList<const AstRawString>* labels, Scope* block_scope) {
5324   // Block ::
5325   //   '{' StatementList '}'
5326 
5327   // Parse the statements and collect escaping labels.
5328   BlockT body = factory()->NewBlock(false, labels != nullptr);
5329   StatementListT statements(pointer_buffer());
5330 
5331   CheckStackOverflow();
5332 
5333   {
5334     BlockState block_state(&scope_, block_scope);
5335     scope()->set_start_position(peek_position());
5336     Target target(this, body, labels, nullptr, Target::TARGET_FOR_NAMED_ONLY);
5337 
5338     Expect(Token::LBRACE);
5339 
5340     while (peek() != Token::RBRACE) {
5341       StatementT stat = ParseStatementListItem();
5342       if (impl()->IsNull(stat)) return body;
5343       if (stat->IsEmptyStatement()) continue;
5344       statements.Add(stat);
5345     }
5346 
5347     Expect(Token::RBRACE);
5348 
5349     int end_pos = end_position();
5350     scope()->set_end_position(end_pos);
5351 
5352     impl()->RecordBlockSourceRange(body, end_pos);
5353     body->set_scope(scope()->FinalizeBlockScope());
5354   }
5355 
5356   body->InitializeStatements(statements, zone());
5357   return body;
5358 }
5359 
5360 template <typename Impl>
ParseBlock(ZonePtrList<const AstRawString> * labels)5361 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock(
5362     ZonePtrList<const AstRawString>* labels) {
5363   return ParseBlock(labels, NewScope(BLOCK_SCOPE));
5364 }
5365 
5366 template <typename Impl>
ParseScopedStatement(ZonePtrList<const AstRawString> * labels)5367 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseScopedStatement(
5368     ZonePtrList<const AstRawString>* labels) {
5369   if (is_strict(language_mode()) || peek() != Token::FUNCTION) {
5370     return ParseStatement(labels, nullptr);
5371   } else {
5372     // Make a block around the statement for a lexical binding
5373     // is introduced by a FunctionDeclaration.
5374     BlockState block_state(zone(), &scope_);
5375     scope()->set_start_position(scanner()->location().beg_pos);
5376     BlockT block = factory()->NewBlock(1, false);
5377     StatementT body = ParseFunctionDeclaration();
5378     block->statements()->Add(body, zone());
5379     scope()->set_end_position(end_position());
5380     block->set_scope(scope()->FinalizeBlockScope());
5381     return block;
5382   }
5383 }
5384 
5385 template <typename Impl>
ParseVariableStatement(VariableDeclarationContext var_context,ZonePtrList<const AstRawString> * names)5386 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseVariableStatement(
5387     VariableDeclarationContext var_context,
5388     ZonePtrList<const AstRawString>* names) {
5389   // VariableStatement ::
5390   //   VariableDeclarations ';'
5391 
5392   // The scope of a var declared variable anywhere inside a function
5393   // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
5394   // transform a source-level var declaration into a (Function) Scope
5395   // declaration, and rewrite the source-level initialization into an assignment
5396   // statement. We use a block to collect multiple assignments.
5397   //
5398   // We mark the block as initializer block because we don't want the
5399   // rewriter to add a '.result' assignment to such a block (to get compliant
5400   // behavior for code such as print(eval('var x = 7')), and for cosmetic
5401   // reasons when pretty-printing. Also, unless an assignment (initialization)
5402   // is inside an initializer block, it is ignored.
5403 
5404   DeclarationParsingResult parsing_result;
5405   ParseVariableDeclarations(var_context, &parsing_result, names);
5406   ExpectSemicolon();
5407   return impl()->BuildInitializationBlock(&parsing_result);
5408 }
5409 
5410 template <typename Impl>
5411 typename ParserBase<Impl>::StatementT
ParseDebuggerStatement()5412 ParserBase<Impl>::ParseDebuggerStatement() {
5413   // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
5414   // contexts this is used as a statement which invokes the debugger as i a
5415   // break point is present.
5416   // DebuggerStatement ::
5417   //   'debugger' ';'
5418 
5419   int pos = peek_position();
5420   Consume(Token::DEBUGGER);
5421   ExpectSemicolon();
5422   return factory()->NewDebuggerStatement(pos);
5423 }
5424 
5425 template <typename Impl>
5426 typename ParserBase<Impl>::StatementT
ParseExpressionOrLabelledStatement(ZonePtrList<const AstRawString> * labels,ZonePtrList<const AstRawString> * own_labels,AllowLabelledFunctionStatement allow_function)5427 ParserBase<Impl>::ParseExpressionOrLabelledStatement(
5428     ZonePtrList<const AstRawString>* labels,
5429     ZonePtrList<const AstRawString>* own_labels,
5430     AllowLabelledFunctionStatement allow_function) {
5431   // ExpressionStatement | LabelledStatement ::
5432   //   Expression ';'
5433   //   Identifier ':' Statement
5434   //
5435   // ExpressionStatement[Yield] :
5436   //   [lookahead notin {{, function, class, let [}] Expression[In, ?Yield] ;
5437 
5438   int pos = peek_position();
5439 
5440   switch (peek()) {
5441     case Token::FUNCTION:
5442     case Token::LBRACE:
5443       UNREACHABLE();  // Always handled by the callers.
5444     case Token::CLASS:
5445       ReportUnexpectedToken(Next());
5446       return impl()->NullStatement();
5447     case Token::LET: {
5448       Token::Value next_next = PeekAhead();
5449       // "let" followed by either "[", "{" or an identifier means a lexical
5450       // declaration, which should not appear here.
5451       // However, ASI may insert a line break before an identifier or a brace.
5452       if (next_next != Token::LBRACK &&
5453           ((next_next != Token::LBRACE && next_next != Token::IDENTIFIER) ||
5454            scanner_->HasLineTerminatorAfterNext())) {
5455         break;
5456       }
5457       impl()->ReportMessageAt(scanner()->peek_location(),
5458                               MessageTemplate::kUnexpectedLexicalDeclaration);
5459       return impl()->NullStatement();
5460     }
5461     default:
5462       break;
5463   }
5464 
5465   bool starts_with_identifier = peek_any_identifier();
5466 
5467   ExpressionT expr;
5468   {
5469     // Effectively inlines ParseExpression, so potential labels can be extracted
5470     // from expression_scope.
5471     ExpressionParsingScope expression_scope(impl());
5472     AcceptINScope scope(this, true);
5473     expr = ParseExpressionCoverGrammar();
5474     expression_scope.ValidateExpression();
5475 
5476     if (peek() == Token::COLON && starts_with_identifier &&
5477         impl()->IsIdentifier(expr)) {
5478       // The whole expression was a single identifier, and not, e.g.,
5479       // something starting with an identifier or a parenthesized identifier.
5480       DCHECK_EQ(expression_scope.variable_list()->length(), 1);
5481       VariableProxy* label = expression_scope.variable_list()->at(0).first;
5482       impl()->DeclareLabel(&labels, &own_labels, label->raw_name());
5483 
5484       // Remove the "ghost" variable that turned out to be a label from the top
5485       // scope. This way, we don't try to resolve it during the scope
5486       // processing.
5487       this->scope()->DeleteUnresolved(label);
5488 
5489       Consume(Token::COLON);
5490       // ES#sec-labelled-function-declarations Labelled Function Declarations
5491       if (peek() == Token::FUNCTION && is_sloppy(language_mode()) &&
5492           allow_function == kAllowLabelledFunctionStatement) {
5493         return ParseFunctionDeclaration();
5494       }
5495       return ParseStatement(labels, own_labels, allow_function);
5496     }
5497   }
5498 
5499   // We allow a native function declaration if we're parsing the source for an
5500   // extension. A native function declaration starts with "native function"
5501   // with no line-terminator between the two words.
5502   if (impl()->ParsingExtension() && peek() == Token::FUNCTION &&
5503       !scanner()->HasLineTerminatorBeforeNext() && impl()->IsNative(expr) &&
5504       !scanner()->literal_contains_escapes()) {
5505     return ParseNativeDeclaration();
5506   }
5507 
5508   // Parsed expression statement, followed by semicolon.
5509   ExpectSemicolon();
5510   if (expr->IsFailureExpression()) return impl()->NullStatement();
5511   return factory()->NewExpressionStatement(expr, pos);
5512 }
5513 
5514 template <typename Impl>
ParseIfStatement(ZonePtrList<const AstRawString> * labels)5515 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseIfStatement(
5516     ZonePtrList<const AstRawString>* labels) {
5517   // IfStatement ::
5518   //   'if' '(' Expression ')' Statement ('else' Statement)?
5519 
5520   int pos = peek_position();
5521   Consume(Token::IF);
5522   Expect(Token::LPAREN);
5523   ExpressionT condition = ParseExpression();
5524   Expect(Token::RPAREN);
5525 
5526   SourceRange then_range, else_range;
5527   StatementT then_statement = impl()->NullStatement();
5528   {
5529     SourceRangeScope range_scope(scanner(), &then_range);
5530     // Make a copy of {labels} to avoid conflicts with any
5531     // labels that may be applied to the else clause below.
5532     auto labels_copy =
5533         labels == nullptr
5534             ? labels
5535             : zone()->template New<ZonePtrList<const AstRawString>>(*labels,
5536                                                                     zone());
5537     then_statement = ParseScopedStatement(labels_copy);
5538   }
5539 
5540   StatementT else_statement = impl()->NullStatement();
5541   if (Check(Token::ELSE)) {
5542     else_statement = ParseScopedStatement(labels);
5543     else_range = SourceRange::ContinuationOf(then_range, end_position());
5544   } else {
5545     else_statement = factory()->EmptyStatement();
5546   }
5547   StatementT stmt =
5548       factory()->NewIfStatement(condition, then_statement, else_statement, pos);
5549   impl()->RecordIfStatementSourceRange(stmt, then_range, else_range);
5550   return stmt;
5551 }
5552 
5553 template <typename Impl>
5554 typename ParserBase<Impl>::StatementT
ParseContinueStatement()5555 ParserBase<Impl>::ParseContinueStatement() {
5556   // ContinueStatement ::
5557   //   'continue' Identifier? ';'
5558 
5559   int pos = peek_position();
5560   Consume(Token::CONTINUE);
5561   IdentifierT label = impl()->NullIdentifier();
5562   Token::Value tok = peek();
5563   if (!scanner()->HasLineTerminatorBeforeNext() &&
5564       !Token::IsAutoSemicolon(tok)) {
5565     // ECMA allows "eval" or "arguments" as labels even in strict mode.
5566     label = ParseIdentifier();
5567   }
5568   IterationStatementT target = LookupContinueTarget(label);
5569   if (impl()->IsNull(target)) {
5570     // Illegal continue statement.
5571     MessageTemplate message = MessageTemplate::kIllegalContinue;
5572     BreakableStatementT breakable_target = LookupBreakTarget(label);
5573     if (impl()->IsNull(label)) {
5574       message = MessageTemplate::kNoIterationStatement;
5575     } else if (impl()->IsNull(breakable_target)) {
5576       message = MessageTemplate::kUnknownLabel;
5577     }
5578     ReportMessage(message, label);
5579     return impl()->NullStatement();
5580   }
5581   ExpectSemicolon();
5582   StatementT stmt = factory()->NewContinueStatement(target, pos);
5583   impl()->RecordJumpStatementSourceRange(stmt, end_position());
5584   return stmt;
5585 }
5586 
5587 template <typename Impl>
ParseBreakStatement(ZonePtrList<const AstRawString> * labels)5588 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement(
5589     ZonePtrList<const AstRawString>* labels) {
5590   // BreakStatement ::
5591   //   'break' Identifier? ';'
5592 
5593   int pos = peek_position();
5594   Consume(Token::BREAK);
5595   IdentifierT label = impl()->NullIdentifier();
5596   Token::Value tok = peek();
5597   if (!scanner()->HasLineTerminatorBeforeNext() &&
5598       !Token::IsAutoSemicolon(tok)) {
5599     // ECMA allows "eval" or "arguments" as labels even in strict mode.
5600     label = ParseIdentifier();
5601   }
5602   // Parse labeled break statements that target themselves into
5603   // empty statements, e.g. 'l1: l2: l3: break l2;'
5604   if (!impl()->IsNull(label) &&
5605       impl()->ContainsLabel(labels, impl()->GetRawNameFromIdentifier(label))) {
5606     ExpectSemicolon();
5607     return factory()->EmptyStatement();
5608   }
5609   BreakableStatementT target = LookupBreakTarget(label);
5610   if (impl()->IsNull(target)) {
5611     // Illegal break statement.
5612     MessageTemplate message = MessageTemplate::kIllegalBreak;
5613     if (!impl()->IsNull(label)) {
5614       message = MessageTemplate::kUnknownLabel;
5615     }
5616     ReportMessage(message, label);
5617     return impl()->NullStatement();
5618   }
5619   ExpectSemicolon();
5620   StatementT stmt = factory()->NewBreakStatement(target, pos);
5621   impl()->RecordJumpStatementSourceRange(stmt, end_position());
5622   return stmt;
5623 }
5624 
5625 template <typename Impl>
ParseReturnStatement()5626 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseReturnStatement() {
5627   // ReturnStatement ::
5628   //   'return' [no line terminator] Expression? ';'
5629 
5630   // Consume the return token. It is necessary to do that before
5631   // reporting any errors on it, because of the way errors are
5632   // reported (underlining).
5633   Consume(Token::RETURN);
5634   Scanner::Location loc = scanner()->location();
5635 
5636   switch (GetDeclarationScope()->scope_type()) {
5637     case SCRIPT_SCOPE:
5638     case EVAL_SCOPE:
5639     case MODULE_SCOPE:
5640       impl()->ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
5641       return impl()->NullStatement();
5642     case BLOCK_SCOPE:
5643       // Class static blocks disallow return. They are their own var scopes and
5644       // have a varblock scope.
5645       if (function_state_->kind() ==
5646           FunctionKind::kClassStaticInitializerFunction) {
5647         impl()->ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
5648         return impl()->NullStatement();
5649       }
5650       break;
5651     default:
5652       break;
5653   }
5654 
5655   Token::Value tok = peek();
5656   ExpressionT return_value = impl()->NullExpression();
5657   if (scanner()->HasLineTerminatorBeforeNext() || Token::IsAutoSemicolon(tok)) {
5658     if (IsDerivedConstructor(function_state_->kind())) {
5659       ExpressionParsingScope expression_scope(impl());
5660       return_value = impl()->ThisExpression();
5661       expression_scope.ValidateExpression();
5662     }
5663   } else {
5664     return_value = ParseExpression();
5665   }
5666   ExpectSemicolon();
5667 
5668   return_value = impl()->RewriteReturn(return_value, loc.beg_pos);
5669   int continuation_pos = end_position();
5670   StatementT stmt =
5671       BuildReturnStatement(return_value, loc.beg_pos, continuation_pos);
5672   impl()->RecordJumpStatementSourceRange(stmt, end_position());
5673   return stmt;
5674 }
5675 
5676 template <typename Impl>
ParseWithStatement(ZonePtrList<const AstRawString> * labels)5677 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWithStatement(
5678     ZonePtrList<const AstRawString>* labels) {
5679   // WithStatement ::
5680   //   'with' '(' Expression ')' Statement
5681 
5682   Consume(Token::WITH);
5683   int pos = position();
5684 
5685   if (is_strict(language_mode())) {
5686     ReportMessage(MessageTemplate::kStrictWith);
5687     return impl()->NullStatement();
5688   }
5689 
5690   Expect(Token::LPAREN);
5691   ExpressionT expr = ParseExpression();
5692   Expect(Token::RPAREN);
5693 
5694   Scope* with_scope = NewScope(WITH_SCOPE);
5695   StatementT body = impl()->NullStatement();
5696   {
5697     BlockState block_state(&scope_, with_scope);
5698     with_scope->set_start_position(scanner()->peek_location().beg_pos);
5699     body = ParseStatement(labels, nullptr);
5700     with_scope->set_end_position(end_position());
5701   }
5702   return factory()->NewWithStatement(with_scope, expr, body, pos);
5703 }
5704 
5705 template <typename Impl>
ParseDoWhileStatement(ZonePtrList<const AstRawString> * labels,ZonePtrList<const AstRawString> * own_labels)5706 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDoWhileStatement(
5707     ZonePtrList<const AstRawString>* labels,
5708     ZonePtrList<const AstRawString>* own_labels) {
5709   // DoStatement ::
5710   //   'do' Statement 'while' '(' Expression ')' ';'
5711   typename FunctionState::LoopScope loop_scope(function_state_);
5712 
5713   auto loop = factory()->NewDoWhileStatement(peek_position());
5714   Target target(this, loop, labels, own_labels, Target::TARGET_FOR_ANONYMOUS);
5715 
5716   SourceRange body_range;
5717   StatementT body = impl()->NullStatement();
5718 
5719   Consume(Token::DO);
5720 
5721   CheckStackOverflow();
5722   {
5723     SourceRangeScope range_scope(scanner(), &body_range);
5724     body = ParseStatement(nullptr, nullptr);
5725   }
5726   Expect(Token::WHILE);
5727   Expect(Token::LPAREN);
5728 
5729   ExpressionT cond = ParseExpression();
5730   Expect(Token::RPAREN);
5731 
5732   // Allow do-statements to be terminated with and without
5733   // semi-colons. This allows code such as 'do;while(0)return' to
5734   // parse, which would not be the case if we had used the
5735   // ExpectSemicolon() functionality here.
5736   Check(Token::SEMICOLON);
5737 
5738   loop->Initialize(cond, body);
5739   impl()->RecordIterationStatementSourceRange(loop, body_range);
5740 
5741   return loop;
5742 }
5743 
5744 template <typename Impl>
ParseWhileStatement(ZonePtrList<const AstRawString> * labels,ZonePtrList<const AstRawString> * own_labels)5745 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWhileStatement(
5746     ZonePtrList<const AstRawString>* labels,
5747     ZonePtrList<const AstRawString>* own_labels) {
5748   // WhileStatement ::
5749   //   'while' '(' Expression ')' Statement
5750   typename FunctionState::LoopScope loop_scope(function_state_);
5751 
5752   auto loop = factory()->NewWhileStatement(peek_position());
5753   Target target(this, loop, labels, own_labels, Target::TARGET_FOR_ANONYMOUS);
5754 
5755   SourceRange body_range;
5756   StatementT body = impl()->NullStatement();
5757 
5758   Consume(Token::WHILE);
5759   Expect(Token::LPAREN);
5760   ExpressionT cond = ParseExpression();
5761   Expect(Token::RPAREN);
5762   {
5763     SourceRangeScope range_scope(scanner(), &body_range);
5764     body = ParseStatement(nullptr, nullptr);
5765   }
5766 
5767   loop->Initialize(cond, body);
5768   impl()->RecordIterationStatementSourceRange(loop, body_range);
5769 
5770   return loop;
5771 }
5772 
5773 template <typename Impl>
ParseThrowStatement()5774 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseThrowStatement() {
5775   // ThrowStatement ::
5776   //   'throw' Expression ';'
5777 
5778   Consume(Token::THROW);
5779   int pos = position();
5780   if (scanner()->HasLineTerminatorBeforeNext()) {
5781     ReportMessage(MessageTemplate::kNewlineAfterThrow);
5782     return impl()->NullStatement();
5783   }
5784   ExpressionT exception = ParseExpression();
5785   ExpectSemicolon();
5786 
5787   StatementT stmt = impl()->NewThrowStatement(exception, pos);
5788   impl()->RecordThrowSourceRange(stmt, end_position());
5789 
5790   return stmt;
5791 }
5792 
5793 template <typename Impl>
ParseSwitchStatement(ZonePtrList<const AstRawString> * labels)5794 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseSwitchStatement(
5795     ZonePtrList<const AstRawString>* labels) {
5796   // SwitchStatement ::
5797   //   'switch' '(' Expression ')' '{' CaseClause* '}'
5798   // CaseClause ::
5799   //   'case' Expression ':' StatementList
5800   //   'default' ':' StatementList
5801   int switch_pos = peek_position();
5802 
5803   Consume(Token::SWITCH);
5804   Expect(Token::LPAREN);
5805   ExpressionT tag = ParseExpression();
5806   Expect(Token::RPAREN);
5807 
5808   auto switch_statement = factory()->NewSwitchStatement(tag, switch_pos);
5809 
5810   {
5811     BlockState cases_block_state(zone(), &scope_);
5812     scope()->set_start_position(switch_pos);
5813     scope()->SetNonlinear();
5814     Target target(this, switch_statement, labels, nullptr,
5815                   Target::TARGET_FOR_ANONYMOUS);
5816 
5817     bool default_seen = false;
5818     Expect(Token::LBRACE);
5819     while (peek() != Token::RBRACE) {
5820       // An empty label indicates the default case.
5821       ExpressionT label = impl()->NullExpression();
5822       StatementListT statements(pointer_buffer());
5823       SourceRange clause_range;
5824       {
5825         SourceRangeScope range_scope(scanner(), &clause_range);
5826         if (Check(Token::CASE)) {
5827           label = ParseExpression();
5828         } else {
5829           Expect(Token::DEFAULT);
5830           if (default_seen) {
5831             ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
5832             return impl()->NullStatement();
5833           }
5834           default_seen = true;
5835         }
5836         Expect(Token::COLON);
5837         while (peek() != Token::CASE && peek() != Token::DEFAULT &&
5838                peek() != Token::RBRACE) {
5839           StatementT stat = ParseStatementListItem();
5840           if (impl()->IsNull(stat)) return stat;
5841           if (stat->IsEmptyStatement()) continue;
5842           statements.Add(stat);
5843         }
5844       }
5845       auto clause = factory()->NewCaseClause(label, statements);
5846       impl()->RecordCaseClauseSourceRange(clause, clause_range);
5847       switch_statement->cases()->Add(clause, zone());
5848     }
5849     Expect(Token::RBRACE);
5850 
5851     int end_pos = end_position();
5852     scope()->set_end_position(end_pos);
5853     impl()->RecordSwitchStatementSourceRange(switch_statement, end_pos);
5854     Scope* switch_scope = scope()->FinalizeBlockScope();
5855     if (switch_scope != nullptr) {
5856       return impl()->RewriteSwitchStatement(switch_statement, switch_scope);
5857     }
5858     return switch_statement;
5859   }
5860 }
5861 
5862 template <typename Impl>
ParseTryStatement()5863 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseTryStatement() {
5864   // TryStatement ::
5865   //   'try' Block Catch
5866   //   'try' Block Finally
5867   //   'try' Block Catch Finally
5868   //
5869   // Catch ::
5870   //   'catch' '(' Identifier ')' Block
5871   //
5872   // Finally ::
5873   //   'finally' Block
5874 
5875   Consume(Token::TRY);
5876   int pos = position();
5877 
5878   BlockT try_block = ParseBlock(nullptr);
5879 
5880   CatchInfo catch_info(this);
5881 
5882   if (peek() != Token::CATCH && peek() != Token::FINALLY) {
5883     ReportMessage(MessageTemplate::kNoCatchOrFinally);
5884     return impl()->NullStatement();
5885   }
5886 
5887   SourceRange catch_range, finally_range;
5888 
5889   BlockT catch_block = impl()->NullBlock();
5890   {
5891     SourceRangeScope catch_range_scope(scanner(), &catch_range);
5892     if (Check(Token::CATCH)) {
5893       bool has_binding;
5894       has_binding = Check(Token::LPAREN);
5895 
5896       if (has_binding) {
5897         catch_info.scope = NewScope(CATCH_SCOPE);
5898         catch_info.scope->set_start_position(scanner()->location().beg_pos);
5899 
5900         {
5901           BlockState catch_block_state(&scope_, catch_info.scope);
5902           StatementListT catch_statements(pointer_buffer());
5903 
5904           // Create a block scope to hold any lexical declarations created
5905           // as part of destructuring the catch parameter.
5906           {
5907             BlockState catch_variable_block_state(zone(), &scope_);
5908             scope()->set_start_position(position());
5909 
5910             if (peek_any_identifier()) {
5911               IdentifierT identifier = ParseNonRestrictedIdentifier();
5912               RETURN_IF_PARSE_ERROR;
5913               catch_info.variable = impl()->DeclareCatchVariableName(
5914                   catch_info.scope, identifier);
5915             } else {
5916               catch_info.variable = catch_info.scope->DeclareCatchVariableName(
5917                   ast_value_factory()->dot_catch_string());
5918 
5919               auto declaration_it = scope()->declarations()->end();
5920 
5921               VariableDeclarationParsingScope destructuring(
5922                   impl(), VariableMode::kLet, nullptr);
5923               catch_info.pattern = ParseBindingPattern();
5924 
5925               int initializer_position = end_position();
5926               auto declaration_end = scope()->declarations()->end();
5927               for (; declaration_it != declaration_end; ++declaration_it) {
5928                 declaration_it->var()->set_initializer_position(
5929                     initializer_position);
5930               }
5931 
5932               RETURN_IF_PARSE_ERROR;
5933               catch_statements.Add(impl()->RewriteCatchPattern(&catch_info));
5934             }
5935 
5936             Expect(Token::RPAREN);
5937 
5938             BlockT inner_block = ParseBlock(nullptr);
5939             catch_statements.Add(inner_block);
5940 
5941             // Check for `catch(e) { let e; }` and similar errors.
5942             if (!impl()->HasCheckedSyntax()) {
5943               Scope* inner_scope = inner_block->scope();
5944               if (inner_scope != nullptr) {
5945                 const AstRawString* conflict = nullptr;
5946                 if (impl()->IsNull(catch_info.pattern)) {
5947                   const AstRawString* name = catch_info.variable->raw_name();
5948                   if (inner_scope->LookupLocal(name)) conflict = name;
5949                 } else {
5950                   conflict = inner_scope->FindVariableDeclaredIn(
5951                       scope(), VariableMode::kVar);
5952                 }
5953                 if (conflict != nullptr) {
5954                   impl()->ReportVarRedeclarationIn(conflict, inner_scope);
5955                 }
5956               }
5957             }
5958 
5959             scope()->set_end_position(end_position());
5960             catch_block = factory()->NewBlock(false, catch_statements);
5961             catch_block->set_scope(scope()->FinalizeBlockScope());
5962           }
5963         }
5964 
5965         catch_info.scope->set_end_position(end_position());
5966       } else {
5967         catch_block = ParseBlock(nullptr);
5968       }
5969     }
5970   }
5971 
5972   BlockT finally_block = impl()->NullBlock();
5973   DCHECK(has_error() || peek() == Token::FINALLY ||
5974          !impl()->IsNull(catch_block));
5975   {
5976     SourceRangeScope range_scope(scanner(), &finally_range);
5977     if (Check(Token::FINALLY)) {
5978       finally_block = ParseBlock(nullptr);
5979     }
5980   }
5981 
5982   RETURN_IF_PARSE_ERROR;
5983   return impl()->RewriteTryStatement(try_block, catch_block, catch_range,
5984                                      finally_block, finally_range, catch_info,
5985                                      pos);
5986 }
5987 
5988 template <typename Impl>
ParseForStatement(ZonePtrList<const AstRawString> * labels,ZonePtrList<const AstRawString> * own_labels)5989 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
5990     ZonePtrList<const AstRawString>* labels,
5991     ZonePtrList<const AstRawString>* own_labels) {
5992   // Either a standard for loop
5993   //   for (<init>; <cond>; <next>) { ... }
5994   // or a for-each loop
5995   //   for (<each> of|in <iterable>) { ... }
5996   //
5997   // We parse a declaration/expression after the 'for (' and then read the first
5998   // expression/declaration before we know if this is a for or a for-each.
5999   typename FunctionState::LoopScope loop_scope(function_state_);
6000 
6001   int stmt_pos = peek_position();
6002   ForInfo for_info(this);
6003 
6004   Consume(Token::FOR);
6005   Expect(Token::LPAREN);
6006 
6007   bool starts_with_let = peek() == Token::LET;
6008   if (peek() == Token::CONST || (starts_with_let && IsNextLetKeyword())) {
6009     // The initializer contains lexical declarations,
6010     // so create an in-between scope.
6011     BlockState for_state(zone(), &scope_);
6012     scope()->set_start_position(position());
6013 
6014     // Also record whether inner functions or evals are found inside
6015     // this loop, as this information is used to simplify the desugaring
6016     // if none are found.
6017     typename FunctionState::FunctionOrEvalRecordingScope recording_scope(
6018         function_state_);
6019 
6020     // Create an inner block scope which will be the parent scope of scopes
6021     // possibly created by ParseVariableDeclarations.
6022     Scope* inner_block_scope = NewScope(BLOCK_SCOPE);
6023     {
6024       BlockState inner_state(&scope_, inner_block_scope);
6025       ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
6026                                 &for_info.bound_names);
6027     }
6028     DCHECK(IsLexicalVariableMode(for_info.parsing_result.descriptor.mode));
6029     for_info.position = position();
6030 
6031     if (CheckInOrOf(&for_info.mode)) {
6032       scope()->set_is_hidden();
6033       return ParseForEachStatementWithDeclarations(
6034           stmt_pos, &for_info, labels, own_labels, inner_block_scope);
6035     }
6036 
6037     Expect(Token::SEMICOLON);
6038 
6039     // Parse the remaining code in the inner block scope since the declaration
6040     // above was parsed there. We'll finalize the unnecessary outer block scope
6041     // after parsing the rest of the loop.
6042     StatementT result = impl()->NullStatement();
6043     inner_block_scope->set_start_position(scope()->start_position());
6044     {
6045       BlockState inner_state(&scope_, inner_block_scope);
6046       StatementT init =
6047           impl()->BuildInitializationBlock(&for_info.parsing_result);
6048 
6049       result = ParseStandardForLoopWithLexicalDeclarations(
6050           stmt_pos, init, &for_info, labels, own_labels);
6051     }
6052     Scope* finalized = scope()->FinalizeBlockScope();
6053     DCHECK_NULL(finalized);
6054     USE(finalized);
6055     return result;
6056   }
6057 
6058   StatementT init = impl()->NullStatement();
6059   if (peek() == Token::VAR) {
6060     ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
6061                               &for_info.bound_names);
6062     DCHECK_EQ(for_info.parsing_result.descriptor.mode, VariableMode::kVar);
6063     for_info.position = scanner()->location().beg_pos;
6064 
6065     if (CheckInOrOf(&for_info.mode)) {
6066       return ParseForEachStatementWithDeclarations(stmt_pos, &for_info, labels,
6067                                                    own_labels, scope());
6068     }
6069 
6070     init = impl()->BuildInitializationBlock(&for_info.parsing_result);
6071   } else if (peek() != Token::SEMICOLON) {
6072     // The initializer does not contain declarations.
6073     Scanner::Location next_loc = scanner()->peek_location();
6074     int lhs_beg_pos = next_loc.beg_pos;
6075     int lhs_end_pos;
6076     bool is_for_each;
6077     ExpressionT expression;
6078 
6079     {
6080       ExpressionParsingScope parsing_scope(impl());
6081       AcceptINScope scope(this, false);
6082       expression = ParseExpressionCoverGrammar();
6083       // `for (async of` is disallowed but `for (async.x of` is allowed, so
6084       // check if the token is ASYNC after parsing the expression.
6085       bool expression_is_async = scanner()->current_token() == Token::ASYNC &&
6086                                  !scanner()->literal_contains_escapes();
6087       // Initializer is reference followed by in/of.
6088       lhs_end_pos = end_position();
6089       is_for_each = CheckInOrOf(&for_info.mode);
6090       if (is_for_each) {
6091         if ((starts_with_let || expression_is_async) &&
6092             for_info.mode == ForEachStatement::ITERATE) {
6093           impl()->ReportMessageAt(next_loc, starts_with_let
6094                                                 ? MessageTemplate::kForOfLet
6095                                                 : MessageTemplate::kForOfAsync);
6096           return impl()->NullStatement();
6097         }
6098         if (expression->IsPattern()) {
6099           parsing_scope.ValidatePattern(expression, lhs_beg_pos, lhs_end_pos);
6100         } else {
6101           expression = parsing_scope.ValidateAndRewriteReference(
6102               expression, lhs_beg_pos, lhs_end_pos);
6103         }
6104       } else {
6105         parsing_scope.ValidateExpression();
6106       }
6107     }
6108 
6109     if (is_for_each) {
6110       return ParseForEachStatementWithoutDeclarations(
6111           stmt_pos, expression, lhs_beg_pos, lhs_end_pos, &for_info, labels,
6112           own_labels);
6113     }
6114     // Initializer is just an expression.
6115     init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
6116   }
6117 
6118   Expect(Token::SEMICOLON);
6119 
6120   // Standard 'for' loop, we have parsed the initializer at this point.
6121   ExpressionT cond = impl()->NullExpression();
6122   StatementT next = impl()->NullStatement();
6123   StatementT body = impl()->NullStatement();
6124   ForStatementT loop =
6125       ParseStandardForLoop(stmt_pos, labels, own_labels, &cond, &next, &body);
6126   RETURN_IF_PARSE_ERROR;
6127   loop->Initialize(init, cond, next, body);
6128   return loop;
6129 }
6130 
6131 template <typename Impl>
6132 typename ParserBase<Impl>::StatementT
ParseForEachStatementWithDeclarations(int stmt_pos,ForInfo * for_info,ZonePtrList<const AstRawString> * labels,ZonePtrList<const AstRawString> * own_labels,Scope * inner_block_scope)6133 ParserBase<Impl>::ParseForEachStatementWithDeclarations(
6134     int stmt_pos, ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
6135     ZonePtrList<const AstRawString>* own_labels, Scope* inner_block_scope) {
6136   // Just one declaration followed by in/of.
6137   if (for_info->parsing_result.declarations.size() != 1) {
6138     impl()->ReportMessageAt(for_info->parsing_result.bindings_loc,
6139                             MessageTemplate::kForInOfLoopMultiBindings,
6140                             ForEachStatement::VisitModeString(for_info->mode));
6141     return impl()->NullStatement();
6142   }
6143   if (for_info->parsing_result.first_initializer_loc.IsValid() &&
6144       (is_strict(language_mode()) ||
6145        for_info->mode == ForEachStatement::ITERATE ||
6146        IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
6147        !impl()->IsIdentifier(
6148            for_info->parsing_result.declarations[0].pattern))) {
6149     impl()->ReportMessageAt(for_info->parsing_result.first_initializer_loc,
6150                             MessageTemplate::kForInOfLoopInitializer,
6151                             ForEachStatement::VisitModeString(for_info->mode));
6152     return impl()->NullStatement();
6153   }
6154 
6155   BlockT init_block = impl()->RewriteForVarInLegacy(*for_info);
6156 
6157   auto loop = factory()->NewForEachStatement(for_info->mode, stmt_pos);
6158   Target target(this, loop, labels, own_labels, Target::TARGET_FOR_ANONYMOUS);
6159 
6160   ExpressionT enumerable = impl()->NullExpression();
6161   if (for_info->mode == ForEachStatement::ITERATE) {
6162     AcceptINScope scope(this, true);
6163     enumerable = ParseAssignmentExpression();
6164   } else {
6165     enumerable = ParseExpression();
6166   }
6167 
6168   Expect(Token::RPAREN);
6169 
6170   if (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode)) {
6171     inner_block_scope->set_start_position(position());
6172   }
6173 
6174   ExpressionT each_variable = impl()->NullExpression();
6175   BlockT body_block = impl()->NullBlock();
6176   {
6177     BlockState block_state(&scope_, inner_block_scope);
6178 
6179     SourceRange body_range;
6180     StatementT body = impl()->NullStatement();
6181     {
6182       SourceRangeScope range_scope(scanner(), &body_range);
6183       body = ParseStatement(nullptr, nullptr);
6184     }
6185     impl()->RecordIterationStatementSourceRange(loop, body_range);
6186 
6187     impl()->DesugarBindingInForEachStatement(for_info, &body_block,
6188                                              &each_variable);
6189     body_block->statements()->Add(body, zone());
6190 
6191     if (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode)) {
6192       scope()->set_end_position(end_position());
6193       body_block->set_scope(scope()->FinalizeBlockScope());
6194     }
6195   }
6196 
6197   loop->Initialize(each_variable, enumerable, body_block);
6198 
6199   init_block = impl()->CreateForEachStatementTDZ(init_block, *for_info);
6200 
6201   // Parsed for-in loop w/ variable declarations.
6202   if (!impl()->IsNull(init_block)) {
6203     init_block->statements()->Add(loop, zone());
6204     if (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode)) {
6205       scope()->set_end_position(end_position());
6206       init_block->set_scope(scope()->FinalizeBlockScope());
6207     }
6208     return init_block;
6209   }
6210 
6211   return loop;
6212 }
6213 
6214 template <typename Impl>
6215 typename ParserBase<Impl>::StatementT
ParseForEachStatementWithoutDeclarations(int stmt_pos,ExpressionT expression,int lhs_beg_pos,int lhs_end_pos,ForInfo * for_info,ZonePtrList<const AstRawString> * labels,ZonePtrList<const AstRawString> * own_labels)6216 ParserBase<Impl>::ParseForEachStatementWithoutDeclarations(
6217     int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
6218     ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
6219     ZonePtrList<const AstRawString>* own_labels) {
6220   auto loop = factory()->NewForEachStatement(for_info->mode, stmt_pos);
6221   Target target(this, loop, labels, own_labels, Target::TARGET_FOR_ANONYMOUS);
6222 
6223   ExpressionT enumerable = impl()->NullExpression();
6224   if (for_info->mode == ForEachStatement::ITERATE) {
6225     AcceptINScope scope(this, true);
6226     enumerable = ParseAssignmentExpression();
6227   } else {
6228     enumerable = ParseExpression();
6229   }
6230 
6231   Expect(Token::RPAREN);
6232 
6233   StatementT body = impl()->NullStatement();
6234   SourceRange body_range;
6235   {
6236     SourceRangeScope range_scope(scanner(), &body_range);
6237     body = ParseStatement(nullptr, nullptr);
6238   }
6239   impl()->RecordIterationStatementSourceRange(loop, body_range);
6240   RETURN_IF_PARSE_ERROR;
6241   loop->Initialize(expression, enumerable, body);
6242   return loop;
6243 }
6244 
6245 template <typename Impl>
6246 typename ParserBase<Impl>::StatementT
ParseStandardForLoopWithLexicalDeclarations(int stmt_pos,StatementT init,ForInfo * for_info,ZonePtrList<const AstRawString> * labels,ZonePtrList<const AstRawString> * own_labels)6247 ParserBase<Impl>::ParseStandardForLoopWithLexicalDeclarations(
6248     int stmt_pos, StatementT init, ForInfo* for_info,
6249     ZonePtrList<const AstRawString>* labels,
6250     ZonePtrList<const AstRawString>* own_labels) {
6251   // The condition and the next statement of the for loop must be parsed
6252   // in a new scope.
6253   Scope* inner_scope = NewScope(BLOCK_SCOPE);
6254   ForStatementT loop = impl()->NullStatement();
6255   ExpressionT cond = impl()->NullExpression();
6256   StatementT next = impl()->NullStatement();
6257   StatementT body = impl()->NullStatement();
6258   {
6259     BlockState block_state(&scope_, inner_scope);
6260     scope()->set_start_position(scanner()->location().beg_pos);
6261     loop =
6262         ParseStandardForLoop(stmt_pos, labels, own_labels, &cond, &next, &body);
6263     RETURN_IF_PARSE_ERROR;
6264     scope()->set_end_position(end_position());
6265   }
6266 
6267   scope()->set_end_position(end_position());
6268   if (for_info->bound_names.length() > 0 &&
6269       function_state_->contains_function_or_eval()) {
6270     scope()->set_is_hidden();
6271     return impl()->DesugarLexicalBindingsInForStatement(
6272         loop, init, cond, next, body, inner_scope, *for_info);
6273   } else {
6274     inner_scope = inner_scope->FinalizeBlockScope();
6275     DCHECK_NULL(inner_scope);
6276     USE(inner_scope);
6277   }
6278 
6279   Scope* for_scope = scope()->FinalizeBlockScope();
6280   if (for_scope != nullptr) {
6281     // Rewrite a for statement of the form
6282     //   for (const x = i; c; n) b
6283     //
6284     // into
6285     //
6286     //   {
6287     //     const x = i;
6288     //     for (; c; n) b
6289     //   }
6290     //
6291     DCHECK(!impl()->IsNull(init));
6292     BlockT block = factory()->NewBlock(2, false);
6293     block->statements()->Add(init, zone());
6294     block->statements()->Add(loop, zone());
6295     block->set_scope(for_scope);
6296     loop->Initialize(impl()->NullStatement(), cond, next, body);
6297     return block;
6298   }
6299 
6300   loop->Initialize(init, cond, next, body);
6301   return loop;
6302 }
6303 
6304 template <typename Impl>
ParseStandardForLoop(int stmt_pos,ZonePtrList<const AstRawString> * labels,ZonePtrList<const AstRawString> * own_labels,ExpressionT * cond,StatementT * next,StatementT * body)6305 typename ParserBase<Impl>::ForStatementT ParserBase<Impl>::ParseStandardForLoop(
6306     int stmt_pos, ZonePtrList<const AstRawString>* labels,
6307     ZonePtrList<const AstRawString>* own_labels, ExpressionT* cond,
6308     StatementT* next, StatementT* body) {
6309   CheckStackOverflow();
6310   ForStatementT loop = factory()->NewForStatement(stmt_pos);
6311   Target target(this, loop, labels, own_labels, Target::TARGET_FOR_ANONYMOUS);
6312 
6313   if (peek() != Token::SEMICOLON) {
6314     *cond = ParseExpression();
6315   }
6316   Expect(Token::SEMICOLON);
6317 
6318   if (peek() != Token::RPAREN) {
6319     ExpressionT exp = ParseExpression();
6320     *next = factory()->NewExpressionStatement(exp, exp->position());
6321   }
6322   Expect(Token::RPAREN);
6323 
6324   SourceRange body_range;
6325   {
6326     SourceRangeScope range_scope(scanner(), &body_range);
6327     *body = ParseStatement(nullptr, nullptr);
6328   }
6329   impl()->RecordIterationStatementSourceRange(loop, body_range);
6330 
6331   return loop;
6332 }
6333 
6334 template <typename Impl>
ParseForAwaitStatement(ZonePtrList<const AstRawString> * labels,ZonePtrList<const AstRawString> * own_labels)6335 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
6336     ZonePtrList<const AstRawString>* labels,
6337     ZonePtrList<const AstRawString>* own_labels) {
6338   // for await '(' ForDeclaration of AssignmentExpression ')'
6339   DCHECK(is_await_allowed());
6340   typename FunctionState::LoopScope loop_scope(function_state_);
6341 
6342   int stmt_pos = peek_position();
6343 
6344   ForInfo for_info(this);
6345   for_info.mode = ForEachStatement::ITERATE;
6346 
6347   // Create an in-between scope for let-bound iteration variables.
6348   BlockState for_state(zone(), &scope_);
6349   Expect(Token::FOR);
6350   Expect(Token::AWAIT);
6351   Expect(Token::LPAREN);
6352   scope()->set_start_position(scanner()->location().beg_pos);
6353   scope()->set_is_hidden();
6354 
6355   auto loop = factory()->NewForOfStatement(stmt_pos, IteratorType::kAsync);
6356   // Two suspends: one for next() and one for return()
6357   function_state_->AddSuspend();
6358   function_state_->AddSuspend();
6359 
6360   Target target(this, loop, labels, own_labels, Target::TARGET_FOR_ANONYMOUS);
6361 
6362   ExpressionT each_variable = impl()->NullExpression();
6363 
6364   bool has_declarations = false;
6365   Scope* inner_block_scope = NewScope(BLOCK_SCOPE);
6366 
6367   bool starts_with_let = peek() == Token::LET;
6368   if (peek() == Token::VAR || peek() == Token::CONST ||
6369       (starts_with_let && IsNextLetKeyword())) {
6370     // The initializer contains declarations
6371     // 'for' 'await' '(' ForDeclaration 'of' AssignmentExpression ')'
6372     //     Statement
6373     // 'for' 'await' '(' 'var' ForBinding 'of' AssignmentExpression ')'
6374     //     Statement
6375     has_declarations = true;
6376 
6377     {
6378       BlockState inner_state(&scope_, inner_block_scope);
6379       ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
6380                                 &for_info.bound_names);
6381     }
6382     for_info.position = scanner()->location().beg_pos;
6383 
6384     // Only a single declaration is allowed in for-await-of loops
6385     if (for_info.parsing_result.declarations.size() != 1) {
6386       impl()->ReportMessageAt(for_info.parsing_result.bindings_loc,
6387                               MessageTemplate::kForInOfLoopMultiBindings,
6388                               "for-await-of");
6389       return impl()->NullStatement();
6390     }
6391 
6392     // for-await-of's declarations do not permit initializers.
6393     if (for_info.parsing_result.first_initializer_loc.IsValid()) {
6394       impl()->ReportMessageAt(for_info.parsing_result.first_initializer_loc,
6395                               MessageTemplate::kForInOfLoopInitializer,
6396                               "for-await-of");
6397       return impl()->NullStatement();
6398     }
6399   } else {
6400     // The initializer does not contain declarations.
6401     // 'for' 'await' '(' LeftHandSideExpression 'of' AssignmentExpression ')'
6402     //     Statement
6403     if (starts_with_let) {
6404       impl()->ReportMessageAt(scanner()->peek_location(),
6405                               MessageTemplate::kForOfLet);
6406       return impl()->NullStatement();
6407     }
6408     int lhs_beg_pos = peek_position();
6409     BlockState inner_state(&scope_, inner_block_scope);
6410     ExpressionParsingScope parsing_scope(impl());
6411     ExpressionT lhs = each_variable = ParseLeftHandSideExpression();
6412     int lhs_end_pos = end_position();
6413 
6414     if (lhs->IsPattern()) {
6415       parsing_scope.ValidatePattern(lhs, lhs_beg_pos, lhs_end_pos);
6416     } else {
6417       each_variable = parsing_scope.ValidateAndRewriteReference(
6418           lhs, lhs_beg_pos, lhs_end_pos);
6419     }
6420   }
6421 
6422   ExpectContextualKeyword(ast_value_factory()->of_string());
6423 
6424   const bool kAllowIn = true;
6425   ExpressionT iterable = impl()->NullExpression();
6426 
6427   {
6428     AcceptINScope scope(this, kAllowIn);
6429     iterable = ParseAssignmentExpression();
6430   }
6431 
6432   Expect(Token::RPAREN);
6433 
6434   StatementT body = impl()->NullStatement();
6435   {
6436     BlockState block_state(&scope_, inner_block_scope);
6437     scope()->set_start_position(scanner()->location().beg_pos);
6438 
6439     SourceRange body_range;
6440     {
6441       SourceRangeScope range_scope(scanner(), &body_range);
6442       body = ParseStatement(nullptr, nullptr);
6443       scope()->set_end_position(end_position());
6444     }
6445     impl()->RecordIterationStatementSourceRange(loop, body_range);
6446 
6447     if (has_declarations) {
6448       BlockT body_block = impl()->NullBlock();
6449       impl()->DesugarBindingInForEachStatement(&for_info, &body_block,
6450                                                &each_variable);
6451       body_block->statements()->Add(body, zone());
6452       body_block->set_scope(scope()->FinalizeBlockScope());
6453       body = body_block;
6454     } else {
6455       Scope* block_scope = scope()->FinalizeBlockScope();
6456       DCHECK_NULL(block_scope);
6457       USE(block_scope);
6458     }
6459   }
6460 
6461   loop->Initialize(each_variable, iterable, body);
6462 
6463   if (!has_declarations) {
6464     Scope* for_scope = scope()->FinalizeBlockScope();
6465     DCHECK_NULL(for_scope);
6466     USE(for_scope);
6467     return loop;
6468   }
6469 
6470   BlockT init_block =
6471       impl()->CreateForEachStatementTDZ(impl()->NullBlock(), for_info);
6472 
6473   scope()->set_end_position(end_position());
6474   Scope* for_scope = scope()->FinalizeBlockScope();
6475   // Parsed for-in loop w/ variable declarations.
6476   if (!impl()->IsNull(init_block)) {
6477     init_block->statements()->Add(loop, zone());
6478     init_block->set_scope(for_scope);
6479     return init_block;
6480   }
6481   DCHECK_NULL(for_scope);
6482   return loop;
6483 }
6484 
6485 template <typename Impl>
CheckClassMethodName(IdentifierT name,ParsePropertyKind type,ParseFunctionFlags flags,bool is_static,bool * has_seen_constructor)6486 void ParserBase<Impl>::CheckClassMethodName(IdentifierT name,
6487                                             ParsePropertyKind type,
6488                                             ParseFunctionFlags flags,
6489                                             bool is_static,
6490                                             bool* has_seen_constructor) {
6491   DCHECK(type == ParsePropertyKind::kMethod || IsAccessor(type));
6492 
6493   AstValueFactory* avf = ast_value_factory();
6494 
6495   if (impl()->IdentifierEquals(name, avf->private_constructor_string())) {
6496     ReportMessage(MessageTemplate::kConstructorIsPrivate);
6497     return;
6498   } else if (is_static) {
6499     if (impl()->IdentifierEquals(name, avf->prototype_string())) {
6500       ReportMessage(MessageTemplate::kStaticPrototype);
6501       return;
6502     }
6503   } else if (impl()->IdentifierEquals(name, avf->constructor_string())) {
6504     if (flags != ParseFunctionFlag::kIsNormal || IsAccessor(type)) {
6505       MessageTemplate msg = (flags & ParseFunctionFlag::kIsGenerator) != 0
6506                                 ? MessageTemplate::kConstructorIsGenerator
6507                                 : (flags & ParseFunctionFlag::kIsAsync) != 0
6508                                       ? MessageTemplate::kConstructorIsAsync
6509                                       : MessageTemplate::kConstructorIsAccessor;
6510       ReportMessage(msg);
6511       return;
6512     }
6513     if (*has_seen_constructor) {
6514       ReportMessage(MessageTemplate::kDuplicateConstructor);
6515       return;
6516     }
6517     *has_seen_constructor = true;
6518     return;
6519   }
6520 }
6521 
6522 template <typename Impl>
CheckClassFieldName(IdentifierT name,bool is_static)6523 void ParserBase<Impl>::CheckClassFieldName(IdentifierT name, bool is_static) {
6524   AstValueFactory* avf = ast_value_factory();
6525   if (is_static && impl()->IdentifierEquals(name, avf->prototype_string())) {
6526     ReportMessage(MessageTemplate::kStaticPrototype);
6527     return;
6528   }
6529 
6530   if (impl()->IdentifierEquals(name, avf->constructor_string()) ||
6531       impl()->IdentifierEquals(name, avf->private_constructor_string())) {
6532     ReportMessage(MessageTemplate::kConstructorClassField);
6533     return;
6534   }
6535 }
6536 
6537 #undef RETURN_IF_PARSE_ERROR
6538 
6539 }  // namespace internal
6540 }  // namespace v8
6541 
6542 #endif  // V8_PARSING_PARSER_BASE_H_
6543