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