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