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