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