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