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