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