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 : typedef base::Flags<ParseFunctionFlag> ParseFunctionFlags;
53 :
54 : struct FormalParametersBase {
55 5350592 : 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 4369784 : return arity - has_rest;
62 : }
63 :
64 : void UpdateArityAndFunctionLength(bool is_optional, bool is_rest) {
65 8014151 : if (!is_optional && !is_rest && function_length == arity) {
66 7864387 : ++function_length;
67 : }
68 8014151 : ++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 4192889 : 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 4190400 : 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 6743688 : class ParserBase {
196 : public:
197 : // Shorten type names defined by ParserTypes<Impl>.
198 : typedef ParserTypes<Impl> Types;
199 : typedef typename v8::internal::ExpressionScope<Types> ExpressionScope;
200 : typedef typename v8::internal::ExpressionParsingScope<Types>
201 : ExpressionParsingScope;
202 : typedef typename v8::internal::AccumulationScope<Types> AccumulationScope;
203 : typedef typename v8::internal::ArrowHeadParsingScope<Types>
204 : ArrowHeadParsingScope;
205 : typedef typename v8::internal::VariableDeclarationParsingScope<Types>
206 : VariableDeclarationParsingScope;
207 : typedef typename v8::internal::ParameterDeclarationParsingScope<Types>
208 : ParameterDeclarationParsingScope;
209 :
210 : // Return types for traversing functions.
211 : typedef typename Types::Block BlockT;
212 : typedef typename Types::BreakableStatement BreakableStatementT;
213 : typedef typename Types::ClassLiteralProperty ClassLiteralPropertyT;
214 : typedef typename Types::ClassPropertyList ClassPropertyListT;
215 : typedef typename Types::Expression ExpressionT;
216 : typedef typename Types::ExpressionList ExpressionListT;
217 : typedef typename Types::FormalParameters FormalParametersT;
218 : typedef typename Types::ForStatement ForStatementT;
219 : typedef typename Types::FunctionLiteral FunctionLiteralT;
220 : typedef typename Types::Identifier IdentifierT;
221 : typedef typename Types::IterationStatement IterationStatementT;
222 : typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT;
223 : typedef typename Types::ObjectPropertyList ObjectPropertyListT;
224 : typedef typename Types::Statement StatementT;
225 : typedef typename Types::StatementList StatementListT;
226 : typedef typename Types::Suspend SuspendExpressionT;
227 : // For constructing objects returned by the traversing functions.
228 : typedef typename Types::Factory FactoryT;
229 : // Other implementation-specific tasks.
230 : typedef typename Types::FuncNameInferrer FuncNameInferrer;
231 : typedef typename Types::FuncNameInferrer::State FuncNameInferrerState;
232 : typedef typename Types::SourceRange SourceRange;
233 : typedef typename Types::SourceRangeScope SourceRangeScope;
234 : typedef typename Types::Target TargetT;
235 : typedef typename Types::TargetScope TargetScopeT;
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 3371831 : 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 11035982 : allow_eval_cache_(true) {
273 3371818 : pointer_buffer_.reserve(32);
274 3371833 : variable_buffer_.reserve(32);
275 3371838 : }
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 3371699 : ALLOW_ACCESSORS(natives)
282 3371669 : ALLOW_ACCESSORS(harmony_public_fields)
283 3371669 : ALLOW_ACCESSORS(harmony_static_fields)
284 3371669 : ALLOW_ACCESSORS(harmony_dynamic_import)
285 3371669 : ALLOW_ACCESSORS(harmony_import_meta)
286 3371669 : ALLOW_ACCESSORS(harmony_private_methods)
287 2894109 : 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 2451302 : 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 5553113 : int GetNextFunctionLiteralId() { return ++function_literal_id_; }
324 : int GetLastFunctionLiteralId() const { return function_literal_id_; }
325 :
326 3260478 : void SkipFunctionLiterals(int delta) { function_literal_id_ += delta; }
327 :
328 4994159 : 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 23750080 : : scope_stack_(scope_stack), outer_scope_(*scope_stack) {
358 23755827 : *scope_stack_ = scope;
359 : }
360 :
361 4718758 : BlockState(Zone* zone, Scope** scope_stack)
362 : : BlockState(scope_stack,
363 9437566 : new (zone) Scope(zone, *scope_stack, BLOCK_SCOPE)) {}
364 :
365 23477400 : ~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 121659857 : DeclarationScope* scope() const { return scope_->AsDeclarationScope(); }
379 :
380 4669274 : void AddProperty() { expected_property_count_++; }
381 : int expected_property_count() { return expected_property_count_; }
382 :
383 : void DisableOptimization(BailoutReason reason) {
384 1814 : dont_optimize_reason_ = reason;
385 : }
386 : BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }
387 :
388 477959 : void AddSuspend() { suspend_count_++; }
389 : int suspend_count() const { return suspend_count_; }
390 44856 : bool CanSuspend() const { return suspend_count_ > 0; }
391 :
392 274309 : 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 610126 : next_function_is_likely_called_ = !FLAG_max_lazy;
404 : }
405 :
406 5845626 : 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 256255 : : state_and_prev_value_(state, state->contains_function_or_eval_) {
415 256255 : state->contains_function_or_eval_ = false;
416 : }
417 : ~FunctionOrEvalRecordingScope() {
418 256255 : bool found = state_and_prev_value_->contains_function_or_eval_;
419 256255 : if (!found) {
420 228871 : 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 992393 : function_state_->loop_nesting_depth_++;
434 : }
435 :
436 992406 : ~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 13939209 : struct DeclarationParsingResult {
483 : struct Declaration {
484 : Declaration(ExpressionT pattern, ExpressionT initializer)
485 14213760 : : 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 13938988 : 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 97207 : scope(nullptr) {}
510 : ExpressionT pattern;
511 : Variable* variable;
512 : Scope* scope;
513 : };
514 :
515 938708 : struct ForInfo {
516 : public:
517 938694 : explicit ForInfo(ParserBase* parser)
518 : : bound_names(1, parser->zone()),
519 : mode(ForEachStatement::ENUMERATE),
520 : position(kNoSourcePosition),
521 1877412 : 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 184758 : 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 867471 : 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 11082374 : is_rest(false) {}
578 :
579 5475536 : 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 5475536 : switch (token) {
585 : case Token::COLON:
586 4515246 : kind = ParsePropertyKind::kValue;
587 4515246 : return true;
588 : case Token::COMMA:
589 70125 : kind = ParsePropertyKind::kShorthand;
590 70125 : return true;
591 : case Token::RBRACE:
592 117183 : kind = ParsePropertyKind::kShorthandOrClassField;
593 117183 : return true;
594 : case Token::ASSIGN:
595 72355 : kind = ParsePropertyKind::kAssign;
596 72355 : return true;
597 : case Token::LPAREN:
598 414096 : kind = ParsePropertyKind::kMethod;
599 414096 : return true;
600 : case Token::MUL:
601 : case Token::SEMICOLON:
602 20793 : kind = ParsePropertyKind::kClassField;
603 20793 : 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 477997 : ClassLiteralProperty::Kind ClassPropertyKindFor(ParsePropertyKind kind) {
622 477997 : 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 2974379 : DeclarationScope* NewScriptScope() const {
644 2974382 : return new (zone()) DeclarationScope(zone(), ast_value_factory());
645 : }
646 :
647 166267 : DeclarationScope* NewVarblockScope() const {
648 166267 : return new (zone()) DeclarationScope(zone(), scope(), BLOCK_SCOPE);
649 : }
650 :
651 71720 : ModuleScope* NewModuleScope(DeclarationScope* parent) const {
652 71720 : return new (zone()) ModuleScope(parent, ast_value_factory());
653 : }
654 :
655 960347 : DeclarationScope* NewEvalScope(Scope* parent) const {
656 960347 : return new (zone()) DeclarationScope(zone(), parent, EVAL_SCOPE);
657 : }
658 :
659 : Scope* NewScope(ScopeType scope_type) const {
660 1292644 : return NewScopeWithParent(scope(), scope_type);
661 : }
662 :
663 : // This constructor should only be used when absolutely necessary. Most scopes
664 : // should automatically use scope() as parent, and be fine with
665 : // NewScope(ScopeType) above.
666 1362086 : Scope* NewScopeWithParent(Scope* parent, ScopeType scope_type) const {
667 : // Must always use the specific constructors for the blacklisted scope
668 : // types.
669 : DCHECK_NE(FUNCTION_SCOPE, scope_type);
670 : DCHECK_NE(SCRIPT_SCOPE, scope_type);
671 : DCHECK_NE(MODULE_SCOPE, scope_type);
672 : DCHECK_NOT_NULL(parent);
673 1362093 : return new (zone()) Scope(zone(), parent, scope_type);
674 : }
675 :
676 : // Creates a function scope that always allocates in zone(). The function
677 : // scope itself is either allocated in zone() or in target_zone if one is
678 : // passed in.
679 5623779 : DeclarationScope* NewFunctionScope(FunctionKind kind,
680 : Zone* parse_zone = nullptr) const {
681 : DCHECK(ast_value_factory());
682 5623779 : if (parse_zone == nullptr) parse_zone = zone();
683 : DeclarationScope* result = new (zone())
684 5623796 : DeclarationScope(parse_zone, scope(), FUNCTION_SCOPE, kind);
685 :
686 : // Record presence of an inner function scope
687 5623803 : function_state_->RecordFunctionOrEvalCall();
688 :
689 : // TODO(verwaest): Move into the DeclarationScope constructor.
690 5623803 : if (!IsArrowFunction(kind)) {
691 4511048 : result->DeclareDefaultFunctionVariables(ast_value_factory());
692 : }
693 5623820 : return result;
694 : }
695 :
696 : V8_INLINE DeclarationScope* GetDeclarationScope() const {
697 3611922 : return scope()->GetDeclarationScope();
698 : }
699 : V8_INLINE DeclarationScope* GetClosureScope() const {
700 1819 : return scope()->GetClosureScope();
701 : }
702 :
703 : VariableProxy* NewRawVariable(const AstRawString* name, int pos) {
704 : return factory()->ast_node_factory()->NewVariableProxy(
705 : name, NORMAL_VARIABLE, pos);
706 : }
707 :
708 : VariableProxy* NewUnresolved(const AstRawString* name) {
709 : return scope()->NewUnresolved(factory()->ast_node_factory(), name,
710 25678 : scanner()->location().beg_pos);
711 : }
712 :
713 : VariableProxy* NewUnresolved(const AstRawString* name, int begin_pos,
714 : VariableKind kind = NORMAL_VARIABLE) {
715 : return scope()->NewUnresolved(factory()->ast_node_factory(), name,
716 33063 : begin_pos, kind);
717 : }
718 :
719 133136 : Scanner* scanner() const { return scanner_; }
720 : AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
721 43974896 : int position() const { return scanner_->location().beg_pos; }
722 614099483 : int peek_position() const { return scanner_->peek_location().beg_pos; }
723 124636926 : int end_position() const { return scanner_->location().end_pos; }
724 29509 : int peek_end_position() const { return scanner_->peek_location().end_pos; }
725 : bool stack_overflow() const {
726 : return pending_error_handler()->stack_overflow();
727 : }
728 : void set_stack_overflow() {
729 12753 : scanner_->set_parser_error();
730 : pending_error_handler()->set_stack_overflow();
731 : }
732 116987977 : void CheckStackOverflow() {
733 : // Any further calls to Next or peek will return the illegal token.
734 116987977 : if (GetCurrentStackPosition() < stack_limit_) set_stack_overflow();
735 116985264 : }
736 : int script_id() { return script_id_; }
737 2555883 : void set_script_id(int id) { script_id_ = id; }
738 :
739 : V8_INLINE Token::Value peek() { return scanner()->peek(); }
740 :
741 : // Returns the position past the following semicolon (if it exists), and the
742 : // position past the end of the current token otherwise.
743 : int PositionAfterSemicolon() {
744 47701 : return (peek() == Token::SEMICOLON) ? peek_end_position() : end_position();
745 : }
746 :
747 2009922 : V8_INLINE Token::Value PeekAhead() { return scanner()->PeekAhead(); }
748 :
749 191732103 : V8_INLINE Token::Value Next() { return scanner()->Next(); }
750 :
751 : V8_INLINE void Consume(Token::Value token) {
752 197522715 : Token::Value next = scanner()->Next();
753 : USE(next);
754 : USE(token);
755 : DCHECK_IMPLIES(!has_error(), next == token);
756 : }
757 :
758 : V8_INLINE bool Check(Token::Value token) {
759 : Token::Value next = scanner()->peek();
760 199330461 : if (next == token) {
761 : Consume(next);
762 : return true;
763 : }
764 : return false;
765 : }
766 :
767 55047132 : void Expect(Token::Value token) {
768 : Token::Value next = Next();
769 55047734 : if (V8_UNLIKELY(next != token)) {
770 835590 : ReportUnexpectedToken(next);
771 : }
772 55047734 : }
773 :
774 37917278 : void ExpectSemicolon() {
775 : // Check for automatic semicolon insertion according to
776 : // the rules given in ECMA-262, section 7.9, page 21.
777 : Token::Value tok = peek();
778 37917278 : if (V8_LIKELY(tok == Token::SEMICOLON)) {
779 : Next();
780 : return;
781 : }
782 6005875 : if (V8_LIKELY(scanner()->HasLineTerminatorBeforeNext() ||
783 : Token::IsAutoSemicolon(tok))) {
784 : return;
785 : }
786 :
787 1313625 : if (scanner()->current_token() == Token::AWAIT && !is_async_function()) {
788 21 : ReportMessageAt(scanner()->location(),
789 : MessageTemplate::kAwaitNotInAsyncFunction, kSyntaxError);
790 21 : return;
791 : }
792 :
793 1313565 : ReportUnexpectedToken(Next());
794 : }
795 :
796 : bool peek_any_identifier() { return Token::IsAnyIdentifier(peek()); }
797 :
798 1094071 : bool PeekContextualKeyword(const AstRawString* name) {
799 : return peek() == Token::IDENTIFIER &&
800 : !scanner()->next_literal_contains_escapes() &&
801 1607661 : scanner()->NextSymbol(ast_value_factory()) == name;
802 : }
803 :
804 705340 : bool CheckContextualKeyword(const AstRawString* name) {
805 705340 : if (PeekContextualKeyword(name)) {
806 : Consume(Token::IDENTIFIER);
807 192692 : return true;
808 : }
809 : return false;
810 : }
811 :
812 134075 : void ExpectContextualKeyword(const AstRawString* name,
813 : const char* fullname = nullptr, int pos = -1) {
814 134075 : Expect(Token::IDENTIFIER);
815 134075 : if (V8_UNLIKELY(scanner()->CurrentSymbol(ast_value_factory()) != name)) {
816 9478 : ReportUnexpectedToken(scanner()->current_token());
817 : }
818 134075 : if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
819 : const char* full = fullname == nullptr
820 : ? reinterpret_cast<const char*>(name->raw_data())
821 3005 : : fullname;
822 3005 : int start = pos == -1 ? position() : pos;
823 3005 : impl()->ReportMessageAt(Scanner::Location(start, end_position()),
824 : MessageTemplate::kInvalidEscapedMetaProperty,
825 : full);
826 : }
827 134075 : }
828 :
829 793296 : bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode) {
830 793304 : if (Check(Token::IN)) {
831 90728 : *visit_mode = ForEachStatement::ENUMERATE;
832 90728 : return true;
833 702576 : } else if (CheckContextualKeyword(ast_value_factory()->of_string())) {
834 191515 : *visit_mode = ForEachStatement::ITERATE;
835 191515 : return true;
836 : }
837 : return false;
838 : }
839 :
840 441511 : bool PeekInOrOf() {
841 : return peek() == Token::IN ||
842 441511 : PeekContextualKeyword(ast_value_factory()->of_string());
843 : }
844 :
845 : // Checks whether an octal literal was last seen between beg_pos and end_pos.
846 : // Only called for strict mode strings.
847 2667106 : void CheckStrictOctalLiteral(int beg_pos, int end_pos) {
848 : Scanner::Location octal = scanner()->octal_position();
849 2667106 : if (octal.IsValid() && beg_pos <= octal.beg_pos &&
850 : octal.end_pos <= end_pos) {
851 : MessageTemplate message = scanner()->octal_message();
852 : DCHECK_NE(message, MessageTemplate::kNone);
853 2865 : impl()->ReportMessageAt(octal, message);
854 : scanner()->clear_octal_position();
855 2865 : if (message == MessageTemplate::kStrictDecimalWithLeadingZero) {
856 : impl()->CountUsage(v8::Isolate::kDecimalWithLeadingZeroInStrictMode);
857 : }
858 : }
859 2667106 : }
860 :
861 : // Checks if an octal literal or an invalid hex or unicode escape sequence
862 : // appears in the current template literal token. In the presence of such,
863 : // either returns false or reports an error, depending on should_throw.
864 : // Otherwise returns true.
865 153125 : inline bool CheckTemplateEscapes(bool should_throw) {
866 : DCHECK(Token::IsTemplate(scanner()->current_token()));
867 153125 : if (!scanner()->has_invalid_template_escape()) return true;
868 :
869 : // Handle error case(s)
870 12980 : if (should_throw) {
871 6344 : impl()->ReportMessageAt(scanner()->invalid_template_escape_location(),
872 : scanner()->invalid_template_escape_message());
873 : }
874 : scanner()->clear_invalid_template_escape_message();
875 12980 : return should_throw;
876 : }
877 :
878 : ExpressionT ParsePossibleDestructuringSubPattern(AccumulationScope* scope);
879 : void ClassifyParameter(IdentifierT parameter, int beg_pos, int end_pos);
880 : void ClassifyArrowParameter(AccumulationScope* accumulation_scope,
881 : int position, ExpressionT parameter);
882 :
883 : // Checking the name of a function literal. This has to be done after parsing
884 : // the function, since the function can declare itself strict.
885 4248931 : void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name,
886 : FunctionNameValidity function_name_validity,
887 : const Scanner::Location& function_name_loc) {
888 4248931 : if (impl()->IsNull(function_name)) return;
889 4182726 : if (function_name_validity == kSkipFunctionNameCheck) return;
890 : // The function name needs to be checked in strict mode.
891 3114489 : if (is_sloppy(language_mode)) return;
892 :
893 409409 : if (impl()->IsEvalOrArguments(function_name)) {
894 623 : impl()->ReportMessageAt(function_name_loc,
895 : MessageTemplate::kStrictEvalArguments);
896 343 : return;
897 : }
898 408786 : if (function_name_validity == kFunctionNameIsStrictReserved) {
899 1807 : impl()->ReportMessageAt(function_name_loc,
900 : MessageTemplate::kUnexpectedStrictReserved);
901 231 : return;
902 : }
903 : }
904 :
905 60742597 : typename Types::Factory* factory() { return &ast_node_factory_; }
906 :
907 : DeclarationScope* GetReceiverScope() const {
908 37860 : return scope()->GetReceiverScope();
909 : }
910 : LanguageMode language_mode() { return scope()->language_mode(); }
911 39029 : void RaiseLanguageMode(LanguageMode mode) {
912 : LanguageMode old = scope()->language_mode();
913 1527789 : impl()->SetLanguageMode(scope(), old > mode ? old : mode);
914 39029 : }
915 : bool is_generator() const {
916 : return IsGeneratorFunction(function_state_->kind());
917 : }
918 : bool is_async_function() const {
919 : return IsAsyncFunction(function_state_->kind());
920 : }
921 : bool is_async_generator() const {
922 : return IsAsyncGeneratorFunction(function_state_->kind());
923 : }
924 : bool is_resumable() const {
925 : return IsResumableFunction(function_state_->kind());
926 : }
927 :
928 : const PendingCompilationErrorHandler* pending_error_handler() const {
929 : return pending_error_handler_;
930 : }
931 : PendingCompilationErrorHandler* pending_error_handler() {
932 : return pending_error_handler_;
933 : }
934 :
935 : // Report syntax errors.
936 20174 : V8_NOINLINE void ReportMessage(MessageTemplate message) {
937 20174 : Scanner::Location source_location = scanner()->location();
938 20174 : impl()->ReportMessageAt(source_location, message,
939 : static_cast<const char*>(nullptr), kSyntaxError);
940 20174 : }
941 :
942 : template <typename T>
943 635 : V8_NOINLINE void ReportMessage(MessageTemplate message, T arg,
944 : ParseErrorType error_type = kSyntaxError) {
945 635 : Scanner::Location source_location = scanner()->location();
946 635 : impl()->ReportMessageAt(source_location, message, arg, error_type);
947 635 : }
948 :
949 25193 : V8_NOINLINE void ReportMessageAt(Scanner::Location location,
950 : MessageTemplate message,
951 : ParseErrorType error_type) {
952 25193 : impl()->ReportMessageAt(location, message,
953 : static_cast<const char*>(nullptr), error_type);
954 25193 : }
955 :
956 : V8_NOINLINE void ReportUnexpectedToken(Token::Value token);
957 :
958 5205352 : void ValidateFormalParameters(LanguageMode language_mode,
959 : const FormalParametersT& parameters,
960 : bool allow_duplicates) {
961 5205352 : if (!allow_duplicates) parameters.ValidateDuplicate(impl());
962 5205362 : if (is_strict(language_mode)) parameters.ValidateStrictMode(impl());
963 5205363 : }
964 :
965 : // Needs to be called if the reference needs to be available from the current
966 : // point. It causes the receiver to be context allocated if necessary.
967 : // Returns the receiver variable that we're referencing.
968 : V8_INLINE Variable* UseThis() {
969 5695383 : DeclarationScope* closure_scope = scope()->GetClosureScope();
970 5695381 : DeclarationScope* receiver_scope = closure_scope->GetReceiverScope();
971 : Variable* var = receiver_scope->receiver();
972 : var->set_is_used();
973 5695361 : if (closure_scope == receiver_scope) {
974 : // It's possible that we're parsing the head of an arrow function, in
975 : // which case we haven't realized yet that closure_scope !=
976 : // receiver_scope. Mark through the ExpressionScope for now.
977 2483438 : expression_scope()->RecordThisUse();
978 : } else {
979 : closure_scope->set_has_this_reference();
980 : var->ForceContextAllocation();
981 : }
982 : return var;
983 : }
984 :
985 : V8_INLINE IdentifierT ParseAndClassifyIdentifier(Token::Value token);
986 : // Parses an identifier or a strict mode future reserved word. Allows passing
987 : // in function_kind for the case of parsing the identifier in a function
988 : // expression, where the relevant "function_kind" bit is of the function being
989 : // parsed, not the containing function.
990 : V8_INLINE IdentifierT ParseIdentifier(FunctionKind function_kind);
991 : V8_INLINE IdentifierT ParseIdentifier() {
992 1919216 : return ParseIdentifier(function_state_->kind());
993 : }
994 : // Same as above but additionally disallows 'eval' and 'arguments' in strict
995 : // mode.
996 : IdentifierT ParseNonRestrictedIdentifier();
997 :
998 : // This method should be used to ambiguously parse property names that can
999 : // become destructuring identifiers.
1000 : V8_INLINE IdentifierT ParsePropertyName();
1001 :
1002 : ExpressionT ParsePropertyOrPrivatePropertyName();
1003 :
1004 : ExpressionT ParseRegExpLiteral();
1005 :
1006 : ExpressionT ParseBindingPattern();
1007 : ExpressionT ParsePrimaryExpression();
1008 :
1009 : // Use when parsing an expression that is known to not be a pattern or part of
1010 : // a pattern.
1011 : V8_INLINE ExpressionT ParseExpression();
1012 : V8_INLINE ExpressionT ParseAssignmentExpression();
1013 :
1014 : // These methods do not wrap the parsing of the expression inside a new
1015 : // expression_scope; they use the outer expression_scope instead. They should
1016 : // be used whenever we're parsing something with the "cover" grammar that
1017 : // recognizes both patterns and non-patterns (which roughly corresponds to
1018 : // what's inside the parentheses generated by the symbol
1019 : // "CoverParenthesizedExpressionAndArrowParameterList" in the ES 2017
1020 : // specification).
1021 : ExpressionT ParseExpressionCoverGrammar();
1022 : ExpressionT ParseAssignmentExpressionCoverGrammar();
1023 :
1024 : ExpressionT ParseArrowParametersWithRest(ExpressionListT* list,
1025 : AccumulationScope* scope);
1026 :
1027 : ExpressionT ParseArrayLiteral();
1028 :
1029 : inline static bool IsAccessor(ParsePropertyKind kind) {
1030 : return IsInRange(kind, ParsePropertyKind::kAccessorGetter,
1031 : ParsePropertyKind::kAccessorSetter);
1032 : }
1033 :
1034 : ExpressionT ParseProperty(ParsePropertyInfo* prop_info);
1035 : ExpressionT ParseObjectLiteral();
1036 : ClassLiteralPropertyT ParseClassPropertyDefinition(
1037 : ClassInfo* class_info, ParsePropertyInfo* prop_info, bool has_extends);
1038 : void CheckClassFieldName(IdentifierT name, bool is_static);
1039 : void CheckClassMethodName(IdentifierT name, ParsePropertyKind type,
1040 : ParseFunctionFlags flags, bool is_static,
1041 : bool* has_seen_constructor);
1042 : ExpressionT ParseMemberInitializer(ClassInfo* class_info, int beg_pos,
1043 : bool is_static);
1044 : ObjectLiteralPropertyT ParseObjectPropertyDefinition(
1045 : ParsePropertyInfo* prop_info, bool* has_seen_proto);
1046 : void ParseArguments(
1047 : ExpressionListT* args, bool* has_spread,
1048 : ParsingArrowHeadFlag maybe_arrow = kCertainlyNotArrowHead);
1049 :
1050 : ExpressionT ParseYieldExpression();
1051 : V8_INLINE ExpressionT ParseConditionalExpression();
1052 : ExpressionT ParseConditionalContinuation(ExpressionT expression, int pos);
1053 : ExpressionT ParseBinaryContinuation(ExpressionT x, int prec, int prec1);
1054 : V8_INLINE ExpressionT ParseBinaryExpression(int prec);
1055 : ExpressionT ParseUnaryOrPrefixExpression();
1056 : ExpressionT ParseAwaitExpression();
1057 : V8_INLINE ExpressionT ParseUnaryExpression();
1058 : V8_INLINE ExpressionT ParsePostfixExpression();
1059 : V8_NOINLINE ExpressionT ParsePostfixContinuation(ExpressionT expression,
1060 : int lhs_beg_pos);
1061 : V8_INLINE ExpressionT ParseLeftHandSideExpression();
1062 : ExpressionT ParseLeftHandSideContinuation(ExpressionT expression);
1063 : ExpressionT ParseMemberWithPresentNewPrefixesExpression();
1064 : ExpressionT ParseFunctionExpression();
1065 : V8_INLINE ExpressionT ParseMemberExpression();
1066 : V8_INLINE ExpressionT
1067 : ParseMemberExpressionContinuation(ExpressionT expression) {
1068 109295991 : if (!Token::IsMember(peek())) return expression;
1069 17124687 : return DoParseMemberExpressionContinuation(expression);
1070 : }
1071 : ExpressionT DoParseMemberExpressionContinuation(ExpressionT expression);
1072 :
1073 : ExpressionT ParseArrowFunctionLiteral(const FormalParametersT& parameters);
1074 : void ParseAsyncFunctionBody(Scope* scope, StatementListT* body);
1075 : ExpressionT ParseAsyncFunctionLiteral();
1076 : ExpressionT ParseClassLiteral(IdentifierT name,
1077 : Scanner::Location class_name_location,
1078 : bool name_is_strict_reserved,
1079 : int class_token_pos);
1080 : ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool tagged);
1081 : ExpressionT ParseSuperExpression(bool is_new);
1082 : ExpressionT ParseImportExpressions();
1083 : ExpressionT ParseNewTargetExpression();
1084 :
1085 : V8_INLINE void ParseFormalParameter(FormalParametersT* parameters);
1086 : void ParseFormalParameterList(FormalParametersT* parameters);
1087 : void CheckArityRestrictions(int param_count, FunctionKind function_type,
1088 : bool has_rest, int formals_start_pos,
1089 : int formals_end_pos);
1090 :
1091 : void ParseVariableDeclarations(VariableDeclarationContext var_context,
1092 : DeclarationParsingResult* parsing_result,
1093 : ZonePtrList<const AstRawString>* names);
1094 : StatementT ParseAsyncFunctionDeclaration(
1095 : ZonePtrList<const AstRawString>* names, bool default_export);
1096 : StatementT ParseFunctionDeclaration();
1097 : StatementT ParseHoistableDeclaration(ZonePtrList<const AstRawString>* names,
1098 : bool default_export);
1099 : StatementT ParseHoistableDeclaration(int pos, ParseFunctionFlags flags,
1100 : ZonePtrList<const AstRawString>* names,
1101 : bool default_export);
1102 : StatementT ParseClassDeclaration(ZonePtrList<const AstRawString>* names,
1103 : bool default_export);
1104 : StatementT ParseNativeDeclaration();
1105 :
1106 : // Whether we're parsing a single-expression arrow function or something else.
1107 : enum class FunctionBodyType { kExpression, kBlock };
1108 : // Consumes the ending }.
1109 : void ParseFunctionBody(StatementListT* body, IdentifierT function_name,
1110 : int pos, const FormalParametersT& parameters,
1111 : FunctionKind kind,
1112 : FunctionLiteral::FunctionType function_type,
1113 : FunctionBodyType body_type);
1114 :
1115 : // Check if the scope has conflicting var/let declarations from different
1116 : // scopes. This covers for example
1117 : //
1118 : // function f() { { { var x; } let x; } }
1119 : // function g() { { var x; let x; } }
1120 : //
1121 : // The var declarations are hoisted to the function scope, but originate from
1122 : // a scope where the name has also been let bound or the var declaration is
1123 : // hoisted over such a scope.
1124 7520922 : void CheckConflictingVarDeclarations(DeclarationScope* scope) {
1125 7520922 : if (has_error()) return;
1126 6587324 : Declaration* decl = scope->CheckConflictingVarDeclarations();
1127 6587337 : if (decl != nullptr) {
1128 : // In ES6, conflicting variable bindings are early errors.
1129 : const AstRawString* name = decl->var()->raw_name();
1130 : int position = decl->position();
1131 : Scanner::Location location =
1132 : position == kNoSourcePosition
1133 : ? Scanner::Location::invalid()
1134 13283 : : Scanner::Location(position, position + 1);
1135 13283 : impl()->ReportMessageAt(location, MessageTemplate::kVarRedeclaration,
1136 : name);
1137 : }
1138 : }
1139 :
1140 : // TODO(nikolaos, marja): The first argument should not really be passed
1141 : // by value. The method is expected to add the parsed statements to the
1142 : // list. This works because in the case of the parser, StatementListT is
1143 : // a pointer whereas the preparser does not really modify the body.
1144 : V8_INLINE void ParseStatementList(StatementListT* body,
1145 : Token::Value end_token);
1146 : StatementT ParseStatementListItem();
1147 :
1148 : StatementT ParseStatement(ZonePtrList<const AstRawString>* labels,
1149 : ZonePtrList<const AstRawString>* own_labels) {
1150 : return ParseStatement(labels, own_labels,
1151 4898180 : kDisallowLabelledFunctionStatement);
1152 : }
1153 : StatementT ParseStatement(ZonePtrList<const AstRawString>* labels,
1154 : ZonePtrList<const AstRawString>* own_labels,
1155 : AllowLabelledFunctionStatement allow_function);
1156 : BlockT ParseBlock(ZonePtrList<const AstRawString>* labels);
1157 :
1158 : // Parse a SubStatement in strict mode, or with an extra block scope in
1159 : // sloppy mode to handle
1160 : // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
1161 : StatementT ParseScopedStatement(ZonePtrList<const AstRawString>* labels);
1162 :
1163 : StatementT ParseVariableStatement(VariableDeclarationContext var_context,
1164 : ZonePtrList<const AstRawString>* names);
1165 :
1166 : // Magical syntax support.
1167 : ExpressionT ParseV8Intrinsic();
1168 :
1169 : StatementT ParseDebuggerStatement();
1170 :
1171 : StatementT ParseExpressionOrLabelledStatement(
1172 : ZonePtrList<const AstRawString>* labels,
1173 : ZonePtrList<const AstRawString>* own_labels,
1174 : AllowLabelledFunctionStatement allow_function);
1175 : StatementT ParseIfStatement(ZonePtrList<const AstRawString>* labels);
1176 : StatementT ParseContinueStatement();
1177 : StatementT ParseBreakStatement(ZonePtrList<const AstRawString>* labels);
1178 : StatementT ParseReturnStatement();
1179 : StatementT ParseWithStatement(ZonePtrList<const AstRawString>* labels);
1180 : StatementT ParseDoWhileStatement(ZonePtrList<const AstRawString>* labels,
1181 : ZonePtrList<const AstRawString>* own_labels);
1182 : StatementT ParseWhileStatement(ZonePtrList<const AstRawString>* labels,
1183 : ZonePtrList<const AstRawString>* own_labels);
1184 : StatementT ParseThrowStatement();
1185 : StatementT ParseSwitchStatement(ZonePtrList<const AstRawString>* labels);
1186 : V8_INLINE StatementT ParseTryStatement();
1187 : StatementT ParseForStatement(ZonePtrList<const AstRawString>* labels,
1188 : ZonePtrList<const AstRawString>* own_labels);
1189 : StatementT ParseForEachStatementWithDeclarations(
1190 : int stmt_pos, ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
1191 : ZonePtrList<const AstRawString>* own_labels, Scope* inner_block_scope);
1192 : StatementT ParseForEachStatementWithoutDeclarations(
1193 : int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
1194 : ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
1195 : ZonePtrList<const AstRawString>* own_labels);
1196 :
1197 : // Parse a C-style for loop: 'for (<init>; <cond>; <next>) { ... }'
1198 : // "for (<init>;" is assumed to have been parser already.
1199 : ForStatementT ParseStandardForLoop(
1200 : int stmt_pos, ZonePtrList<const AstRawString>* labels,
1201 : ZonePtrList<const AstRawString>* own_labels, ExpressionT* cond,
1202 : StatementT* next, StatementT* body);
1203 : // Same as the above, but handles those cases where <init> is a
1204 : // lexical variable declaration.
1205 : StatementT ParseStandardForLoopWithLexicalDeclarations(
1206 : int stmt_pos, StatementT init, ForInfo* for_info,
1207 : ZonePtrList<const AstRawString>* labels,
1208 : ZonePtrList<const AstRawString>* own_labels);
1209 : StatementT ParseForAwaitStatement(
1210 : ZonePtrList<const AstRawString>* labels,
1211 : ZonePtrList<const AstRawString>* own_labels);
1212 :
1213 : V8_INLINE bool IsLet(const AstRawString* identifier) const {
1214 : return identifier == ast_value_factory()->let_string();
1215 : }
1216 :
1217 : bool IsNextLetKeyword();
1218 :
1219 : // Checks if the expression is a valid reference expression (e.g., on the
1220 : // left-hand side of assignments). Although ruled out by ECMA as early errors,
1221 : // we allow calls for web compatibility and rewrite them to a runtime throw.
1222 : ExpressionT RewriteInvalidReferenceExpression(
1223 : ExpressionT expression, int beg_pos, int end_pos, MessageTemplate message,
1224 : ParseErrorType type = kReferenceError);
1225 :
1226 : bool IsValidReferenceExpression(ExpressionT expression);
1227 :
1228 14899907 : bool IsAssignableIdentifier(ExpressionT expression) {
1229 25079730 : if (!impl()->IsIdentifier(expression)) return false;
1230 7650675 : if (is_strict(language_mode()) &&
1231 : impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) {
1232 : return false;
1233 : }
1234 3126146 : return true;
1235 : }
1236 :
1237 : FunctionKind FunctionKindForImpl(bool is_method, ParseFunctionFlags flags) {
1238 : static const FunctionKind kFunctionKinds[][2][2] = {
1239 : {
1240 : // is_method=false
1241 : {// is_generator=false
1242 : FunctionKind::kNormalFunction, FunctionKind::kAsyncFunction},
1243 : {// is_generator=true
1244 : FunctionKind::kGeneratorFunction,
1245 : FunctionKind::kAsyncGeneratorFunction},
1246 : },
1247 : {
1248 : // is_method=true
1249 : {// is_generator=false
1250 : FunctionKind::kConciseMethod, FunctionKind::kAsyncConciseMethod},
1251 : {// is_generator=true
1252 : FunctionKind::kConciseGeneratorMethod,
1253 : FunctionKind::kAsyncConciseGeneratorMethod},
1254 : }};
1255 : return kFunctionKinds[is_method]
1256 : [(flags & ParseFunctionFlag::kIsGenerator) != 0]
1257 3437342 : [(flags & ParseFunctionFlag::kIsAsync) != 0];
1258 : }
1259 :
1260 : inline FunctionKind FunctionKindFor(ParseFunctionFlags flags) {
1261 : const bool kIsMethod = false;
1262 : return FunctionKindForImpl(kIsMethod, flags);
1263 : }
1264 :
1265 : inline FunctionKind MethodKindFor(ParseFunctionFlags flags) {
1266 : const bool kIsMethod = true;
1267 : return FunctionKindForImpl(kIsMethod, flags);
1268 : }
1269 :
1270 : // Keep track of eval() calls since they disable all local variable
1271 : // optimizations. This checks if expression is an eval call, and if yes,
1272 : // forwards the information to scope.
1273 13257995 : Call::PossiblyEval CheckPossibleEvalCall(ExpressionT expression,
1274 : Scope* scope) {
1275 22213647 : if (impl()->IsIdentifier(expression) &&
1276 : impl()->IsEval(impl()->AsIdentifier(expression))) {
1277 : scope->RecordInnerScopeEvalCall();
1278 221823 : function_state_->RecordFunctionOrEvalCall();
1279 221823 : if (is_sloppy(scope->language_mode())) {
1280 : // For sloppy scopes we also have to record the call at function level,
1281 : // in case it includes declarations that will be hoisted.
1282 146408 : scope->GetDeclarationScope()->RecordEvalCall();
1283 : }
1284 :
1285 : // This call is only necessary to track evals that may be
1286 : // inside arrow function parameter lists. In that case,
1287 : // Scope::Snapshot::Reparent will move this bit down into
1288 : // the arrow function's scope.
1289 : scope->RecordEvalCall();
1290 :
1291 133796 : return Call::IS_POSSIBLY_EVAL;
1292 : }
1293 : return Call::NOT_EVAL;
1294 : }
1295 :
1296 : // Convenience method which determines the type of return statement to emit
1297 : // depending on the current function type.
1298 4325751 : inline StatementT BuildReturnStatement(ExpressionT expr, int pos,
1299 : int end_pos = kNoSourcePosition) {
1300 4325751 : if (impl()->IsNull(expr)) {
1301 : expr = factory()->NewUndefinedLiteral(kNoSourcePosition);
1302 4002627 : } else if (is_async_generator()) {
1303 : // In async generators, if there is an explicit operand to the return
1304 : // statement, await the operand.
1305 25543 : expr = factory()->NewAwait(expr, kNoSourcePosition);
1306 26699 : function_state_->AddSuspend();
1307 : }
1308 4325754 : if (is_async_function()) {
1309 29832 : return factory()->NewAsyncReturnStatement(expr, pos, end_pos);
1310 : }
1311 1390310 : return factory()->NewReturnStatement(expr, pos, end_pos);
1312 : }
1313 :
1314 : ModuleDescriptor* module() const {
1315 37440 : return scope()->AsModuleScope()->module();
1316 : }
1317 : Scope* scope() const { return scope_; }
1318 :
1319 : // Stack of expression expression_scopes.
1320 : // The top of the stack is always pointed to by expression_scope().
1321 : V8_INLINE ExpressionScope* expression_scope() const {
1322 : DCHECK_NOT_NULL(expression_scope_);
1323 191153346 : return expression_scope_;
1324 : }
1325 :
1326 : class AcceptINScope final {
1327 : public:
1328 : AcceptINScope(ParserBase* parser, bool accept_IN)
1329 83340767 : : parser_(parser), previous_accept_IN_(parser->accept_IN_) {
1330 83340767 : parser_->accept_IN_ = accept_IN;
1331 : }
1332 :
1333 73566400 : ~AcceptINScope() { parser_->accept_IN_ = previous_accept_IN_; }
1334 :
1335 : private:
1336 : ParserBase* parser_;
1337 : bool previous_accept_IN_;
1338 : };
1339 :
1340 : class ParameterParsingScope {
1341 : public:
1342 : ParameterParsingScope(Impl* parser, FormalParametersT* parameters)
1343 4409516 : : parser_(parser), parent_parameters_(parser_->parameters_) {
1344 4409516 : parser_->parameters_ = parameters;
1345 : }
1346 :
1347 4409490 : ~ParameterParsingScope() { parser_->parameters_ = parent_parameters_; }
1348 :
1349 : private:
1350 : Impl* parser_;
1351 : FormalParametersT* parent_parameters_;
1352 : };
1353 :
1354 : class FunctionBodyParsingScope {
1355 : public:
1356 : explicit FunctionBodyParsingScope(Impl* parser)
1357 2777191 : : parser_(parser), expression_scope_(parser_->expression_scope_) {
1358 2777191 : parser_->expression_scope_ = nullptr;
1359 : }
1360 :
1361 : ~FunctionBodyParsingScope() {
1362 2757058 : parser_->expression_scope_ = expression_scope_;
1363 : }
1364 :
1365 : private:
1366 : Impl* parser_;
1367 : ExpressionScope* expression_scope_;
1368 : };
1369 :
1370 42404276 : std::vector<void*>* pointer_buffer() { return &pointer_buffer_; }
1371 58809154 : std::vector<void*>* variable_buffer() { return &variable_buffer_; }
1372 :
1373 : // Parser base's protected field members.
1374 :
1375 : Scope* scope_; // Scope stack.
1376 : Scope* original_scope_; // The top scope for the current parsing item.
1377 : FunctionState* function_state_; // Function state stack.
1378 : v8::Extension* extension_;
1379 : FuncNameInferrer fni_;
1380 : AstValueFactory* ast_value_factory_; // Not owned.
1381 : typename Types::Factory ast_node_factory_;
1382 : RuntimeCallStats* runtime_call_stats_;
1383 : internal::Logger* logger_;
1384 : bool parsing_on_main_thread_;
1385 : const bool parsing_module_;
1386 : uintptr_t stack_limit_;
1387 : PendingCompilationErrorHandler* pending_error_handler_;
1388 :
1389 : // Parser base's private field members.
1390 :
1391 : private:
1392 : Zone* zone_;
1393 : ExpressionScope* expression_scope_;
1394 :
1395 : std::vector<void*> pointer_buffer_;
1396 : std::vector<void*> variable_buffer_;
1397 :
1398 : Scanner* scanner_;
1399 :
1400 : int function_literal_id_;
1401 : int script_id_;
1402 :
1403 : FunctionLiteral::EagerCompileHint default_eager_compile_hint_;
1404 :
1405 : // This struct is used to move information about the next arrow function from
1406 : // the place where the arrow head was parsed to where the body will be parsed.
1407 : // Nothing can be parsed between the head and the body, so it will be consumed
1408 : // immediately after it's produced.
1409 : // Preallocating the struct as part of the parser minimizes the cost of
1410 : // supporting arrow functions on non-arrow expressions.
1411 3371818 : struct NextArrowFunctionInfo {
1412 : Scanner::Location strict_parameter_error_location =
1413 : Scanner::Location::invalid();
1414 : MessageTemplate strict_parameter_error_message = MessageTemplate::kNone;
1415 : DeclarationScope* scope = nullptr;
1416 :
1417 : bool HasInitialState() const { return scope == nullptr; }
1418 :
1419 : void Reset() {
1420 910751 : scope = nullptr;
1421 : ClearStrictParameterError();
1422 : DCHECK(HasInitialState());
1423 : }
1424 :
1425 : // Tracks strict-mode parameter violations of sloppy-mode arrow heads in
1426 : // case the function ends up becoming strict mode. Only one global place to
1427 : // track this is necessary since arrow functions with none-simple parameters
1428 : // cannot become strict-mode later on.
1429 : void ClearStrictParameterError() {
1430 3867862 : strict_parameter_error_location = Scanner::Location::invalid();
1431 3867862 : strict_parameter_error_message = MessageTemplate::kNone;
1432 : }
1433 : };
1434 :
1435 : FormalParametersT* parameters_;
1436 : NextArrowFunctionInfo next_arrow_function_info_;
1437 :
1438 : bool accept_IN_ = true;
1439 :
1440 : bool allow_natives_;
1441 : bool allow_harmony_public_fields_;
1442 : bool allow_harmony_static_fields_;
1443 : bool allow_harmony_dynamic_import_;
1444 : bool allow_harmony_import_meta_;
1445 : bool allow_harmony_private_fields_;
1446 : bool allow_harmony_private_methods_;
1447 : bool allow_eval_cache_;
1448 : };
1449 :
1450 : template <typename Impl>
1451 : ParserBase<Impl>::FunctionState::FunctionState(
1452 : FunctionState** function_state_stack, Scope** scope_stack,
1453 : DeclarationScope* scope)
1454 : : BlockState(scope_stack, scope),
1455 : expected_property_count_(0),
1456 : suspend_count_(0),
1457 : function_state_stack_(function_state_stack),
1458 : outer_function_state_(*function_state_stack),
1459 : scope_(scope),
1460 : dont_optimize_reason_(BailoutReason::kNoReason),
1461 : next_function_is_likely_called_(false),
1462 : previous_function_was_likely_called_(false),
1463 11112051 : contains_function_or_eval_(false) {
1464 11112051 : *function_state_stack = this;
1465 11112051 : if (outer_function_state_) {
1466 5595080 : outer_function_state_->previous_function_was_likely_called_ =
1467 : outer_function_state_->next_function_is_likely_called_;
1468 5595080 : outer_function_state_->next_function_is_likely_called_ = false;
1469 : }
1470 : }
1471 :
1472 : template <typename Impl>
1473 : ParserBase<Impl>::FunctionState::~FunctionState() {
1474 11112043 : *function_state_stack_ = outer_function_state_;
1475 11112043 : }
1476 :
1477 : template <typename Impl>
1478 3539410 : void ParserBase<Impl>::ReportUnexpectedToken(Token::Value token) {
1479 5433978 : return impl()->ReportUnexpectedTokenAt(scanner_->location(), token);
1480 : }
1481 :
1482 : template <typename Impl>
1483 : typename ParserBase<Impl>::IdentifierT
1484 : ParserBase<Impl>::ParseAndClassifyIdentifier(Token::Value next) {
1485 : DCHECK_EQ(scanner()->current_token(), next);
1486 146730084 : if (V8_LIKELY(IsInRange(next, Token::IDENTIFIER, Token::ASYNC))) {
1487 40440126 : IdentifierT name = impl()->GetIdentifier();
1488 73267740 : if (V8_UNLIKELY(impl()->IsArguments(name) &&
1489 : scope()->ShouldBanArguments())) {
1490 5600 : ReportMessage(MessageTemplate::kArgumentsDisallowedInInitializer);
1491 : return impl()->EmptyIdentifierString();
1492 : }
1493 40440249 : return name;
1494 : }
1495 :
1496 297480 : if (!Token::IsValidIdentifier(next, language_mode(), is_generator(),
1497 100618 : parsing_module_ || is_async_function())) {
1498 34495 : ReportUnexpectedToken(next);
1499 : return impl()->EmptyIdentifierString();
1500 : }
1501 :
1502 66123 : if (next == Token::AWAIT) {
1503 : expression_scope()->RecordAsyncArrowParametersError(
1504 : scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
1505 15650 : return impl()->GetIdentifier();
1506 : }
1507 :
1508 : DCHECK(Token::IsStrictReservedWord(next));
1509 43742 : expression_scope()->RecordStrictModeParameterError(
1510 : scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
1511 27068 : return impl()->GetIdentifier();
1512 : }
1513 :
1514 : template <class Impl>
1515 : typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier(
1516 : FunctionKind function_kind) {
1517 : Token::Value next = Next();
1518 :
1519 8548058 : if (!Token::IsValidIdentifier(
1520 : next, language_mode(), IsGeneratorFunction(function_kind),
1521 2862703 : parsing_module_ || IsAsyncFunction(function_kind))) {
1522 8647 : ReportUnexpectedToken(next);
1523 : return impl()->EmptyIdentifierString();
1524 : }
1525 :
1526 690433 : return impl()->GetIdentifier();
1527 : }
1528 :
1529 : template <typename Impl>
1530 : typename ParserBase<Impl>::IdentifierT
1531 362157 : ParserBase<Impl>::ParseNonRestrictedIdentifier() {
1532 : IdentifierT result = ParseIdentifier();
1533 :
1534 378874 : if (is_strict(language_mode()) &&
1535 16710 : V8_UNLIKELY(impl()->IsEvalOrArguments(result))) {
1536 286 : impl()->ReportMessageAt(scanner()->location(),
1537 : MessageTemplate::kStrictEvalArguments);
1538 : }
1539 :
1540 362164 : return result;
1541 : }
1542 :
1543 : template <typename Impl>
1544 : typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParsePropertyName() {
1545 : Token::Value next = Next();
1546 6280926 : if (V8_LIKELY(Token::IsPropertyName(next))) {
1547 2985852 : if (peek() == Token::COLON) return impl()->GetSymbol();
1548 220390 : return impl()->GetIdentifier();
1549 : }
1550 :
1551 154611 : ReportUnexpectedToken(next);
1552 : return impl()->EmptyIdentifierString();
1553 : }
1554 :
1555 : template <typename Impl>
1556 : typename ParserBase<Impl>::ExpressionT
1557 14817887 : ParserBase<Impl>::ParsePropertyOrPrivatePropertyName() {
1558 : int pos = position();
1559 : IdentifierT name;
1560 : ExpressionT key;
1561 : Token::Value next = Next();
1562 14817723 : if (V8_LIKELY(Token::IsPropertyName(next))) {
1563 : name = impl()->GetSymbol();
1564 : key = factory()->NewStringLiteral(name, pos);
1565 15264 : } else if (allow_harmony_private_fields() && next == Token::PRIVATE_NAME) {
1566 : // In the case of a top level function, we completely skip
1567 : // analysing it's scope, meaning, we don't have a chance to
1568 : // resolve private names and find that they are not enclosed in a
1569 : // class body.
1570 : //
1571 : // Here, we check if this is a new private name reference in a top
1572 : // level function and throw an error if so.
1573 : //
1574 : // Bug(v8:7468): This hack will go away once we refactor private
1575 : // name resolution to happen independently from scope resolution.
1576 6177 : if (scope()->scope_type() == FUNCTION_SCOPE &&
1577 : scope()->outer_scope() != nullptr &&
1578 : scope()->outer_scope()->scope_type() == SCRIPT_SCOPE) {
1579 0 : ReportMessage(MessageTemplate::kInvalidPrivateFieldResolution);
1580 : }
1581 :
1582 3601 : name = impl()->GetIdentifier();
1583 : key = impl()->ExpressionFromIdentifier(name, pos, InferName::kNo);
1584 : } else {
1585 9087 : ReportUnexpectedToken(next);
1586 9087 : return impl()->FailureExpression();
1587 : }
1588 : impl()->PushLiteralName(name);
1589 14808683 : return key;
1590 : }
1591 :
1592 : template <typename Impl>
1593 79616 : typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral() {
1594 : int pos = peek_position();
1595 79616 : if (!scanner()->ScanRegExpPattern()) {
1596 : Next();
1597 279 : ReportMessage(MessageTemplate::kUnterminatedRegExp);
1598 279 : return impl()->FailureExpression();
1599 : }
1600 :
1601 : IdentifierT js_pattern = impl()->GetNextSymbol();
1602 79339 : Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags();
1603 79340 : if (flags.IsNothing()) {
1604 : Next();
1605 610 : ReportMessage(MessageTemplate::kMalformedRegExpFlags);
1606 610 : return impl()->FailureExpression();
1607 : }
1608 48779 : int js_flags = flags.FromJust();
1609 : Next();
1610 48778 : return factory()->NewRegExpLiteral(js_pattern, js_flags, pos);
1611 : }
1612 :
1613 : template <typename Impl>
1614 8105867 : typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBindingPattern() {
1615 : // Pattern ::
1616 : // Identifier
1617 : // ArrayLiteral
1618 : // ObjectLiteral
1619 :
1620 : int beg_pos = peek_position();
1621 : Token::Value token = peek();
1622 : ExpressionT result;
1623 :
1624 8105867 : if (Token::IsAnyIdentifier(token)) {
1625 : IdentifierT name = ParseAndClassifyIdentifier(Next());
1626 8505562 : if (V8_UNLIKELY(is_strict(language_mode()) &&
1627 : impl()->IsEvalOrArguments(name))) {
1628 3287 : impl()->ReportMessageAt(scanner()->location(),
1629 : MessageTemplate::kStrictEvalArguments);
1630 3290 : return impl()->FailureExpression();
1631 : }
1632 3896401 : return impl()->ExpressionFromIdentifier(name, beg_pos);
1633 : }
1634 :
1635 277033 : CheckStackOverflow();
1636 :
1637 277033 : if (token == Token::LBRACK) {
1638 57932 : result = ParseArrayLiteral();
1639 219101 : } else if (token == Token::LBRACE) {
1640 172984 : result = ParseObjectLiteral();
1641 : } else {
1642 46117 : ReportUnexpectedToken(Next());
1643 46117 : return impl()->FailureExpression();
1644 : }
1645 :
1646 148519 : return result;
1647 : }
1648 :
1649 : template <typename Impl>
1650 : typename ParserBase<Impl>::ExpressionT
1651 108788320 : ParserBase<Impl>::ParsePrimaryExpression() {
1652 108788320 : CheckStackOverflow();
1653 :
1654 : // PrimaryExpression ::
1655 : // 'this'
1656 : // 'null'
1657 : // 'true'
1658 : // 'false'
1659 : // Identifier
1660 : // Number
1661 : // String
1662 : // ArrayLiteral
1663 : // ObjectLiteral
1664 : // RegExpLiteral
1665 : // ClassLiteral
1666 : // '(' Expression ')'
1667 : // TemplateLiteral
1668 : // do Block
1669 : // AsyncFunctionLiteral
1670 :
1671 : int beg_pos = peek_position();
1672 : Token::Value token = peek();
1673 :
1674 108799030 : if (Token::IsAnyIdentifier(token)) {
1675 : Consume(token);
1676 :
1677 : FunctionKind kind = FunctionKind::kArrowFunction;
1678 :
1679 51595364 : if (V8_UNLIKELY(token == Token::ASYNC &&
1680 : !scanner()->HasLineTerminatorBeforeNext() &&
1681 : !scanner()->literal_contains_escapes())) {
1682 : // async function ...
1683 44091 : if (peek() == Token::FUNCTION) return ParseAsyncFunctionLiteral();
1684 :
1685 : // async Identifier => ...
1686 23382 : if (peek_any_identifier() && PeekAhead() == Token::ARROW) {
1687 : token = Next();
1688 : beg_pos = position();
1689 : kind = FunctionKind::kAsyncArrowFunction;
1690 : }
1691 : }
1692 :
1693 51485696 : if (V8_UNLIKELY(peek() == Token::ARROW)) {
1694 : ArrowHeadParsingScope parsing_scope(impl(), kind);
1695 : IdentifierT name = ParseAndClassifyIdentifier(token);
1696 57932 : ClassifyParameter(name, beg_pos, end_position());
1697 : ExpressionT result =
1698 : impl()->ExpressionFromIdentifier(name, beg_pos, InferName::kNo);
1699 378997 : next_arrow_function_info_.scope = parsing_scope.ValidateAndCreateScope();
1700 321066 : return result;
1701 : }
1702 :
1703 : IdentifierT name = ParseAndClassifyIdentifier(token);
1704 19667826 : return impl()->ExpressionFromIdentifier(name, beg_pos);
1705 : }
1706 :
1707 57289921 : if (Token::IsLiteral(token)) {
1708 24947294 : return impl()->ExpressionFromLiteral(Next(), beg_pos);
1709 : }
1710 :
1711 15382643 : switch (token) {
1712 : case Token::NEW:
1713 549719 : return ParseMemberWithPresentNewPrefixesExpression();
1714 :
1715 : case Token::THIS: {
1716 : Consume(Token::THIS);
1717 2540466 : return impl()->ThisExpression();
1718 : }
1719 :
1720 : case Token::ASSIGN_DIV:
1721 : case Token::DIV:
1722 79617 : return ParseRegExpLiteral();
1723 :
1724 : case Token::FUNCTION:
1725 1940062 : return ParseFunctionExpression();
1726 :
1727 : case Token::SUPER: {
1728 : const bool is_new = false;
1729 21648 : return ParseSuperExpression(is_new);
1730 : }
1731 : case Token::IMPORT:
1732 66784 : if (!allow_harmony_dynamic_import()) break;
1733 31724 : return ParseImportExpressions();
1734 :
1735 : case Token::LBRACK:
1736 1114140 : return ParseArrayLiteral();
1737 :
1738 : case Token::LBRACE:
1739 1182468 : return ParseObjectLiteral();
1740 :
1741 : case Token::LPAREN: {
1742 : Consume(Token::LPAREN);
1743 3496745 : if (Check(Token::RPAREN)) {
1744 : // ()=>x. The continuation that consumes the => is in
1745 : // ParseAssignmentExpressionCoverGrammar.
1746 422343 : if (peek() != Token::ARROW) ReportUnexpectedToken(Token::RPAREN);
1747 422354 : next_arrow_function_info_.scope =
1748 422343 : NewFunctionScope(FunctionKind::kArrowFunction);
1749 261133 : return factory()->NewEmptyParentheses(beg_pos);
1750 : }
1751 3074402 : Scope::Snapshot scope_snapshot(scope());
1752 : ArrowHeadParsingScope maybe_arrow(impl(), FunctionKind::kArrowFunction);
1753 : // Heuristically try to detect immediately called functions before
1754 : // seeing the call parentheses.
1755 3085928 : if (peek() == Token::FUNCTION ||
1756 : (peek() == Token::ASYNC && PeekAhead() == Token::FUNCTION)) {
1757 609845 : function_state_->set_next_function_is_likely_called();
1758 : }
1759 : AcceptINScope scope(this, true);
1760 3074415 : ExpressionT expr = ParseExpressionCoverGrammar();
1761 : expr->mark_parenthesized();
1762 3074439 : Expect(Token::RPAREN);
1763 :
1764 3074419 : if (peek() == Token::ARROW) {
1765 121576 : next_arrow_function_info_.scope = maybe_arrow.ValidateAndCreateScope();
1766 121574 : scope_snapshot.Reparent(next_arrow_function_info_.scope);
1767 : } else {
1768 2952843 : maybe_arrow.ValidateExpression();
1769 : }
1770 :
1771 1906357 : return expr;
1772 : }
1773 :
1774 : case Token::CLASS: {
1775 : Consume(Token::CLASS);
1776 : int class_token_pos = position();
1777 59008 : IdentifierT name = impl()->NullIdentifier();
1778 : bool is_strict_reserved_name = false;
1779 136887 : Scanner::Location class_name_location = Scanner::Location::invalid();
1780 136887 : if (peek_any_identifier()) {
1781 1684 : name = ParseAndClassifyIdentifier(Next());
1782 18069 : class_name_location = scanner()->location();
1783 : is_strict_reserved_name =
1784 : Token::IsStrictReservedWord(scanner()->current_token());
1785 : }
1786 136887 : return ParseClassLiteral(name, class_name_location,
1787 136887 : is_strict_reserved_name, class_token_pos);
1788 : }
1789 :
1790 : case Token::TEMPLATE_SPAN:
1791 : case Token::TEMPLATE_TAIL:
1792 59185 : return ParseTemplateLiteral(impl()->NullExpression(), beg_pos, false);
1793 :
1794 : case Token::MOD:
1795 136211 : if (allow_natives() || extension_ != nullptr) {
1796 136091 : return ParseV8Intrinsic();
1797 : }
1798 : break;
1799 :
1800 : default:
1801 : break;
1802 : }
1803 :
1804 956008 : ReportUnexpectedToken(Next());
1805 956008 : return impl()->FailureExpression();
1806 : }
1807 :
1808 : template <typename Impl>
1809 : typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression() {
1810 30357079 : ExpressionParsingScope expression_scope(impl());
1811 : AcceptINScope scope(this, true);
1812 30047876 : ExpressionT result = ParseExpressionCoverGrammar();
1813 30047749 : expression_scope.ValidateExpression();
1814 12818740 : return result;
1815 : }
1816 :
1817 : template <typename Impl>
1818 : typename ParserBase<Impl>::ExpressionT
1819 : ParserBase<Impl>::ParseAssignmentExpression() {
1820 25517279 : ExpressionParsingScope expression_scope(impl());
1821 24811683 : ExpressionT result = ParseAssignmentExpressionCoverGrammar();
1822 24811340 : expression_scope.ValidateExpression();
1823 4859689 : return result;
1824 : }
1825 :
1826 : template <typename Impl>
1827 : typename ParserBase<Impl>::ExpressionT
1828 37476007 : ParserBase<Impl>::ParseExpressionCoverGrammar() {
1829 : // Expression ::
1830 : // AssignmentExpression
1831 : // Expression ',' AssignmentExpression
1832 :
1833 : ExpressionListT list(pointer_buffer());
1834 : ExpressionT expression;
1835 74950869 : AccumulationScope accumulation_scope(expression_scope());
1836 : while (true) {
1837 40236777 : if (V8_UNLIKELY(peek() == Token::ELLIPSIS)) {
1838 10426 : return ParseArrowParametersWithRest(&list, &accumulation_scope);
1839 : }
1840 :
1841 : int expr_pos = peek_position();
1842 40226351 : expression = ParseAssignmentExpressionCoverGrammar();
1843 :
1844 40224400 : ClassifyArrowParameter(&accumulation_scope, expr_pos, expression);
1845 : list.Add(expression);
1846 :
1847 40225390 : if (!Check(Token::COMMA)) break;
1848 :
1849 2762117 : if (peek() == Token::RPAREN && PeekAhead() == Token::ARROW) {
1850 : // a trailing comma is allowed at the end of an arrow parameter list
1851 : break;
1852 : }
1853 :
1854 : // Pass on the 'set_next_function_is_likely_called' flag if we have
1855 : // several function literals separated by comma.
1856 2761544 : if (peek() == Token::FUNCTION &&
1857 590 : function_state_->previous_function_was_likely_called()) {
1858 16 : function_state_->set_next_function_is_likely_called();
1859 : }
1860 : }
1861 :
1862 : // Return the single element if the list is empty. We need to do this because
1863 : // callers of this function care about the type of the result if there was
1864 : // only a single assignment expression. The preparser would lose this
1865 : // information otherwise.
1866 37464436 : if (list.length() == 1) return expression;
1867 57979 : return impl()->ExpressionListToExpression(list);
1868 : }
1869 :
1870 : template <typename Impl>
1871 : typename ParserBase<Impl>::ExpressionT
1872 10426 : ParserBase<Impl>::ParseArrowParametersWithRest(
1873 : typename ParserBase<Impl>::ExpressionListT* list,
1874 : AccumulationScope* accumulation_scope) {
1875 : Consume(Token::ELLIPSIS);
1876 :
1877 5410 : Scanner::Location ellipsis = scanner()->location();
1878 : int pattern_pos = peek_position();
1879 10426 : ExpressionT pattern = ParseBindingPattern();
1880 10426 : ClassifyArrowParameter(accumulation_scope, pattern_pos, pattern);
1881 :
1882 : expression_scope()->RecordNonSimpleParameter();
1883 :
1884 10426 : if (V8_UNLIKELY(peek() == Token::ASSIGN)) {
1885 152 : ReportMessage(MessageTemplate::kRestDefaultInitializer);
1886 152 : return impl()->FailureExpression();
1887 : }
1888 :
1889 : ExpressionT spread =
1890 : factory()->NewSpread(pattern, ellipsis.beg_pos, pattern_pos);
1891 10274 : if (V8_UNLIKELY(peek() == Token::COMMA)) {
1892 384 : ReportMessage(MessageTemplate::kParamAfterRest);
1893 384 : return impl()->FailureExpression();
1894 : }
1895 :
1896 : // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
1897 : // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
1898 : // valid expression.
1899 18505 : if (peek() != Token::RPAREN || PeekAhead() != Token::ARROW) {
1900 3490 : impl()->ReportUnexpectedTokenAt(ellipsis, Token::ELLIPSIS);
1901 7050 : return impl()->FailureExpression();
1902 : }
1903 :
1904 : list->Add(spread);
1905 1654 : return impl()->ExpressionListToExpression(*list);
1906 : }
1907 :
1908 : template <typename Impl>
1909 1172070 : typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral() {
1910 : // ArrayLiteral ::
1911 : // '[' Expression? (',' Expression?)* ']'
1912 :
1913 : int pos = peek_position();
1914 : ExpressionListT values(pointer_buffer());
1915 : int first_spread_index = -1;
1916 : Consume(Token::LBRACK);
1917 :
1918 2344178 : AccumulationScope accumulation_scope(expression_scope());
1919 :
1920 10797227 : while (!Check(Token::RBRACK)) {
1921 : ExpressionT elem;
1922 9649989 : if (peek() == Token::COMMA) {
1923 : elem = factory()->NewTheHoleLiteral();
1924 7501134 : } else if (Check(Token::ELLIPSIS)) {
1925 : int start_pos = position();
1926 : int expr_pos = peek_position();
1927 : AcceptINScope scope(this, true);
1928 : ExpressionT argument =
1929 37668 : ParsePossibleDestructuringSubPattern(&accumulation_scope);
1930 : elem = factory()->NewSpread(argument, start_pos, expr_pos);
1931 :
1932 18077 : if (first_spread_index < 0) {
1933 : first_spread_index = values.length();
1934 : }
1935 :
1936 37667 : if (argument->IsAssignment()) {
1937 3215 : expression_scope()->RecordPatternError(
1938 : Scanner::Location(start_pos, end_position()),
1939 : MessageTemplate::kInvalidDestructuringTarget);
1940 : }
1941 :
1942 37667 : if (peek() == Token::COMMA) {
1943 5408 : expression_scope()->RecordPatternError(
1944 : Scanner::Location(start_pos, end_position()),
1945 : MessageTemplate::kElementAfterRest);
1946 : }
1947 : } else {
1948 : AcceptINScope scope(this, true);
1949 7463466 : elem = ParsePossibleDestructuringSubPattern(&accumulation_scope);
1950 : }
1951 : values.Add(elem);
1952 9649993 : if (peek() != Token::RBRACK) {
1953 9054391 : Expect(Token::COMMA);
1954 9054384 : if (elem->IsFailureExpression()) return elem;
1955 : }
1956 : }
1957 :
1958 756597 : return factory()->NewArrayLiteral(values, first_spread_index, pos);
1959 : }
1960 :
1961 : template <class Impl>
1962 5540160 : typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseProperty(
1963 : ParsePropertyInfo* prop_info) {
1964 : DCHECK_EQ(prop_info->kind, ParsePropertyKind::kNotSet);
1965 : DCHECK_EQ(prop_info->function_flags, ParseFunctionFlag::kIsNormal);
1966 : DCHECK(!prop_info->is_computed_name);
1967 :
1968 5540166 : if (Check(Token::ASYNC)) {
1969 : Token::Value token = peek();
1970 66036 : if ((token != Token::MUL && prop_info->ParsePropertyKindFromToken(token)) ||
1971 : scanner()->HasLineTerminatorBeforeNext()) {
1972 5520 : prop_info->name = impl()->GetIdentifier();
1973 : impl()->PushLiteralName(prop_info->name);
1974 5520 : return factory()->NewStringLiteral(prop_info->name, position());
1975 : }
1976 29618 : if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
1977 0 : impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
1978 : }
1979 29618 : prop_info->function_flags = ParseFunctionFlag::kIsAsync;
1980 29618 : prop_info->kind = ParsePropertyKind::kMethod;
1981 : }
1982 :
1983 5534646 : if (Check(Token::MUL)) {
1984 : prop_info->function_flags |= ParseFunctionFlag::kIsGenerator;
1985 46624 : prop_info->kind = ParsePropertyKind::kMethod;
1986 : }
1987 :
1988 11002648 : if (prop_info->kind == ParsePropertyKind::kNotSet &&
1989 : IsInRange(peek(), Token::GET, Token::SET)) {
1990 : Token::Value token = Next();
1991 114398 : if (prop_info->ParsePropertyKindFromToken(peek())) {
1992 35856 : prop_info->name = impl()->GetIdentifier();
1993 : impl()->PushLiteralName(prop_info->name);
1994 55004 : return factory()->NewStringLiteral(prop_info->name, position());
1995 : }
1996 78543 : if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
1997 240 : impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
1998 : }
1999 78543 : if (token == Token::GET) {
2000 43644 : prop_info->kind = ParsePropertyKind::kAccessorGetter;
2001 34899 : } else if (token == Token::SET) {
2002 34899 : prop_info->kind = ParsePropertyKind::kAccessorSetter;
2003 : }
2004 : }
2005 :
2006 : int pos = peek_position();
2007 :
2008 : // For non computed property names we normalize the name a bit:
2009 : //
2010 : // "12" -> 12
2011 : // 12.3 -> "12.3"
2012 : // 12.30 -> "12.3"
2013 : // identifier -> "identifier"
2014 : //
2015 : // This is important because we use the property name as a key in a hash
2016 : // table when we compute constant properties.
2017 : bool is_array_index;
2018 : uint32_t index;
2019 5498791 : switch (peek()) {
2020 : case Token::PRIVATE_NAME:
2021 50738 : prop_info->is_private = true;
2022 : is_array_index = false;
2023 : Consume(Token::PRIVATE_NAME);
2024 50738 : if (prop_info->kind == ParsePropertyKind::kNotSet) {
2025 32978 : prop_info->ParsePropertyKindFromToken(peek());
2026 : }
2027 50738 : prop_info->name = impl()->GetIdentifier();
2028 50738 : if (V8_UNLIKELY(prop_info->position ==
2029 : PropertyPosition::kObjectLiteral)) {
2030 1470 : ReportUnexpectedToken(Token::PRIVATE_NAME);
2031 1470 : prop_info->kind = ParsePropertyKind::kNotSet;
2032 1470 : return impl()->FailureExpression();
2033 : }
2034 74376 : if (V8_UNLIKELY(!allow_harmony_private_methods() &&
2035 : (IsAccessor(prop_info->kind) ||
2036 : prop_info->kind == ParsePropertyKind::kMethod))) {
2037 1920 : ReportUnexpectedToken(Next());
2038 1920 : prop_info->kind = ParsePropertyKind::kNotSet;
2039 1920 : return impl()->FailureExpression();
2040 : }
2041 : break;
2042 :
2043 : case Token::STRING:
2044 : Consume(Token::STRING);
2045 141861 : prop_info->name = peek() == Token::COLON ? impl()->GetSymbol()
2046 : : impl()->GetIdentifier();
2047 : is_array_index = impl()->IsArrayIndex(prop_info->name, &index);
2048 90461 : break;
2049 :
2050 : case Token::SMI:
2051 : Consume(Token::SMI);
2052 1448368 : index = scanner()->smi_value();
2053 : is_array_index = true;
2054 : // Token::SMI were scanned from their canonical representation.
2055 2121943 : prop_info->name = impl()->GetSymbol();
2056 2121943 : break;
2057 :
2058 : case Token::NUMBER: {
2059 : Consume(Token::NUMBER);
2060 7225 : prop_info->name = impl()->GetNumberAsSymbol();
2061 : is_array_index = impl()->IsArrayIndex(prop_info->name, &index);
2062 7225 : break;
2063 : }
2064 : case Token::LBRACK: {
2065 66951 : prop_info->name = impl()->NullIdentifier();
2066 66951 : prop_info->is_computed_name = true;
2067 : Consume(Token::LBRACK);
2068 : AcceptINScope scope(this, true);
2069 : ExpressionT expression = ParseAssignmentExpression();
2070 66951 : Expect(Token::RBRACK);
2071 66951 : if (prop_info->kind == ParsePropertyKind::kNotSet) {
2072 61044 : prop_info->ParsePropertyKindFromToken(peek());
2073 : }
2074 34208 : return expression;
2075 : }
2076 :
2077 : case Token::ELLIPSIS:
2078 24543 : if (prop_info->kind == ParsePropertyKind::kNotSet) {
2079 24223 : prop_info->name = impl()->NullIdentifier();
2080 : Consume(Token::ELLIPSIS);
2081 : AcceptINScope scope(this, true);
2082 : int start_pos = peek_position();
2083 : ExpressionT expression =
2084 24223 : ParsePossibleDestructuringSubPattern(prop_info->accumulation_scope);
2085 24223 : prop_info->kind = ParsePropertyKind::kSpread;
2086 :
2087 24223 : if (!IsValidReferenceExpression(expression)) {
2088 8270 : expression_scope()->RecordDeclarationError(
2089 : Scanner::Location(start_pos, end_position()),
2090 : MessageTemplate::kInvalidRestBindingPattern);
2091 8270 : expression_scope()->RecordPatternError(
2092 : Scanner::Location(start_pos, end_position()),
2093 : MessageTemplate::kInvalidRestAssignmentPattern);
2094 : }
2095 :
2096 24223 : if (peek() != Token::RBRACE) {
2097 11749 : expression_scope()->RecordPatternError(
2098 : scanner()->location(), MessageTemplate::kElementAfterRest);
2099 : }
2100 13011 : return expression;
2101 : }
2102 : V8_FALLTHROUGH;
2103 :
2104 : default:
2105 3137240 : prop_info->name = ParsePropertyName();
2106 : is_array_index = false;
2107 3137240 : break;
2108 : }
2109 :
2110 5404217 : if (prop_info->kind == ParsePropertyKind::kNotSet) {
2111 5241594 : prop_info->ParsePropertyKindFromToken(peek());
2112 : }
2113 3492236 : impl()->PushLiteralName(prop_info->name);
2114 3492227 : return is_array_index ? factory()->NewNumberLiteral(index, pos)
2115 6855094 : : factory()->NewStringLiteral(prop_info->name, pos);
2116 : }
2117 :
2118 : template <typename Impl>
2119 : typename ParserBase<Impl>::ClassLiteralPropertyT
2120 626495 : ParserBase<Impl>::ParseClassPropertyDefinition(ClassInfo* class_info,
2121 : ParsePropertyInfo* prop_info,
2122 : bool has_extends) {
2123 : DCHECK_NOT_NULL(class_info);
2124 : DCHECK_EQ(prop_info->position, PropertyPosition::kClassLiteral);
2125 :
2126 : Token::Value name_token = peek();
2127 : DCHECK_IMPLIES(name_token == Token::PRIVATE_NAME,
2128 : allow_harmony_private_fields());
2129 :
2130 626495 : int property_beg_pos = scanner()->peek_location().beg_pos;
2131 : int name_token_position = property_beg_pos;
2132 : ExpressionT name_expression;
2133 626495 : if (name_token == Token::STATIC) {
2134 : Consume(Token::STATIC);
2135 107427 : name_token_position = scanner()->peek_location().beg_pos;
2136 107427 : if (peek() == Token::LPAREN) {
2137 240 : prop_info->kind = ParsePropertyKind::kMethod;
2138 : // TODO(bakkot) specialize on 'static'
2139 240 : prop_info->name = impl()->GetIdentifier();
2140 : name_expression =
2141 : factory()->NewStringLiteral(prop_info->name, position());
2142 107187 : } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON ||
2143 : peek() == Token::RBRACE) {
2144 : // TODO(bakkot) specialize on 'static'
2145 800 : prop_info->name = impl()->GetIdentifier();
2146 : name_expression =
2147 : factory()->NewStringLiteral(prop_info->name, position());
2148 : } else {
2149 106387 : prop_info->is_static = true;
2150 106387 : name_expression = ParseProperty(prop_info);
2151 : }
2152 : } else {
2153 519068 : name_expression = ParseProperty(prop_info);
2154 : }
2155 :
2156 626489 : if (!class_info->has_name_static_property && prop_info->is_static &&
2157 : impl()->IsName(prop_info->name)) {
2158 117 : class_info->has_name_static_property = true;
2159 : }
2160 :
2161 626489 : switch (prop_info->kind) {
2162 : case ParsePropertyKind::kAssign:
2163 : case ParsePropertyKind::kClassField:
2164 : case ParsePropertyKind::kShorthandOrClassField:
2165 : case ParsePropertyKind::kNotSet: // This case is a name followed by a name
2166 : // or other property. Here we have to
2167 : // assume that's an uninitialized field
2168 : // followed by a linebreak followed by a
2169 : // property, with ASI adding the
2170 : // semicolon. If not, there will be a
2171 : // syntax error after parsing the first
2172 : // name as an uninitialized field.
2173 160701 : if (allow_harmony_public_fields() || allow_harmony_private_fields()) {
2174 113641 : prop_info->kind = ParsePropertyKind::kClassField;
2175 : DCHECK_IMPLIES(prop_info->is_computed_name, !prop_info->is_private);
2176 :
2177 113641 : if (prop_info->is_static && !allow_harmony_static_fields()) {
2178 11840 : ReportUnexpectedToken(Next());
2179 11840 : return impl()->NullLiteralProperty();
2180 : }
2181 :
2182 101801 : if (!prop_info->is_computed_name) {
2183 91868 : CheckClassFieldName(prop_info->name, prop_info->is_static);
2184 : }
2185 :
2186 101801 : ExpressionT initializer = ParseMemberInitializer(
2187 101801 : class_info, property_beg_pos, prop_info->is_static);
2188 101801 : ExpectSemicolon();
2189 :
2190 : ClassLiteralPropertyT result = factory()->NewClassLiteralProperty(
2191 : name_expression, initializer, ClassLiteralProperty::FIELD,
2192 : prop_info->is_static, prop_info->is_computed_name,
2193 52169 : prop_info->is_private);
2194 52169 : impl()->SetFunctionNameFromPropertyName(result, prop_info->name);
2195 :
2196 101801 : return result;
2197 :
2198 : } else {
2199 47060 : ReportUnexpectedToken(Next());
2200 47060 : return impl()->NullLiteralProperty();
2201 : }
2202 :
2203 : case ParsePropertyKind::kMethod: {
2204 : // MethodDefinition
2205 : // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2206 : // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2207 : // async PropertyName '(' StrictFormalParameters ')'
2208 : // '{' FunctionBody '}'
2209 : // async '*' PropertyName '(' StrictFormalParameters ')'
2210 : // '{' FunctionBody '}'
2211 :
2212 419286 : if (!prop_info->is_computed_name) {
2213 411554 : CheckClassMethodName(prop_info->name, ParsePropertyKind::kMethod,
2214 : prop_info->function_flags, prop_info->is_static,
2215 : &class_info->has_seen_constructor);
2216 : }
2217 :
2218 : FunctionKind kind = MethodKindFor(prop_info->function_flags);
2219 :
2220 419284 : if (!prop_info->is_static && impl()->IsConstructor(prop_info->name)) {
2221 23295 : class_info->has_seen_constructor = true;
2222 23295 : kind = has_extends ? FunctionKind::kDerivedConstructor
2223 : : FunctionKind::kBaseConstructor;
2224 : }
2225 :
2226 : ExpressionT value = impl()->ParseFunctionLiteral(
2227 : prop_info->name, scanner()->location(), kSkipFunctionNameCheck, kind,
2228 : name_token_position, FunctionLiteral::kAccessorOrMethod,
2229 838568 : language_mode(), nullptr);
2230 :
2231 : ClassLiteralPropertyT result = factory()->NewClassLiteralProperty(
2232 : name_expression, value, ClassLiteralProperty::METHOD,
2233 : prop_info->is_static, prop_info->is_computed_name,
2234 376497 : prop_info->is_private);
2235 376495 : impl()->SetFunctionNameFromPropertyName(result, prop_info->name);
2236 419292 : return result;
2237 : }
2238 :
2239 : case ParsePropertyKind::kAccessorGetter:
2240 : case ParsePropertyKind::kAccessorSetter: {
2241 : DCHECK_EQ(prop_info->function_flags, ParseFunctionFlag::kIsNormal);
2242 : bool is_get = prop_info->kind == ParsePropertyKind::kAccessorGetter;
2243 :
2244 44958 : if (!prop_info->is_computed_name) {
2245 82754 : CheckClassMethodName(prop_info->name, prop_info->kind,
2246 : ParseFunctionFlag::kIsNormal, prop_info->is_static,
2247 : &class_info->has_seen_constructor);
2248 : // Make sure the name expression is a string since we need a Name for
2249 : // Runtime_DefineAccessorPropertyUnchecked and since we can determine
2250 : // this statically we can skip the extra runtime check.
2251 22642 : name_expression = factory()->NewStringLiteral(
2252 : prop_info->name, name_expression->position());
2253 : }
2254 :
2255 : FunctionKind kind = is_get ? FunctionKind::kGetterFunction
2256 44958 : : FunctionKind::kSetterFunction;
2257 :
2258 : FunctionLiteralT value = impl()->ParseFunctionLiteral(
2259 : prop_info->name, scanner()->location(), kSkipFunctionNameCheck, kind,
2260 : name_token_position, FunctionLiteral::kAccessorOrMethod,
2261 89916 : language_mode(), nullptr);
2262 :
2263 : ClassLiteralProperty::Kind property_kind =
2264 25789 : is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER;
2265 : ClassLiteralPropertyT result = factory()->NewClassLiteralProperty(
2266 : name_expression, value, property_kind, prop_info->is_static,
2267 25789 : prop_info->is_computed_name, prop_info->is_private);
2268 : const AstRawString* prefix =
2269 : is_get ? ast_value_factory()->get_space_string()
2270 25789 : : ast_value_factory()->set_space_string();
2271 25789 : impl()->SetFunctionNameFromPropertyName(result, prop_info->name, prefix);
2272 44958 : return result;
2273 : }
2274 : case ParsePropertyKind::kValue:
2275 : case ParsePropertyKind::kShorthand:
2276 : case ParsePropertyKind::kSpread:
2277 1568 : impl()->ReportUnexpectedTokenAt(
2278 : Scanner::Location(name_token_position, name_expression->position()),
2279 : name_token);
2280 1544 : return impl()->NullLiteralProperty();
2281 : }
2282 0 : UNREACHABLE();
2283 : }
2284 :
2285 : template <typename Impl>
2286 101801 : typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberInitializer(
2287 : ClassInfo* class_info, int beg_pos, bool is_static) {
2288 : DeclarationScope* initializer_scope =
2289 : is_static ? class_info->static_fields_scope
2290 101801 : : class_info->instance_members_scope;
2291 :
2292 101801 : if (initializer_scope == nullptr) {
2293 93137 : initializer_scope =
2294 : NewFunctionScope(FunctionKind::kClassMembersInitializerFunction);
2295 : // TODO(gsathya): Make scopes be non contiguous.
2296 : initializer_scope->set_start_position(beg_pos);
2297 : initializer_scope->SetLanguageMode(LanguageMode::kStrict);
2298 : }
2299 :
2300 : ExpressionT initializer;
2301 101801 : if (Check(Token::ASSIGN)) {
2302 : FunctionState initializer_state(&function_state_, &scope_,
2303 32941 : initializer_scope);
2304 :
2305 : AcceptINScope scope(this, true);
2306 : initializer = ParseAssignmentExpression();
2307 : } else {
2308 : initializer = factory()->NewUndefinedLiteral(kNoSourcePosition);
2309 : }
2310 :
2311 : initializer_scope->set_end_position(end_position());
2312 101801 : if (is_static) {
2313 40481 : class_info->static_fields_scope = initializer_scope;
2314 40481 : class_info->has_static_class_fields = true;
2315 : } else {
2316 61320 : class_info->instance_members_scope = initializer_scope;
2317 61320 : class_info->has_instance_members = true;
2318 : }
2319 :
2320 101801 : return initializer;
2321 : }
2322 :
2323 : template <typename Impl>
2324 : typename ParserBase<Impl>::ObjectLiteralPropertyT
2325 4914695 : ParserBase<Impl>::ParseObjectPropertyDefinition(ParsePropertyInfo* prop_info,
2326 : bool* has_seen_proto) {
2327 : DCHECK_EQ(prop_info->position, PropertyPosition::kObjectLiteral);
2328 : Token::Value name_token = peek();
2329 4914695 : Scanner::Location next_loc = scanner()->peek_location();
2330 :
2331 4914695 : ExpressionT name_expression = ParseProperty(prop_info);
2332 :
2333 : DCHECK_IMPLIES(name_token == Token::PRIVATE_NAME, has_error());
2334 :
2335 4914688 : IdentifierT name = prop_info->name;
2336 4914688 : ParseFunctionFlags function_flags = prop_info->function_flags;
2337 4914688 : ParsePropertyKind kind = prop_info->kind;
2338 :
2339 4914688 : switch (prop_info->kind) {
2340 : case ParsePropertyKind::kSpread:
2341 : DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2342 : DCHECK(!prop_info->is_computed_name);
2343 : DCHECK_EQ(Token::ELLIPSIS, name_token);
2344 :
2345 24199 : prop_info->is_computed_name = true;
2346 24199 : prop_info->is_rest = true;
2347 :
2348 : return factory()->NewObjectLiteralProperty(
2349 : factory()->NewTheHoleLiteral(), name_expression,
2350 11188 : ObjectLiteralProperty::SPREAD, true);
2351 :
2352 : case ParsePropertyKind::kValue: {
2353 : DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2354 :
2355 4513680 : if (!prop_info->is_computed_name &&
2356 : scanner()->CurrentLiteralEquals("__proto__")) {
2357 9411 : if (*has_seen_proto) {
2358 : expression_scope()->RecordExpressionError(
2359 : scanner()->location(), MessageTemplate::kDuplicateProto);
2360 : }
2361 9411 : *has_seen_proto = true;
2362 : }
2363 : Consume(Token::COLON);
2364 : AcceptINScope scope(this, true);
2365 : ExpressionT value =
2366 4513685 : ParsePossibleDestructuringSubPattern(prop_info->accumulation_scope);
2367 :
2368 : ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2369 5817356 : name_expression, value, prop_info->is_computed_name);
2370 2908665 : impl()->SetFunctionNameFromPropertyName(result, name);
2371 1605016 : return result;
2372 : }
2373 :
2374 : case ParsePropertyKind::kAssign:
2375 : case ParsePropertyKind::kShorthandOrClassField:
2376 : case ParsePropertyKind::kShorthand: {
2377 : // PropertyDefinition
2378 : // IdentifierReference
2379 : // CoverInitializedName
2380 : //
2381 : // CoverInitializedName
2382 : // IdentifierReference Initializer?
2383 : DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2384 :
2385 610707 : if (!Token::IsValidIdentifier(name_token, language_mode(), is_generator(),
2386 204841 : parsing_module_ || is_async_function())) {
2387 8107 : ReportUnexpectedToken(Next());
2388 8107 : return impl()->NullLiteralProperty();
2389 : }
2390 :
2391 : DCHECK(!prop_info->is_computed_name);
2392 :
2393 196733 : if (name_token == Token::AWAIT) {
2394 : DCHECK(!is_async_function());
2395 : expression_scope()->RecordAsyncArrowParametersError(
2396 : next_loc, MessageTemplate::kAwaitBindingIdentifier);
2397 : }
2398 : ExpressionT lhs =
2399 196733 : impl()->ExpressionFromIdentifier(name, next_loc.beg_pos);
2400 196733 : if (!IsAssignableIdentifier(lhs)) {
2401 1140 : expression_scope()->RecordPatternError(
2402 : next_loc, MessageTemplate::kStrictEvalArguments);
2403 : }
2404 :
2405 : ExpressionT value;
2406 196734 : if (peek() == Token::ASSIGN) {
2407 : Consume(Token::ASSIGN);
2408 : {
2409 : AcceptINScope scope(this, true);
2410 : ExpressionT rhs = ParseAssignmentExpression();
2411 13135 : value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
2412 : kNoSourcePosition);
2413 13135 : impl()->SetFunctionNameFromIdentifierRef(rhs, lhs);
2414 : }
2415 30936 : expression_scope()->RecordExpressionError(
2416 : Scanner::Location(next_loc.beg_pos, end_position()),
2417 : MessageTemplate::kInvalidCoverInitializedName);
2418 : } else {
2419 : value = lhs;
2420 : }
2421 :
2422 : ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2423 : name_expression, value, ObjectLiteralProperty::COMPUTED, false);
2424 72206 : impl()->SetFunctionNameFromPropertyName(result, name);
2425 196735 : return result;
2426 : }
2427 :
2428 : case ParsePropertyKind::kMethod: {
2429 : // MethodDefinition
2430 : // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2431 : // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2432 :
2433 119522 : expression_scope()->RecordPatternError(
2434 : Scanner::Location(next_loc.beg_pos, end_position()),
2435 : MessageTemplate::kInvalidDestructuringTarget);
2436 :
2437 : FunctionKind kind = MethodKindFor(function_flags);
2438 :
2439 : ExpressionT value = impl()->ParseFunctionLiteral(
2440 : name, scanner()->location(), kSkipFunctionNameCheck, kind,
2441 : next_loc.beg_pos, FunctionLiteral::kAccessorOrMethod, language_mode(),
2442 119520 : nullptr);
2443 :
2444 : ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2445 : name_expression, value, ObjectLiteralProperty::COMPUTED,
2446 34219 : prop_info->is_computed_name);
2447 34219 : impl()->SetFunctionNameFromPropertyName(result, name);
2448 59761 : return result;
2449 : }
2450 :
2451 : case ParsePropertyKind::kAccessorGetter:
2452 : case ParsePropertyKind::kAccessorSetter: {
2453 : DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
2454 : bool is_get = kind == ParsePropertyKind::kAccessorGetter;
2455 :
2456 65250 : expression_scope()->RecordPatternError(
2457 : Scanner::Location(next_loc.beg_pos, end_position()),
2458 : MessageTemplate::kInvalidDestructuringTarget);
2459 :
2460 19933 : if (!prop_info->is_computed_name) {
2461 : // Make sure the name expression is a string since we need a Name for
2462 : // Runtime_DefineAccessorPropertyUnchecked and since we can determine
2463 : // this statically we can skip the extra runtime check.
2464 : name_expression =
2465 : factory()->NewStringLiteral(name, name_expression->position());
2466 : }
2467 :
2468 : FunctionKind kind = is_get ? FunctionKind::kGetterFunction
2469 32625 : : FunctionKind::kSetterFunction;
2470 :
2471 : FunctionLiteralT value = impl()->ParseFunctionLiteral(
2472 : name, scanner()->location(), kSkipFunctionNameCheck, kind,
2473 : next_loc.beg_pos, FunctionLiteral::kAccessorOrMethod, language_mode(),
2474 65250 : nullptr);
2475 :
2476 : ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty(
2477 : name_expression, value,
2478 : is_get ? ObjectLiteralProperty::GETTER
2479 : : ObjectLiteralProperty::SETTER,
2480 19933 : prop_info->is_computed_name);
2481 : const AstRawString* prefix =
2482 : is_get ? ast_value_factory()->get_space_string()
2483 19933 : : ast_value_factory()->set_space_string();
2484 19933 : impl()->SetFunctionNameFromPropertyName(result, name, prefix);
2485 32625 : return result;
2486 : }
2487 :
2488 : case ParsePropertyKind::kClassField:
2489 : case ParsePropertyKind::kNotSet:
2490 79582 : ReportUnexpectedToken(Next());
2491 79582 : return impl()->NullLiteralProperty();
2492 : }
2493 0 : UNREACHABLE();
2494 : }
2495 :
2496 : template <typename Impl>
2497 1355446 : typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral() {
2498 : // ObjectLiteral ::
2499 : // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2500 :
2501 : int pos = peek_position();
2502 : ObjectPropertyListT properties(pointer_buffer());
2503 : int number_of_boilerplate_properties = 0;
2504 :
2505 : bool has_computed_names = false;
2506 : bool has_rest_property = false;
2507 1355446 : bool has_seen_proto = false;
2508 :
2509 : Consume(Token::LBRACE);
2510 2710908 : AccumulationScope accumulation_scope(expression_scope());
2511 :
2512 7963244 : while (!Check(Token::RBRACE)) {
2513 3084086 : FuncNameInferrerState fni_state(&fni_);
2514 :
2515 : ParsePropertyInfo prop_info(this, &accumulation_scope);
2516 4914697 : prop_info.position = PropertyPosition::kObjectLiteral;
2517 : ObjectLiteralPropertyT property =
2518 4914697 : ParseObjectPropertyDefinition(&prop_info, &has_seen_proto);
2519 4914663 : if (impl()->IsNull(property)) return impl()->FailureExpression();
2520 :
2521 3046191 : if (prop_info.is_computed_name) {
2522 : has_computed_names = true;
2523 : }
2524 :
2525 4826974 : if (prop_info.is_rest) {
2526 : has_rest_property = true;
2527 : }
2528 :
2529 3046191 : if (impl()->IsBoilerplateProperty(property) && !has_computed_names) {
2530 : // Count CONSTANT or COMPUTED properties to maintain the enumeration
2531 : // order.
2532 3011508 : number_of_boilerplate_properties++;
2533 : }
2534 :
2535 : properties.Add(property);
2536 :
2537 4826972 : if (peek() != Token::RBRACE) {
2538 3910801 : Expect(Token::COMMA);
2539 : }
2540 :
2541 : fni_.Infer();
2542 : }
2543 :
2544 : // In pattern rewriter, we rewrite rest property to call out to a
2545 : // runtime function passing all the other properties as arguments to
2546 : // this runtime function. Here, we make sure that the number of
2547 : // properties is less than number of arguments allowed for a runtime
2548 : // call.
2549 1273991 : if (has_rest_property && properties.length() > Code::kMaxArguments) {
2550 20 : expression_scope()->RecordPatternError(Scanner::Location(pos, position()),
2551 : MessageTemplate::kTooManyArguments);
2552 : }
2553 :
2554 : return impl()->InitializeObjectLiteral(factory()->NewObjectLiteral(
2555 1773181 : properties, number_of_boilerplate_properties, pos, has_rest_property));
2556 : }
2557 :
2558 : template <typename Impl>
2559 13905249 : void ParserBase<Impl>::ParseArguments(
2560 : typename ParserBase<Impl>::ExpressionListT* args, bool* has_spread,
2561 : ParsingArrowHeadFlag maybe_arrow) {
2562 : // Arguments ::
2563 : // '(' (AssignmentExpression)*[','] ')'
2564 :
2565 13905249 : *has_spread = false;
2566 : Consume(Token::LPAREN);
2567 27810510 : AccumulationScope accumulation_scope(expression_scope());
2568 :
2569 23697114 : while (peek() != Token::RPAREN) {
2570 : int start_pos = peek_position();
2571 : bool is_spread = Check(Token::ELLIPSIS);
2572 : int expr_pos = peek_position();
2573 :
2574 : AcceptINScope scope(this, true);
2575 19567508 : ExpressionT argument = ParseAssignmentExpressionCoverGrammar();
2576 :
2577 19567319 : if (V8_UNLIKELY(maybe_arrow == kMaybeArrowHead)) {
2578 9047 : ClassifyArrowParameter(&accumulation_scope, expr_pos, argument);
2579 9047 : if (is_spread) {
2580 : expression_scope()->RecordNonSimpleParameter();
2581 456 : if (argument->IsAssignment()) {
2582 : expression_scope()->RecordAsyncArrowParametersError(
2583 : scanner()->location(), MessageTemplate::kRestDefaultInitializer);
2584 : }
2585 456 : if (peek() == Token::COMMA) {
2586 : expression_scope()->RecordAsyncArrowParametersError(
2587 : scanner()->peek_location(), MessageTemplate::kParamAfterRest);
2588 : }
2589 : }
2590 : }
2591 19567319 : if (is_spread) {
2592 12416 : *has_spread = true;
2593 : argument = factory()->NewSpread(argument, start_pos, expr_pos);
2594 : }
2595 : args->Add(argument);
2596 19568725 : if (!Check(Token::COMMA)) break;
2597 : }
2598 :
2599 13905010 : if (args->length() > Code::kMaxArguments) {
2600 29 : ReportMessage(MessageTemplate::kTooManyArguments);
2601 29 : return;
2602 : }
2603 :
2604 13904981 : Scanner::Location location = scanner_->location();
2605 13905006 : if (!Check(Token::RPAREN)) {
2606 9920 : impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList);
2607 : }
2608 : }
2609 :
2610 : // Precedence = 2
2611 : template <typename Impl>
2612 : typename ParserBase<Impl>::ExpressionT
2613 96675719 : ParserBase<Impl>::ParseAssignmentExpressionCoverGrammar() {
2614 : // AssignmentExpression ::
2615 : // ConditionalExpression
2616 : // ArrowFunction
2617 : // YieldExpression
2618 : // LeftHandSideExpression AssignmentOperator AssignmentExpression
2619 : int lhs_beg_pos = peek_position();
2620 :
2621 96730474 : if (peek() == Token::YIELD && is_generator()) {
2622 43479 : return ParseYieldExpression();
2623 : }
2624 :
2625 49837406 : FuncNameInferrerState fni_state(&fni_);
2626 :
2627 : DCHECK_IMPLIES(!has_error(), next_arrow_function_info_.HasInitialState());
2628 :
2629 : ExpressionT expression = ParseConditionalExpression();
2630 :
2631 : Token::Value op = peek();
2632 :
2633 96629445 : if (!Token::IsArrowOrAssignmentOp(op)) return expression;
2634 :
2635 : // Arrow functions.
2636 12568949 : if (V8_UNLIKELY(op == Token::ARROW)) {
2637 : Scanner::Location loc(lhs_beg_pos, end_position());
2638 :
2639 1414291 : if (!impl()->IsIdentifier(expression) && !expression->is_parenthesized()) {
2640 12834 : impl()->ReportMessageAt(
2641 : Scanner::Location(expression->position(), position()),
2642 : MessageTemplate::kMalformedArrowFunParamList);
2643 12834 : return impl()->FailureExpression();
2644 : }
2645 :
2646 905025 : DeclarationScope* scope = next_arrow_function_info_.scope;
2647 : scope->set_start_position(lhs_beg_pos);
2648 :
2649 : FormalParametersT parameters(scope);
2650 360266 : parameters.set_strict_parameter_error(
2651 : next_arrow_function_info_.strict_parameter_error_location,
2652 : next_arrow_function_info_.strict_parameter_error_message);
2653 905025 : parameters.is_simple = scope->has_simple_parameters();
2654 : next_arrow_function_info_.Reset();
2655 :
2656 360266 : impl()->DeclareArrowFunctionFormalParameters(¶meters, expression, loc);
2657 :
2658 905028 : expression = ParseArrowFunctionLiteral(parameters);
2659 :
2660 905018 : return expression;
2661 : }
2662 :
2663 11651090 : if (V8_LIKELY(impl()->IsAssignableIdentifier(expression))) {
2664 3259544 : if (expression->is_parenthesized()) {
2665 2273 : expression_scope()->RecordDeclarationError(
2666 : Scanner::Location(lhs_beg_pos, end_position()),
2667 : MessageTemplate::kInvalidDestructuringTarget);
2668 : }
2669 : expression_scope()->MarkIdentifierAsAssigned();
2670 8391522 : } else if (expression->IsProperty()) {
2671 8191119 : expression_scope()->RecordDeclarationError(
2672 : Scanner::Location(lhs_beg_pos, end_position()),
2673 : MessageTemplate::kInvalidPropertyBindingPattern);
2674 200403 : } else if (expression->IsPattern() && op == Token::ASSIGN) {
2675 : // Destructuring assignmment.
2676 189872 : if (expression->is_parenthesized()) {
2677 : Scanner::Location loc(lhs_beg_pos, end_position());
2678 1725 : if (expression_scope()->IsCertainlyDeclaration()) {
2679 18 : impl()->ReportMessageAt(loc,
2680 : MessageTemplate::kInvalidDestructuringTarget);
2681 : } else {
2682 : // Reference Error if LHS is neither object literal nor an array literal
2683 : // (Parenthesized literals are
2684 : // CoverParenthesizedExpressionAndArrowParameterList).
2685 : // #sec-assignment-operators-static-semantics-early-errors
2686 1707 : impl()->ReportMessageAt(loc, MessageTemplate::kInvalidLhsInAssignment,
2687 : static_cast<const char*>(nullptr),
2688 : kReferenceError);
2689 : }
2690 : }
2691 : expression_scope()->ValidateAsPattern(expression, lhs_beg_pos,
2692 : end_position());
2693 : } else {
2694 : DCHECK(!IsValidReferenceExpression(expression));
2695 10531 : expression = RewriteInvalidReferenceExpression(
2696 : expression, lhs_beg_pos, end_position(),
2697 : MessageTemplate::kInvalidLhsInAssignment);
2698 : }
2699 :
2700 : Consume(op);
2701 : int op_position = position();
2702 :
2703 : ExpressionT right = ParseAssignmentExpression();
2704 :
2705 11650882 : if (op == Token::ASSIGN) {
2706 : // We try to estimate the set of properties set by constructors. We define a
2707 : // new property whenever there is an assignment to a property of 'this'. We
2708 : // should probably only add properties if we haven't seen them before.
2709 : // Otherwise we'll probably overestimate the number of properties.
2710 11194138 : if (impl()->IsThisProperty(expression)) function_state_->AddProperty();
2711 :
2712 : impl()->CheckAssigningFunctionLiteralToProperty(expression, right);
2713 :
2714 : // Check if the right hand side is a call to avoid inferring a
2715 : // name if we're dealing with "a = function(){...}();"-like
2716 : // expression.
2717 5620330 : if (right->IsCall() || right->IsCallNew()) {
2718 : fni_.RemoveLastFunction();
2719 : } else {
2720 : fni_.Infer();
2721 : }
2722 :
2723 5620325 : impl()->SetFunctionNameFromIdentifierRef(right, expression);
2724 : } else {
2725 456744 : expression_scope()->RecordPatternError(
2726 : Scanner::Location(lhs_beg_pos, end_position()),
2727 : MessageTemplate::kInvalidDestructuringTarget);
2728 : fni_.RemoveLastFunction();
2729 : }
2730 :
2731 11451308 : return factory()->NewAssignment(op, expression, right, op_position);
2732 : }
2733 :
2734 : template <typename Impl>
2735 : typename ParserBase<Impl>::ExpressionT
2736 43479 : ParserBase<Impl>::ParseYieldExpression() {
2737 : // YieldExpression ::
2738 : // 'yield' ([no line terminator] '*'? AssignmentExpression)?
2739 : int pos = peek_position();
2740 43479 : expression_scope()->RecordParameterInitializerError(
2741 : scanner()->peek_location(), MessageTemplate::kYieldInParameter);
2742 : Consume(Token::YIELD);
2743 43479 : if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
2744 240 : impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
2745 : }
2746 :
2747 43479 : CheckStackOverflow();
2748 :
2749 : // The following initialization is necessary.
2750 : ExpressionT expression = impl()->NullExpression();
2751 : bool delegating = false; // yield*
2752 43479 : if (!scanner()->HasLineTerminatorBeforeNext()) {
2753 41626 : if (Check(Token::MUL)) delegating = true;
2754 : switch (peek()) {
2755 : case Token::EOS:
2756 : case Token::SEMICOLON:
2757 : case Token::RBRACE:
2758 : case Token::RBRACK:
2759 : case Token::RPAREN:
2760 : case Token::COLON:
2761 : case Token::COMMA:
2762 : case Token::IN:
2763 : // The above set of tokens is the complete set of tokens that can appear
2764 : // after an AssignmentExpression, and none of them can start an
2765 : // AssignmentExpression. This allows us to avoid looking for an RHS for
2766 : // a regular yield, given only one look-ahead token.
2767 11870 : if (!delegating) break;
2768 : // Delegating yields require an RHS; fall through.
2769 : V8_FALLTHROUGH;
2770 : default:
2771 30156 : expression = ParseAssignmentExpressionCoverGrammar();
2772 30156 : break;
2773 : }
2774 : }
2775 :
2776 43479 : if (delegating) {
2777 : ExpressionT yieldstar = factory()->NewYieldStar(expression, pos);
2778 : impl()->RecordSuspendSourceRange(yieldstar, PositionAfterSemicolon());
2779 5481 : function_state_->AddSuspend();
2780 10962 : if (IsAsyncGeneratorFunction(function_state_->kind())) {
2781 : // iterator_close and delegated_iterator_output suspend ids.
2782 2781 : function_state_->AddSuspend();
2783 2781 : function_state_->AddSuspend();
2784 : }
2785 3268 : return yieldstar;
2786 : }
2787 :
2788 : // Hackily disambiguate o from o.next and o [Symbol.iterator]().
2789 : // TODO(verwaest): Come up with a better solution.
2790 : ExpressionT yield =
2791 17893 : factory()->NewYield(expression, pos, Suspend::kOnExceptionThrow);
2792 : impl()->RecordSuspendSourceRange(yield, PositionAfterSemicolon());
2793 37998 : function_state_->AddSuspend();
2794 37998 : return yield;
2795 : }
2796 :
2797 : // Precedence = 3
2798 : template <typename Impl>
2799 : typename ParserBase<Impl>::ExpressionT
2800 : ParserBase<Impl>::ParseConditionalExpression() {
2801 : // ConditionalExpression ::
2802 : // LogicalOrExpression
2803 : // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2804 :
2805 : int pos = peek_position();
2806 : // We start using the binary expression parser for prec >= 4 only!
2807 : ExpressionT expression = ParseBinaryExpression(4);
2808 : return peek() == Token::CONDITIONAL
2809 : ? ParseConditionalContinuation(expression, pos)
2810 96635191 : : expression;
2811 : }
2812 :
2813 : template <typename Impl>
2814 : typename ParserBase<Impl>::ExpressionT
2815 277930 : ParserBase<Impl>::ParseConditionalContinuation(ExpressionT expression,
2816 : int pos) {
2817 : SourceRange then_range, else_range;
2818 :
2819 : ExpressionT left;
2820 : {
2821 : SourceRangeScope range_scope(scanner(), &then_range);
2822 : Consume(Token::CONDITIONAL);
2823 : // In parsing the first assignment expression in conditional
2824 : // expressions we always accept the 'in' keyword; see ECMA-262,
2825 : // section 11.12, page 58.
2826 : AcceptINScope scope(this, true);
2827 : left = ParseAssignmentExpression();
2828 : }
2829 : ExpressionT right;
2830 : {
2831 : SourceRangeScope range_scope(scanner(), &else_range);
2832 277934 : Expect(Token::COLON);
2833 : right = ParseAssignmentExpression();
2834 : }
2835 : ExpressionT expr = factory()->NewConditional(expression, left, right, pos);
2836 : impl()->RecordConditionalSourceRange(expr, then_range, else_range);
2837 277932 : return expr;
2838 : }
2839 :
2840 : // Precedence >= 4
2841 : template <typename Impl>
2842 : typename ParserBase<Impl>::ExpressionT
2843 9040406 : ParserBase<Impl>::ParseBinaryContinuation(ExpressionT x, int prec, int prec1) {
2844 60603551 : do {
2845 : // prec1 >= 4
2846 146856251 : while (Token::Precedence(peek(), accept_IN_) == prec1) {
2847 : SourceRange right_range;
2848 : int pos = peek_position();
2849 : ExpressionT y;
2850 : Token::Value op;
2851 : {
2852 : SourceRangeScope right_range_scope(scanner(), &right_range);
2853 : op = Next();
2854 :
2855 : const bool is_right_associative = op == Token::EXP;
2856 11479446 : const int next_prec = is_right_associative ? prec1 : prec1 + 1;
2857 : y = ParseBinaryExpression(next_prec);
2858 : }
2859 :
2860 : // For now we distinguish between comparisons and other binary
2861 : // operations. (We could combine the two and get rid of this
2862 : // code and AST node eventually.)
2863 11478478 : if (Token::IsCompareOp(op)) {
2864 : // We have a comparison.
2865 : Token::Value cmp = op;
2866 978430 : switch (op) {
2867 27025 : case Token::NE: cmp = Token::EQ; break;
2868 191830 : case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2869 : default: break;
2870 : }
2871 1956858 : x = factory()->NewCompareOperation(cmp, x, y, pos);
2872 978428 : if (cmp != op) {
2873 : // The comparison was negated - add a NOT.
2874 218855 : x = factory()->NewUnaryOperation(Token::NOT, x, pos);
2875 : }
2876 2796880 : } else if (!impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op,
2877 : pos) &&
2878 1083748 : !impl()->CollapseNaryExpression(&x, y, op, pos, right_range)) {
2879 : // We have a "normal" binary operation.
2880 1475996 : x = factory()->NewBinaryOperation(op, x, y, pos);
2881 6008687 : if (op == Token::OR || op == Token::AND) {
2882 : impl()->RecordBinaryOperationSourceRange(x, right_range);
2883 : }
2884 : }
2885 : }
2886 60603551 : --prec1;
2887 : } while (prec1 >= prec);
2888 :
2889 9040058 : return x;
2890 : }
2891 :
2892 : // Precedence >= 4
2893 : template <typename Impl>
2894 : typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
2895 : int prec) {
2896 : DCHECK_GE(prec, 4);
2897 : ExpressionT x = ParseUnaryExpression();
2898 108114162 : int prec1 = Token::Precedence(peek(), accept_IN_);
2899 108114162 : if (prec1 >= prec) {
2900 9040091 : return ParseBinaryContinuation(x, prec, prec1);
2901 : }
2902 : return x;
2903 : }
2904 :
2905 : template <typename Impl>
2906 : typename ParserBase<Impl>::ExpressionT
2907 2216787 : ParserBase<Impl>::ParseUnaryOrPrefixExpression() {
2908 : Token::Value op = Next();
2909 : int pos = position();
2910 :
2911 : // Assume "! function ..." indicates the function is likely to be called.
2912 2807789 : if (op == Token::NOT && peek() == Token::FUNCTION) {
2913 265 : function_state_->set_next_function_is_likely_called();
2914 : }
2915 :
2916 2216823 : CheckStackOverflow();
2917 :
2918 : int expression_position = peek_position();
2919 : ExpressionT expression = ParseUnaryExpression();
2920 :
2921 2216808 : if (Token::IsUnaryOp(op)) {
2922 1955624 : if (op == Token::DELETE) {
2923 26525 : if (impl()->IsIdentifier(expression) && is_strict(language_mode())) {
2924 : // "delete identifier" is a syntax error in strict mode.
2925 1486 : ReportMessage(MessageTemplate::kStrictDelete);
2926 1486 : return impl()->FailureExpression();
2927 : }
2928 :
2929 21913 : if (impl()->IsPropertyWithPrivateFieldKey(expression)) {
2930 2400 : ReportMessage(MessageTemplate::kDeletePrivateField);
2931 2400 : return impl()->FailureExpression();
2932 : }
2933 : }
2934 :
2935 1951738 : if (peek() == Token::EXP) {
2936 2886 : impl()->ReportMessageAt(
2937 : Scanner::Location(pos, peek_end_position()),
2938 : MessageTemplate::kUnexpectedTokenUnaryExponentiation);
2939 2886 : return impl()->FailureExpression();
2940 : }
2941 :
2942 : // Allow the parser's implementation to rewrite the expression.
2943 684573 : return impl()->BuildUnaryExpression(expression, op, pos);
2944 : }
2945 :
2946 : DCHECK(Token::IsCountOp(op));
2947 :
2948 261181 : if (V8_LIKELY(IsValidReferenceExpression(expression))) {
2949 256149 : if (impl()->IsIdentifier(expression)) {
2950 : expression_scope()->MarkIdentifierAsAssigned();
2951 : }
2952 : } else {
2953 5029 : expression = RewriteInvalidReferenceExpression(
2954 : expression, expression_position, end_position(),
2955 : MessageTemplate::kInvalidLhsInPrefixOp);
2956 : }
2957 :
2958 : return factory()->NewCountOperation(op, true /* prefix */, expression,
2959 101647 : position());
2960 : }
2961 :
2962 : template <typename Impl>
2963 : typename ParserBase<Impl>::ExpressionT
2964 54458 : ParserBase<Impl>::ParseAwaitExpression() {
2965 54458 : expression_scope()->RecordParameterInitializerError(
2966 : scanner()->peek_location(),
2967 : MessageTemplate::kAwaitExpressionFormalParameter);
2968 : int await_pos = peek_position();
2969 : Consume(Token::AWAIT);
2970 54458 : if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
2971 140 : impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
2972 : }
2973 :
2974 54458 : CheckStackOverflow();
2975 :
2976 : ExpressionT value = ParseUnaryExpression();
2977 :
2978 27595 : ExpressionT expr = factory()->NewAwait(value, await_pos);
2979 54458 : function_state_->AddSuspend();
2980 : impl()->RecordSuspendSourceRange(expr, PositionAfterSemicolon());
2981 54458 : return expr;
2982 : }
2983 :
2984 : template <typename Impl>
2985 : typename ParserBase<Impl>::ExpressionT
2986 : ParserBase<Impl>::ParseUnaryExpression() {
2987 : // UnaryExpression ::
2988 : // PostfixExpression
2989 : // 'delete' UnaryExpression
2990 : // 'void' UnaryExpression
2991 : // 'typeof' UnaryExpression
2992 : // '++' UnaryExpression
2993 : // '--' UnaryExpression
2994 : // '+' UnaryExpression
2995 : // '-' UnaryExpression
2996 : // '~' UnaryExpression
2997 : // '!' UnaryExpression
2998 : // [+Await] AwaitExpression[?Yield]
2999 :
3000 : Token::Value op = peek();
3001 110388702 : if (Token::IsUnaryOrCountOp(op)) return ParseUnaryOrPrefixExpression();
3002 108170938 : if (is_async_function() && op == Token::AWAIT) {
3003 54458 : return ParseAwaitExpression();
3004 : }
3005 : return ParsePostfixExpression();
3006 : }
3007 :
3008 : template <typename Impl>
3009 : typename ParserBase<Impl>::ExpressionT
3010 : ParserBase<Impl>::ParsePostfixExpression() {
3011 : // PostfixExpression ::
3012 : // LeftHandSideExpression ('++' | '--')?
3013 :
3014 : int lhs_beg_pos = peek_position();
3015 : ExpressionT expression = ParseLeftHandSideExpression();
3016 108915306 : if (V8_LIKELY(!Token::IsCountOp(peek()) ||
3017 : scanner()->HasLineTerminatorBeforeNext())) {
3018 : return expression;
3019 : }
3020 803253 : return ParsePostfixContinuation(expression, lhs_beg_pos);
3021 : }
3022 :
3023 : template <typename Impl>
3024 : typename ParserBase<Impl>::ExpressionT
3025 803237 : ParserBase<Impl>::ParsePostfixContinuation(ExpressionT expression,
3026 : int lhs_beg_pos) {
3027 803238 : if (V8_UNLIKELY(!IsValidReferenceExpression(expression))) {
3028 2854 : expression = RewriteInvalidReferenceExpression(
3029 : expression, lhs_beg_pos, end_position(),
3030 : MessageTemplate::kInvalidLhsInPostfixOp);
3031 : }
3032 803249 : if (impl()->IsIdentifier(expression)) {
3033 : expression_scope()->MarkIdentifierAsAssigned();
3034 : }
3035 :
3036 : Token::Value next = Next();
3037 : return factory()->NewCountOperation(next, false /* postfix */, expression,
3038 803263 : position());
3039 : }
3040 :
3041 : template <typename Impl>
3042 : typename ParserBase<Impl>::ExpressionT
3043 : ParserBase<Impl>::ParseLeftHandSideExpression() {
3044 : // LeftHandSideExpression ::
3045 : // (NewExpression | MemberExpression) ...
3046 :
3047 : ExpressionT result = ParseMemberExpression();
3048 108261699 : if (!Token::IsPropertyOrCall(peek())) return result;
3049 13024684 : return ParseLeftHandSideContinuation(result);
3050 : }
3051 :
3052 : template <typename Impl>
3053 : typename ParserBase<Impl>::ExpressionT
3054 13024607 : ParserBase<Impl>::ParseLeftHandSideContinuation(ExpressionT result) {
3055 : DCHECK(Token::IsPropertyOrCall(peek()));
3056 :
3057 35052486 : if (V8_UNLIKELY(peek() == Token::LPAREN && impl()->IsIdentifier(result) &&
3058 : scanner()->current_token() == Token::ASYNC &&
3059 : !scanner()->HasLineTerminatorBeforeNext() &&
3060 : !scanner()->literal_contains_escapes())) {
3061 : DCHECK(impl()->IsAsync(impl()->AsIdentifier(result)));
3062 : int pos = position();
3063 :
3064 : ArrowHeadParsingScope maybe_arrow(impl(),
3065 : FunctionKind::kAsyncArrowFunction);
3066 15899 : Scope::Snapshot scope_snapshot(scope());
3067 :
3068 : ExpressionListT args(pointer_buffer());
3069 : bool has_spread;
3070 15899 : ParseArguments(&args, &has_spread, kMaybeArrowHead);
3071 15900 : if (V8_LIKELY(peek() == Token::ARROW)) {
3072 6539 : fni_.RemoveAsyncKeywordFromEnd();
3073 11621 : next_arrow_function_info_.scope = maybe_arrow.ValidateAndCreateScope();
3074 11621 : scope_snapshot.Reparent(next_arrow_function_info_.scope);
3075 : // async () => ...
3076 15147 : if (!args.length()) return factory()->NewEmptyParentheses(pos);
3077 : // async ( Arguments ) => ...
3078 3012 : ExpressionT result = impl()->ExpressionListToExpression(args);
3079 : result->mark_parenthesized();
3080 5712 : return result;
3081 : }
3082 :
3083 4279 : if (has_spread) {
3084 9 : result = impl()->SpreadCall(result, args, pos, Call::NOT_EVAL);
3085 : } else {
3086 4270 : result = factory()->NewCall(result, args, pos, Call::NOT_EVAL);
3087 : }
3088 :
3089 4279 : maybe_arrow.ValidateExpression();
3090 :
3091 : fni_.RemoveLastFunction();
3092 4279 : if (!Token::IsPropertyOrCall(peek())) return result;
3093 : }
3094 :
3095 13564132 : do {
3096 13563848 : switch (peek()) {
3097 : /* Property */
3098 : case Token::LBRACK: {
3099 : Consume(Token::LBRACK);
3100 : int pos = position();
3101 : AcceptINScope scope(this, true);
3102 20148 : ExpressionT index = ParseExpressionCoverGrammar();
3103 10228 : result = factory()->NewProperty(result, index, pos);
3104 20148 : Expect(Token::RBRACK);
3105 : break;
3106 : }
3107 :
3108 : /* Property */
3109 : case Token::PERIOD: {
3110 : Consume(Token::PERIOD);
3111 : int pos = position();
3112 284218 : ExpressionT key = ParsePropertyOrPrivatePropertyName();
3113 202780 : result = factory()->NewProperty(result, key, pos);
3114 81439 : break;
3115 : }
3116 :
3117 : /* Call */
3118 : case Token::LPAREN: {
3119 : int pos;
3120 6454292 : if (Token::IsCallable(scanner()->current_token())) {
3121 : // For call of an identifier we want to report position of
3122 : // the identifier as position of the call in the stack trace.
3123 : pos = position();
3124 : } else {
3125 : // For other kinds of calls we record position of the parenthesis as
3126 : // position of the call. Note that this is extremely important for
3127 : // expressions of the form function(){...}() for which call position
3128 : // should not point to the closing brace otherwise it will intersect
3129 : // with positions recorded for function literal and confuse debugger.
3130 : pos = peek_position();
3131 : // Also the trailing parenthesis are a hint that the function will
3132 : // be called immediately. If we happen to have parsed a preceding
3133 : // function literal eagerly, we can also compile it eagerly.
3134 162726 : if (result->IsFunctionLiteral()) {
3135 215328 : result->AsFunctionLiteral()->SetShouldEagerCompile();
3136 107668 : if (scope()->is_script_scope()) {
3137 : // A non-top-level iife is likely to be executed multiple times
3138 : // and so shouldn`t be optimized as one-shot.
3139 : result->AsFunctionLiteral()->mark_as_oneshot_iife();
3140 : }
3141 : }
3142 : }
3143 : bool has_spread;
3144 : ExpressionListT args(pointer_buffer());
3145 13258003 : ParseArguments(&args, &has_spread);
3146 :
3147 : // Keep track of eval() calls since they disable all local variable
3148 : // optimizations.
3149 : // The calls that need special treatment are the
3150 : // direct eval calls. These calls are all of the form eval(...), with
3151 : // no explicit receiver.
3152 : // These calls are marked as potentially direct eval calls. Whether
3153 : // they are actually direct calls to eval is determined at run time.
3154 : Call::PossiblyEval is_possibly_eval =
3155 13258004 : CheckPossibleEvalCall(result, scope());
3156 :
3157 13258315 : if (has_spread) {
3158 9195 : result = impl()->SpreadCall(result, args, pos, is_possibly_eval);
3159 : } else {
3160 13249120 : result = factory()->NewCall(result, args, pos, is_possibly_eval);
3161 : }
3162 :
3163 : fni_.RemoveLastFunction();
3164 : break;
3165 : }
3166 :
3167 : /* Call */
3168 : default:
3169 : DCHECK(Token::IsTemplate(peek()));
3170 1487 : result = ParseTemplateLiteral(result, position(), true);
3171 1487 : break;
3172 : }
3173 : } while (Token::IsPropertyOrCall(peek()));
3174 6644620 : return result;
3175 : }
3176 :
3177 : template <typename Impl>
3178 : typename ParserBase<Impl>::ExpressionT
3179 549714 : ParserBase<Impl>::ParseMemberWithPresentNewPrefixesExpression() {
3180 : // NewExpression ::
3181 : // ('new')+ MemberExpression
3182 : //
3183 : // NewTarget ::
3184 : // 'new' '.' 'target'
3185 :
3186 : // The grammar for new expressions is pretty warped. We can have several 'new'
3187 : // keywords following each other, and then a MemberExpression. When we see '('
3188 : // after the MemberExpression, it's associated with the rightmost unassociated
3189 : // 'new' to create a NewExpression with arguments. However, a NewExpression
3190 : // can also occur without arguments.
3191 :
3192 : // Examples of new expression:
3193 : // new foo.bar().baz means (new (foo.bar)()).baz
3194 : // new foo()() means (new foo())()
3195 : // new new foo()() means (new (new foo())())
3196 : // new new foo means new (new foo)
3197 : // new new foo() means new (new foo())
3198 : // new new foo().bar().baz means (new (new foo()).bar()).baz
3199 : Consume(Token::NEW);
3200 : int new_pos = position();
3201 : ExpressionT result;
3202 :
3203 549751 : CheckStackOverflow();
3204 :
3205 549738 : if (peek() == Token::SUPER) {
3206 : const bool is_new = true;
3207 7738 : result = ParseSuperExpression(is_new);
3208 545020 : } else if (allow_harmony_dynamic_import() && peek() == Token::IMPORT &&
3209 : (!allow_harmony_import_meta() || PeekAhead() == Token::LPAREN)) {
3210 2000 : impl()->ReportMessageAt(scanner()->peek_location(),
3211 : MessageTemplate::kImportCallNotNewExpression);
3212 2000 : return impl()->FailureExpression();
3213 540000 : } else if (peek() == Token::PERIOD) {
3214 8474 : result = ParseNewTargetExpression();
3215 3173 : return ParseMemberExpressionContinuation(result);
3216 : } else {
3217 : result = ParseMemberExpression();
3218 : }
3219 539275 : if (peek() == Token::LPAREN) {
3220 : // NewExpression with arguments.
3221 : {
3222 : ExpressionListT args(pointer_buffer());
3223 : bool has_spread;
3224 495156 : ParseArguments(&args, &has_spread);
3225 :
3226 147846 : if (has_spread) {
3227 230 : result = impl()->SpreadCallNew(result, args, new_pos);
3228 : } else {
3229 147616 : result = factory()->NewCallNew(result, args, new_pos);
3230 : }
3231 : }
3232 : // The expression can still continue with . or [ after the arguments.
3233 147852 : return ParseMemberExpressionContinuation(result);
3234 : }
3235 : // NewExpression without arguments.
3236 : ExpressionListT args(pointer_buffer());
3237 26357 : return factory()->NewCallNew(result, args, new_pos);
3238 : }
3239 :
3240 : template <typename Impl>
3241 : typename ParserBase<Impl>::ExpressionT
3242 1940063 : ParserBase<Impl>::ParseFunctionExpression() {
3243 : Consume(Token::FUNCTION);
3244 : int function_token_position = position();
3245 :
3246 : FunctionKind function_kind = Check(Token::MUL)
3247 : ? FunctionKind::kGeneratorFunction
3248 1940065 : : FunctionKind::kNormalFunction;
3249 80390 : IdentifierT name = impl()->NullIdentifier();
3250 : bool is_strict_reserved_name = Token::IsStrictReservedWord(peek());
3251 1940065 : Scanner::Location function_name_location = Scanner::Location::invalid();
3252 : FunctionLiteral::FunctionType function_type =
3253 : FunctionLiteral::kAnonymousExpression;
3254 1859675 : if (impl()->ParsingDynamicFunctionDeclaration()) {
3255 : // We don't want dynamic functions to actually declare their name
3256 : // "anonymous". We just want that name in the toString().
3257 : Consume(Token::IDENTIFIER);
3258 : DCHECK_IMPLIES(!has_error(),
3259 : scanner()->CurrentSymbol(ast_value_factory()) ==
3260 : ast_value_factory()->anonymous_string());
3261 1604188 : } else if (peek_any_identifier()) {
3262 22734 : name = ParseIdentifier(function_kind);
3263 934207 : function_name_location = scanner()->location();
3264 : function_type = FunctionLiteral::kNamedExpression;
3265 : }
3266 : FunctionLiteralT result = impl()->ParseFunctionLiteral(
3267 : name, function_name_location,
3268 : is_strict_reserved_name ? kFunctionNameIsStrictReserved
3269 : : kFunctionNameValidityUnknown,
3270 : function_kind, function_token_position, function_type, language_mode(),
3271 1940062 : nullptr);
3272 : // TODO(verwaest): FailureFunctionLiteral?
3273 1940078 : if (impl()->IsNull(result)) return impl()->FailureExpression();
3274 80390 : return result;
3275 : }
3276 :
3277 : template <typename Impl>
3278 : typename ParserBase<Impl>::ExpressionT
3279 : ParserBase<Impl>::ParseMemberExpression() {
3280 : // MemberExpression ::
3281 : // (PrimaryExpression | FunctionLiteral | ClassLiteral)
3282 : // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
3283 : //
3284 : // CallExpression ::
3285 : // (SuperCall | ImportCall)
3286 : // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
3287 : //
3288 : // The '[' Expression ']' and '.' Identifier parts are parsed by
3289 : // ParseMemberExpressionContinuation, and everything preceeding it is merged
3290 : // into ParsePrimaryExpression.
3291 :
3292 : // Parse the initial primary or function expression.
3293 108797953 : ExpressionT result = ParsePrimaryExpression();
3294 : return ParseMemberExpressionContinuation(result);
3295 : }
3296 :
3297 : template <typename Impl>
3298 : typename ParserBase<Impl>::ExpressionT
3299 31724 : ParserBase<Impl>::ParseImportExpressions() {
3300 : DCHECK(allow_harmony_dynamic_import());
3301 :
3302 : Consume(Token::IMPORT);
3303 : int pos = position();
3304 57228 : if (allow_harmony_import_meta() && Check(Token::PERIOD)) {
3305 24613 : ExpectContextualKeyword(ast_value_factory()->meta_string(), "import.meta",
3306 : pos);
3307 24613 : if (!parsing_module_) {
3308 13478 : impl()->ReportMessageAt(scanner()->location(),
3309 : MessageTemplate::kImportMetaOutsideModule);
3310 13478 : return impl()->FailureExpression();
3311 : }
3312 :
3313 3210 : return impl()->ImportMetaExpression(pos);
3314 : }
3315 7111 : Expect(Token::LPAREN);
3316 7111 : if (peek() == Token::RPAREN) {
3317 86 : impl()->ReportMessageAt(scanner()->location(),
3318 : MessageTemplate::kImportMissingSpecifier);
3319 86 : return impl()->FailureExpression();
3320 : }
3321 : AcceptINScope scope(this, true);
3322 7025 : ExpressionT arg = ParseAssignmentExpressionCoverGrammar();
3323 7025 : Expect(Token::RPAREN);
3324 :
3325 : return factory()->NewImportCallExpression(arg, pos);
3326 : }
3327 :
3328 : template <typename Impl>
3329 29386 : typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression(
3330 : bool is_new) {
3331 : Consume(Token::SUPER);
3332 : int pos = position();
3333 :
3334 : DeclarationScope* scope = GetReceiverScope();
3335 : FunctionKind kind = scope->function_kind();
3336 68823 : if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
3337 : IsClassConstructor(kind)) {
3338 17301 : if (Token::IsProperty(peek())) {
3339 11611 : if (peek() == Token::PERIOD && PeekAhead() == Token::PRIVATE_NAME) {
3340 : Consume(Token::PERIOD);
3341 : Consume(Token::PRIVATE_NAME);
3342 :
3343 0 : impl()->ReportMessage(MessageTemplate::kUnexpectedPrivateField);
3344 0 : return impl()->FailureExpression();
3345 : }
3346 : scope->RecordSuperPropertyUsage();
3347 : UseThis();
3348 2758 : return impl()->NewSuperPropertyReference(pos);
3349 : }
3350 : // new super() is never allowed.
3351 : // super() is only allowed in derived constructor
3352 16978 : if (!is_new && peek() == Token::LPAREN && IsDerivedConstructor(kind)) {
3353 : // TODO(rossberg): This might not be the correct FunctionState for the
3354 : // method here.
3355 : expression_scope()->RecordThisUse();
3356 : UseThis()->set_maybe_assigned();
3357 2890 : return impl()->NewSuperCallReference(pos);
3358 : }
3359 : }
3360 :
3361 16281 : impl()->ReportMessageAt(scanner()->location(),
3362 : MessageTemplate::kUnexpectedSuper);
3363 16281 : return impl()->FailureExpression();
3364 : }
3365 :
3366 : template <typename Impl>
3367 : typename ParserBase<Impl>::ExpressionT
3368 8474 : ParserBase<Impl>::ParseNewTargetExpression() {
3369 : int pos = position();
3370 : Consume(Token::PERIOD);
3371 8474 : ExpectContextualKeyword(ast_value_factory()->target_string(), "new.target",
3372 : pos);
3373 :
3374 8474 : if (!GetReceiverScope()->is_function_scope()) {
3375 2140 : impl()->ReportMessageAt(scanner()->location(),
3376 : MessageTemplate::kUnexpectedNewTarget);
3377 2140 : return impl()->FailureExpression();
3378 : }
3379 :
3380 2113 : return impl()->NewTargetExpression(pos);
3381 : }
3382 :
3383 : template <typename Impl>
3384 : typename ParserBase<Impl>::ExpressionT
3385 17124205 : ParserBase<Impl>::DoParseMemberExpressionContinuation(ExpressionT expression) {
3386 : DCHECK(Token::IsMember(peek()));
3387 : // Parses this part of MemberExpression:
3388 : // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
3389 18641260 : do {
3390 18640875 : switch (peek()) {
3391 : case Token::LBRACK: {
3392 : Consume(Token::LBRACK);
3393 : int pos = position();
3394 : AcceptINScope scope(this, true);
3395 4095040 : ExpressionT index = ParseExpressionCoverGrammar();
3396 2325319 : expression = factory()->NewProperty(expression, index, pos);
3397 : impl()->PushPropertyName(index);
3398 4095047 : Expect(Token::RBRACK);
3399 : break;
3400 : }
3401 : case Token::PERIOD: {
3402 : Consume(Token::PERIOD);
3403 : int pos = peek_position();
3404 14533710 : ExpressionT key = ParsePropertyOrPrivatePropertyName();
3405 8959127 : expression = factory()->NewProperty(expression, key, pos);
3406 5574437 : break;
3407 : }
3408 : default: {
3409 : DCHECK(Token::IsTemplate(peek()));
3410 : int pos;
3411 12606 : if (scanner()->current_token() == Token::IDENTIFIER) {
3412 : pos = position();
3413 : } else {
3414 : pos = peek_position();
3415 1725 : if (expression->IsFunctionLiteral()) {
3416 : // If the tag function looks like an IIFE, set_parenthesized() to
3417 : // force eager compilation.
3418 642 : expression->AsFunctionLiteral()->SetShouldEagerCompile();
3419 : }
3420 : }
3421 12606 : expression = ParseTemplateLiteral(expression, pos, true);
3422 12606 : break;
3423 : }
3424 : }
3425 : } while (Token::IsMember(peek()));
3426 17124590 : return expression;
3427 : }
3428 :
3429 : template <typename Impl>
3430 : void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters) {
3431 : // FormalParameter[Yield,GeneratorParameter] :
3432 : // BindingElement[?Yield, ?GeneratorParameter]
3433 7804542 : FuncNameInferrerState fni_state(&fni_);
3434 : int pos = peek_position();
3435 7867900 : auto declaration_it = scope()->declarations()->end();
3436 7886673 : ExpressionT pattern = ParseBindingPattern();
3437 7886655 : if (impl()->IsIdentifier(pattern)) {
3438 7816367 : ClassifyParameter(impl()->AsIdentifier(pattern), pos, end_position());
3439 : } else {
3440 70288 : parameters->is_simple = false;
3441 : }
3442 :
3443 : ExpressionT initializer = impl()->NullExpression();
3444 7886669 : if (Check(Token::ASSIGN)) {
3445 117010 : parameters->is_simple = false;
3446 :
3447 117010 : if (parameters->has_rest) {
3448 0 : ReportMessage(MessageTemplate::kRestDefaultInitializer);
3449 : return;
3450 : }
3451 :
3452 : AcceptINScope accept_in_scope(this, true);
3453 : initializer = ParseAssignmentExpression();
3454 18356 : impl()->SetFunctionNameFromIdentifierRef(initializer, pattern);
3455 : }
3456 :
3457 7867884 : auto declaration_end = scope()->declarations()->end();
3458 : int initializer_end = end_position();
3459 15682393 : for (; declaration_it != declaration_end; ++declaration_it) {
3460 3888481 : declaration_it->var()->set_initializer_position(initializer_end);
3461 : }
3462 :
3463 7886628 : impl()->AddFormalParameter(parameters, pattern, initializer, end_position(),
3464 : parameters->has_rest);
3465 : }
3466 :
3467 : template <typename Impl>
3468 4390731 : void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters) {
3469 : // FormalParameters[Yield] :
3470 : // [empty]
3471 : // FunctionRestParameter[?Yield]
3472 : // FormalParameterList[?Yield]
3473 : // FormalParameterList[?Yield] ,
3474 : // FormalParameterList[?Yield] , FunctionRestParameter[?Yield]
3475 : //
3476 : // FormalParameterList[Yield] :
3477 : // FormalParameter[?Yield]
3478 : // FormalParameterList[?Yield] , FormalParameter[?Yield]
3479 : ParameterParsingScope scope(impl(), parameters);
3480 :
3481 : DCHECK_EQ(0, parameters->arity);
3482 :
3483 4390731 : if (peek() != Token::RPAREN) {
3484 : while (true) {
3485 : // Add one since we're going to be adding a parameter.
3486 7867918 : if (parameters->arity + 1 > Code::kMaxArguments) {
3487 18 : ReportMessage(MessageTemplate::kTooManyParameters);
3488 18 : return;
3489 : }
3490 7867900 : parameters->has_rest = Check(Token::ELLIPSIS);
3491 : ParseFormalParameter(parameters);
3492 :
3493 7867834 : if (parameters->has_rest) {
3494 16498 : parameters->is_simple = false;
3495 16498 : if (peek() == Token::COMMA) {
3496 3224 : impl()->ReportMessageAt(scanner()->peek_location(),
3497 : MessageTemplate::kParamAfterRest);
3498 3224 : return;
3499 : }
3500 : break;
3501 : }
3502 7851377 : if (!Check(Token::COMMA)) break;
3503 5334340 : if (peek() == Token::RPAREN) {
3504 : // allow the trailing comma
3505 : break;
3506 : }
3507 : }
3508 : }
3509 :
3510 : impl()->DeclareFormalParameters(parameters);
3511 : }
3512 :
3513 : template <typename Impl>
3514 13729595 : void ParserBase<Impl>::ParseVariableDeclarations(
3515 : VariableDeclarationContext var_context,
3516 : DeclarationParsingResult* parsing_result,
3517 : ZonePtrList<const AstRawString>* names) {
3518 : // VariableDeclarations ::
3519 : // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
3520 : //
3521 : // ES6:
3522 : // FIXME(marja, nikolaos): Add an up-to-date comment about ES6 variable
3523 : // declaration syntax.
3524 :
3525 : DCHECK_NOT_NULL(parsing_result);
3526 13729595 : parsing_result->descriptor.kind = NORMAL_VARIABLE;
3527 13729595 : parsing_result->descriptor.declaration_pos = peek_position();
3528 13729595 : parsing_result->descriptor.initialization_pos = peek_position();
3529 :
3530 13729595 : switch (peek()) {
3531 : case Token::VAR:
3532 11507747 : parsing_result->descriptor.mode = VariableMode::kVar;
3533 : Consume(Token::VAR);
3534 : break;
3535 : case Token::CONST:
3536 : Consume(Token::CONST);
3537 : DCHECK_NE(var_context, kStatement);
3538 541327 : parsing_result->descriptor.mode = VariableMode::kConst;
3539 541327 : break;
3540 : case Token::LET:
3541 : Consume(Token::LET);
3542 : DCHECK_NE(var_context, kStatement);
3543 1680520 : parsing_result->descriptor.mode = VariableMode::kLet;
3544 1680520 : break;
3545 : default:
3546 0 : UNREACHABLE(); // by current callers
3547 : break;
3548 : }
3549 :
3550 : VariableDeclarationParsingScope declaration(
3551 13729603 : impl(), parsing_result->descriptor.mode, names);
3552 13729603 : Scope* target_scope = IsLexicalVariableMode(parsing_result->descriptor.mode)
3553 : ? scope()
3554 13729603 : : scope()->GetDeclarationScope();
3555 :
3556 : auto declaration_it = target_scope->declarations()->end();
3557 :
3558 : int bindings_start = peek_position();
3559 14150378 : do {
3560 : // Parse binding pattern.
3561 9297929 : FuncNameInferrerState fni_state(&fni_);
3562 :
3563 : int decl_pos = peek_position();
3564 :
3565 : IdentifierT name;
3566 : ExpressionT pattern;
3567 : // Check for an identifier first, so that we can elide the pattern in cases
3568 : // where there is no initializer (and so no proxy needs to be created).
3569 14232312 : if (V8_LIKELY(Token::IsAnyIdentifier(peek()))) {
3570 : name = ParseAndClassifyIdentifier(Next());
3571 15683943 : if (V8_UNLIKELY(is_strict(language_mode()) &&
3572 : impl()->IsEvalOrArguments(name))) {
3573 478 : impl()->ReportMessageAt(scanner()->location(),
3574 : MessageTemplate::kStrictEvalArguments);
3575 478 : return;
3576 : }
3577 16763764 : if (peek() == Token::ASSIGN ||
3578 179867 : (var_context == kForStatement && PeekInOrOf()) ||
3579 2551968 : parsing_result->descriptor.mode == VariableMode::kLet) {
3580 : // Assignments need the variable expression for the assignment LHS, and
3581 : // for of/in will need it later, so create the expression now.
3582 : pattern = impl()->ExpressionFromIdentifier(name, decl_pos);
3583 : } else {
3584 : // Otherwise, elide the variable expression and just declare it.
3585 : impl()->DeclareIdentifier(name, decl_pos);
3586 : pattern = impl()->NullExpression();
3587 : }
3588 : } else {
3589 : name = impl()->NullIdentifier();
3590 199801 : pattern = ParseBindingPattern();
3591 : DCHECK(!impl()->IsIdentifier(pattern));
3592 : }
3593 :
3594 14231567 : Scanner::Location variable_loc = scanner()->location();
3595 :
3596 : ExpressionT value = impl()->NullExpression();
3597 : int value_beg_pos = kNoSourcePosition;
3598 14231570 : if (Check(Token::ASSIGN)) {
3599 : DCHECK(!impl()->IsNull(pattern));
3600 : {
3601 : value_beg_pos = peek_position();
3602 11365557 : AcceptINScope scope(this, var_context != kForStatement);
3603 : value = ParseAssignmentExpression();
3604 : }
3605 : variable_loc.end_pos = end_position();
3606 :
3607 11365483 : if (!parsing_result->first_initializer_loc.IsValid()) {
3608 11257182 : parsing_result->first_initializer_loc = variable_loc;
3609 : }
3610 :
3611 : // Don't infer if it is "a = function(){...}();"-like expression.
3612 6948698 : if (impl()->IsIdentifier(pattern)) {
3613 6921989 : if (!value->IsCall() && !value->IsCallNew()) {
3614 : fni_.Infer();
3615 : } else {
3616 : fni_.RemoveLastFunction();
3617 : }
3618 : }
3619 :
3620 6948698 : impl()->SetFunctionNameFromIdentifierRef(value, pattern);
3621 : } else {
3622 : #ifdef DEBUG
3623 : // We can fall through into here on error paths, so don't DCHECK those.
3624 : if (!has_error()) {
3625 : // We should never get identifier patterns for the non-initializer path,
3626 : // as those expressions should be elided.
3627 : DCHECK_EQ(!impl()->IsNull(name),
3628 : Token::IsAnyIdentifier(scanner()->current_token()));
3629 : DCHECK_IMPLIES(impl()->IsNull(pattern), !impl()->IsNull(name));
3630 : // The only times we have a non-null pattern are:
3631 : // 1. This is a destructuring declaration (with no initializer, which
3632 : // is immediately an error),
3633 : // 2. This is a declaration in a for in/of loop, or
3634 : // 3. This is a let (which has an implicit undefined initializer)
3635 : DCHECK_IMPLIES(
3636 : !impl()->IsNull(pattern),
3637 : !impl()->IsIdentifier(pattern) ||
3638 : (var_context == kForStatement && PeekInOrOf()) ||
3639 : parsing_result->descriptor.mode == VariableMode::kLet);
3640 : }
3641 : #endif
3642 :
3643 2866013 : if (var_context != kForStatement || !PeekInOrOf()) {
3644 : // ES6 'const' and binding patterns require initializers.
3645 2647506 : if (parsing_result->descriptor.mode == VariableMode::kConst ||
3646 : impl()->IsNull(name)) {
3647 162958 : impl()->ReportMessageAt(
3648 : Scanner::Location(decl_pos, end_position()),
3649 : MessageTemplate::kDeclarationMissingInitializer,
3650 : impl()->IsNull(name) ? "destructuring" : "const");
3651 81479 : return;
3652 : }
3653 : // 'let x' initializes 'x' to undefined.
3654 2566027 : if (parsing_result->descriptor.mode == VariableMode::kLet) {
3655 : value = factory()->NewUndefinedLiteral(position());
3656 : }
3657 : }
3658 : }
3659 :
3660 : int initializer_position = end_position();
3661 : auto declaration_end = target_scope->declarations()->end();
3662 23985357 : for (; declaration_it != declaration_end; ++declaration_it) {
3663 : declaration_it->var()->set_initializer_position(initializer_position);
3664 : }
3665 :
3666 : // Patterns should be elided iff. they don't have an initializer.
3667 : DCHECK_IMPLIES(impl()->IsNull(pattern),
3668 : impl()->IsNull(value) ||
3669 : (var_context == kForStatement && PeekInOrOf()));
3670 :
3671 : typename DeclarationParsingResult::Declaration decl(pattern, value);
3672 14149962 : decl.value_beg_pos = value_beg_pos;
3673 :
3674 14149962 : parsing_result->declarations.push_back(decl);
3675 : } while (Check(Token::COMMA));
3676 :
3677 13647632 : parsing_result->bindings_loc =
3678 : Scanner::Location(bindings_start, end_position());
3679 : }
3680 :
3681 : template <typename Impl>
3682 : typename ParserBase<Impl>::StatementT
3683 1436 : ParserBase<Impl>::ParseFunctionDeclaration() {
3684 : Consume(Token::FUNCTION);
3685 :
3686 : int pos = position();
3687 : ParseFunctionFlags flags = ParseFunctionFlag::kIsNormal;
3688 1436 : if (Check(Token::MUL)) {
3689 320 : impl()->ReportMessageAt(
3690 : scanner()->location(),
3691 : MessageTemplate::kGeneratorInSingleStatementContext);
3692 320 : return impl()->NullStatement();
3693 : }
3694 1116 : return ParseHoistableDeclaration(pos, flags, nullptr, false);
3695 : }
3696 :
3697 : template <typename Impl>
3698 : typename ParserBase<Impl>::StatementT
3699 1059979 : ParserBase<Impl>::ParseHoistableDeclaration(
3700 : ZonePtrList<const AstRawString>* names, bool default_export) {
3701 : Consume(Token::FUNCTION);
3702 :
3703 : int pos = position();
3704 : ParseFunctionFlags flags = ParseFunctionFlag::kIsNormal;
3705 1060013 : if (Check(Token::MUL)) {
3706 : flags |= ParseFunctionFlag::kIsGenerator;
3707 : }
3708 1060013 : return ParseHoistableDeclaration(pos, flags, names, default_export);
3709 : }
3710 :
3711 : template <typename Impl>
3712 : typename ParserBase<Impl>::StatementT
3713 1219366 : ParserBase<Impl>::ParseHoistableDeclaration(
3714 : int pos, ParseFunctionFlags flags, ZonePtrList<const AstRawString>* names,
3715 : bool default_export) {
3716 1219366 : CheckStackOverflow();
3717 :
3718 : // FunctionDeclaration ::
3719 : // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
3720 : // 'function' '(' FormalParameters ')' '{' FunctionBody '}'
3721 : // GeneratorDeclaration ::
3722 : // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
3723 : // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
3724 : //
3725 : // The anonymous forms are allowed iff [default_export] is true.
3726 : //
3727 : // 'function' and '*' (if present) have been consumed by the caller.
3728 :
3729 : DCHECK_IMPLIES((flags & ParseFunctionFlag::kIsAsync) != 0,
3730 : (flags & ParseFunctionFlag::kIsGenerator) == 0);
3731 :
3732 1377638 : if ((flags & ParseFunctionFlag::kIsAsync) != 0 && Check(Token::MUL)) {
3733 : // Async generator
3734 : flags |= ParseFunctionFlag::kIsGenerator;
3735 : }
3736 :
3737 : IdentifierT name;
3738 : FunctionNameValidity name_validity;
3739 : IdentifierT variable_name;
3740 1219385 : if (peek() == Token::LPAREN) {
3741 1288 : if (default_export) {
3742 : impl()->GetDefaultStrings(&name, &variable_name);
3743 : name_validity = kSkipFunctionNameCheck;
3744 : } else {
3745 1238 : ReportMessage(MessageTemplate::kMissingFunctionName);
3746 1238 : return impl()->NullStatement();
3747 : }
3748 : } else {
3749 : bool is_strict_reserved = Token::IsStrictReservedWord(peek());
3750 : name = ParseIdentifier();
3751 1218079 : name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved
3752 : : kFunctionNameValidityUnknown;
3753 : variable_name = name;
3754 : }
3755 :
3756 982578 : FuncNameInferrerState fni_state(&fni_);
3757 : impl()->PushEnclosingName(name);
3758 :
3759 : FunctionKind function_kind = FunctionKindFor(flags);
3760 :
3761 : FunctionLiteralT function = impl()->ParseFunctionLiteral(
3762 : name, scanner()->location(), name_validity, function_kind, pos,
3763 2436282 : FunctionLiteral::kDeclaration, language_mode(), nullptr);
3764 :
3765 : // In ES6, a function behaves as a lexical binding, except in
3766 : // a script scope, or the initial scope of eval or another function.
3767 : VariableMode mode =
3768 : (!scope()->is_declaration_scope() || scope()->is_module_scope())
3769 : ? VariableMode::kLet
3770 1218121 : : VariableMode::kVar;
3771 : // Async functions don't undergo sloppy mode block scoped hoisting, and don't
3772 : // allow duplicates in a block. Both are represented by the
3773 : // sloppy_block_functions_. Don't add them to the map for async functions.
3774 : // Generators are also supposed to be prohibited; currently doing this behind
3775 : // a flag and UseCounting violations to assess web compatibility.
3776 : VariableKind kind = is_sloppy(language_mode()) &&
3777 : !scope()->is_declaration_scope() &&
3778 : flags == ParseFunctionFlag::kIsNormal
3779 : ? SLOPPY_BLOCK_FUNCTION_VARIABLE
3780 1218121 : : NORMAL_VARIABLE;
3781 :
3782 : return impl()->DeclareFunction(variable_name, function, mode, kind, pos,
3783 982571 : end_position(), names);
3784 : }
3785 :
3786 : template <typename Impl>
3787 177710 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration(
3788 : ZonePtrList<const AstRawString>* names, bool default_export) {
3789 : // ClassDeclaration ::
3790 : // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
3791 : // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
3792 : //
3793 : // The anonymous form is allowed iff [default_export] is true.
3794 : //
3795 : // 'class' is expected to be consumed by the caller.
3796 : //
3797 : // A ClassDeclaration
3798 : //
3799 : // class C { ... }
3800 : //
3801 : // has the same semantics as:
3802 : //
3803 : // let C = class C { ... };
3804 : //
3805 : // so rewrite it as such.
3806 :
3807 : int class_token_pos = position();
3808 70131 : IdentifierT name = impl()->NullIdentifier();
3809 : bool is_strict_reserved = Token::IsStrictReservedWord(peek());
3810 : IdentifierT variable_name = impl()->NullIdentifier();
3811 177710 : if (default_export && (peek() == Token::EXTENDS || peek() == Token::LBRACE)) {
3812 : impl()->GetDefaultStrings(&name, &variable_name);
3813 : } else {
3814 : name = ParseIdentifier();
3815 : variable_name = name;
3816 : }
3817 :
3818 177710 : ExpressionParsingScope no_expression_scope(impl());
3819 177710 : ExpressionT value = ParseClassLiteral(name, scanner()->location(),
3820 177710 : is_strict_reserved, class_token_pos);
3821 177711 : no_expression_scope.ValidateExpression();
3822 : int end_pos = position();
3823 : return impl()->DeclareClass(variable_name, value, names, class_token_pos,
3824 285289 : end_pos);
3825 : }
3826 :
3827 : // Language extension which is only enabled for source files loaded
3828 : // through the API's extension mechanism. A native function
3829 : // declaration is resolved by looking up the function through a
3830 : // callback provided by the extension.
3831 : template <typename Impl>
3832 : typename ParserBase<Impl>::StatementT
3833 1814 : ParserBase<Impl>::ParseNativeDeclaration() {
3834 1814 : function_state_->DisableOptimization(BailoutReason::kNativeFunctionLiteral);
3835 :
3836 : int pos = peek_position();
3837 : Consume(Token::FUNCTION);
3838 : // Allow "eval" or "arguments" for backward compatibility.
3839 : IdentifierT name = ParseIdentifier();
3840 1814 : Expect(Token::LPAREN);
3841 1814 : if (peek() != Token::RPAREN) {
3842 0 : do {
3843 : ParseIdentifier();
3844 : } while (Check(Token::COMMA));
3845 : }
3846 1814 : Expect(Token::RPAREN);
3847 1814 : Expect(Token::SEMICOLON);
3848 1814 : return impl()->DeclareNative(name, pos);
3849 : }
3850 :
3851 : template <typename Impl>
3852 : typename ParserBase<Impl>::StatementT
3853 158253 : ParserBase<Impl>::ParseAsyncFunctionDeclaration(
3854 : ZonePtrList<const AstRawString>* names, bool default_export) {
3855 : // AsyncFunctionDeclaration ::
3856 : // async [no LineTerminator here] function BindingIdentifier[Await]
3857 : // ( FormalParameters[Await] ) { AsyncFunctionBody }
3858 : DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
3859 158253 : if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
3860 0 : impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
3861 : }
3862 : int pos = position();
3863 : DCHECK(!scanner()->HasLineTerminatorBeforeNext());
3864 : Consume(Token::FUNCTION);
3865 : ParseFunctionFlags flags = ParseFunctionFlag::kIsAsync;
3866 158253 : return ParseHoistableDeclaration(pos, flags, names, default_export);
3867 : }
3868 :
3869 : template <typename Impl>
3870 2777191 : void ParserBase<Impl>::ParseFunctionBody(
3871 : StatementListT* body, IdentifierT function_name, int pos,
3872 : const FormalParametersT& parameters, FunctionKind kind,
3873 : FunctionLiteral::FunctionType function_type, FunctionBodyType body_type) {
3874 : FunctionBodyParsingScope body_parsing_scope(impl());
3875 :
3876 1808485 : if (IsResumableFunction(kind)) impl()->PrepareGeneratorVariables();
3877 :
3878 2777204 : DeclarationScope* function_scope = parameters.scope;
3879 : DeclarationScope* inner_scope = function_scope;
3880 :
3881 : // Building the parameter initialization block declares the parameters.
3882 : // TODO(verwaest): Rely on ArrowHeadParsingScope instead.
3883 2777204 : if (V8_UNLIKELY(!parameters.is_simple)) {
3884 145602 : if (has_error()) return;
3885 53301 : BlockT init_block = impl()->BuildParameterInitializationBlock(parameters);
3886 31646 : if (IsAsyncFunction(kind) && !IsAsyncGeneratorFunction(kind)) {
3887 1782 : init_block = impl()->BuildRejectPromiseOnException(init_block);
3888 : }
3889 : body->Add(init_block);
3890 53301 : if (has_error()) return;
3891 :
3892 53301 : inner_scope = NewVarblockScope();
3893 53302 : inner_scope->set_start_position(scanner()->location().beg_pos);
3894 : }
3895 :
3896 : StatementListT inner_body(pointer_buffer());
3897 :
3898 : {
3899 2720985 : BlockState block_state(&scope_, inner_scope);
3900 :
3901 2720985 : if (body_type == FunctionBodyType::kExpression) {
3902 294597 : ExpressionT expression = ParseAssignmentExpression();
3903 :
3904 704583 : if (IsAsyncFunction(kind)) {
3905 2290 : BlockT block = factory()->NewBlock(1, true);
3906 2290 : impl()->RewriteAsyncFunctionBody(&inner_body, block, expression);
3907 : } else {
3908 700949 : inner_body.Add(
3909 : BuildReturnStatement(expression, expression->position()));
3910 : }
3911 : } else {
3912 : DCHECK(accept_IN_);
3913 : DCHECK_EQ(FunctionBodyType::kBlock, body_type);
3914 : // If we are parsing the source as if it is wrapped in a function, the
3915 : // source ends without a closing brace.
3916 : Token::Value closing_token = function_type == FunctionLiteral::kWrapped
3917 : ? Token::EOS
3918 2016398 : : Token::RBRACE;
3919 :
3920 2016398 : if (IsAsyncGeneratorFunction(kind)) {
3921 24603 : impl()->ParseAndRewriteAsyncGeneratorFunctionBody(pos, kind,
3922 : &inner_body);
3923 1954398 : } else if (IsGeneratorFunction(kind)) {
3924 25200 : impl()->ParseAndRewriteGeneratorFunctionBody(pos, kind, &inner_body);
3925 1897750 : } else if (IsAsyncFunction(kind)) {
3926 92979 : ParseAsyncFunctionBody(inner_scope, &inner_body);
3927 : } else {
3928 : ParseStatementList(&inner_body, closing_token);
3929 : }
3930 :
3931 2016401 : if (IsDerivedConstructor(kind)) {
3932 3723 : ExpressionParsingScope expression_scope(impl());
3933 3102 : inner_body.Add(factory()->NewReturnStatement(impl()->ThisExpression(),
3934 : kNoSourcePosition));
3935 3723 : expression_scope.ValidateExpression();
3936 : }
3937 2016401 : Expect(closing_token);
3938 : }
3939 : }
3940 :
3941 : scope()->set_end_position(end_position());
3942 :
3943 : bool allow_duplicate_parameters = false;
3944 :
3945 2720979 : CheckConflictingVarDeclarations(inner_scope);
3946 :
3947 2720974 : if (V8_LIKELY(parameters.is_simple)) {
3948 : DCHECK_EQ(inner_scope, function_scope);
3949 2667673 : if (is_sloppy(function_scope->language_mode())) {
3950 1025820 : impl()->InsertSloppyBlockFunctionVarBindings(function_scope);
3951 : }
3952 4193122 : allow_duplicate_parameters =
3953 : is_sloppy(function_scope->language_mode()) && !IsConciseMethod(kind);
3954 : } else {
3955 : DCHECK_NOT_NULL(inner_scope);
3956 : DCHECK_EQ(function_scope, scope());
3957 : DCHECK_EQ(function_scope, inner_scope->outer_scope());
3958 31646 : impl()->SetLanguageMode(function_scope, inner_scope->language_mode());
3959 :
3960 53301 : if (is_sloppy(inner_scope->language_mode())) {
3961 19881 : impl()->InsertSloppyBlockFunctionVarBindings(inner_scope);
3962 : }
3963 :
3964 : inner_scope->set_end_position(end_position());
3965 53301 : if (inner_scope->FinalizeBlockScope() != nullptr) {
3966 8933 : BlockT inner_block = factory()->NewBlock(true, inner_body);
3967 : inner_body.Rewind();
3968 : inner_body.Add(inner_block);
3969 : inner_block->set_scope(inner_scope);
3970 8933 : if (!impl()->HasCheckedSyntax()) {
3971 : const AstRawString* conflict = inner_scope->FindVariableDeclaredIn(
3972 8777 : function_scope, VariableMode::kLastLexicalVariableMode);
3973 8777 : if (conflict != nullptr) {
3974 114 : impl()->ReportVarRedeclarationIn(conflict, inner_scope);
3975 : }
3976 : }
3977 8933 : impl()->InsertShadowingVarBindingInitializers(inner_block);
3978 : }
3979 : }
3980 :
3981 5441932 : ValidateFormalParameters(language_mode(), parameters,
3982 : allow_duplicate_parameters);
3983 :
3984 2720970 : if (!IsArrowFunction(kind)) {
3985 : // Declare arguments after parsing the function since lexical 'arguments'
3986 : // masks the arguments object. Declare arguments before declaring the
3987 : // function var since the arguments object masks 'function arguments'.
3988 1662840 : function_scope->DeclareArguments(ast_value_factory());
3989 : }
3990 :
3991 1788350 : impl()->DeclareFunctionNameVar(function_name, function_type, function_scope);
3992 :
3993 : inner_body.MergeInto(body);
3994 : }
3995 :
3996 : template <typename Impl>
3997 4231204 : void ParserBase<Impl>::CheckArityRestrictions(int param_count,
3998 : FunctionKind function_kind,
3999 : bool has_rest,
4000 : int formals_start_pos,
4001 : int formals_end_pos) {
4002 1294694 : if (impl()->HasCheckedSyntax()) return;
4003 4231209 : if (IsGetterFunction(function_kind)) {
4004 45622 : if (param_count != 0) {
4005 6062 : impl()->ReportMessageAt(
4006 : Scanner::Location(formals_start_pos, formals_end_pos),
4007 : MessageTemplate::kBadGetterArity);
4008 : }
4009 4185587 : } else if (IsSetterFunction(function_kind)) {
4010 37034 : if (param_count != 1) {
4011 1022 : impl()->ReportMessageAt(
4012 : Scanner::Location(formals_start_pos, formals_end_pos),
4013 : MessageTemplate::kBadSetterArity);
4014 : }
4015 37034 : if (has_rest) {
4016 936 : impl()->ReportMessageAt(
4017 : Scanner::Location(formals_start_pos, formals_end_pos),
4018 : MessageTemplate::kBadSetterRestParameter);
4019 : }
4020 : }
4021 : }
4022 :
4023 : template <typename Impl>
4024 1671986 : bool ParserBase<Impl>::IsNextLetKeyword() {
4025 : DCHECK_EQ(Token::LET, peek());
4026 : Token::Value next_next = PeekAhead();
4027 1672033 : switch (next_next) {
4028 : case Token::LBRACE:
4029 : case Token::LBRACK:
4030 : case Token::IDENTIFIER:
4031 : case Token::STATIC:
4032 : case Token::LET: // `let let;` is disallowed by static semantics, but the
4033 : // token must be first interpreted as a keyword in order
4034 : // for those semantics to apply. This ensures that ASI is
4035 : // not honored when a LineTerminator separates the
4036 : // tokens.
4037 : case Token::YIELD:
4038 : case Token::AWAIT:
4039 : case Token::GET:
4040 : case Token::SET:
4041 : case Token::ASYNC:
4042 : return true;
4043 : case Token::FUTURE_STRICT_RESERVED_WORD:
4044 3280 : return is_sloppy(language_mode());
4045 : default:
4046 8394 : return false;
4047 : }
4048 : }
4049 :
4050 : template <typename Impl>
4051 : typename ParserBase<Impl>::ExpressionT
4052 1083227 : ParserBase<Impl>::ParseArrowFunctionLiteral(
4053 : const FormalParametersT& formal_parameters) {
4054 : const RuntimeCallCounterId counters[2][2] = {
4055 : {RuntimeCallCounterId::kParseBackgroundArrowFunctionLiteral,
4056 : RuntimeCallCounterId::kParseArrowFunctionLiteral},
4057 : {RuntimeCallCounterId::kPreParseBackgroundArrowFunctionLiteral,
4058 1083227 : RuntimeCallCounterId::kPreParseArrowFunctionLiteral}};
4059 : RuntimeCallTimerScope runtime_timer(
4060 : runtime_call_stats_,
4061 1083227 : counters[Impl::IsPreParser()][parsing_on_main_thread_]);
4062 : base::ElapsedTimer timer;
4063 1083234 : if (V8_UNLIKELY(FLAG_log_function_events)) timer.Start();
4064 :
4065 : DCHECK_IMPLIES(!has_error(), peek() == Token::ARROW);
4066 2154899 : if (!impl()->HasCheckedSyntax() && scanner_->HasLineTerminatorBeforeNext()) {
4067 : // ASI inserts `;` after arrow parameters if a line terminator is found.
4068 : // `=> ...` is never a valid expression, so report as syntax error.
4069 : // If next token is not `=>`, it's a syntax error anyways.
4070 480 : impl()->ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW);
4071 480 : return impl()->FailureExpression();
4072 : }
4073 :
4074 : int expected_property_count = -1;
4075 : int suspend_count = 0;
4076 : int function_literal_id = GetNextFunctionLiteralId();
4077 :
4078 1082749 : FunctionKind kind = formal_parameters.scope->function_kind();
4079 : FunctionLiteral::EagerCompileHint eager_compile_hint =
4080 538227 : default_eager_compile_hint_;
4081 : bool can_preparse = impl()->parse_lazily() &&
4082 538227 : eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
4083 : // TODO(marja): consider lazy-parsing inner arrow functions too. is_this
4084 : // handling in Scope::ResolveVariable needs to change.
4085 : bool is_lazy_top_level_function =
4086 854420 : can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables();
4087 : bool has_braces = true;
4088 538227 : ProducedPreparseData* produced_preparse_data = nullptr;
4089 : StatementListT body(pointer_buffer());
4090 : {
4091 : FunctionState function_state(&function_state_, &scope_,
4092 1082749 : formal_parameters.scope);
4093 :
4094 : Consume(Token::ARROW);
4095 :
4096 1082744 : if (peek() == Token::LBRACE) {
4097 : // Multiple statement body
4098 : DCHECK_EQ(scope(), formal_parameters.scope);
4099 :
4100 128150 : if (is_lazy_top_level_function) {
4101 : // FIXME(marja): Arrow function parameters will be parsed even if the
4102 : // body is preparsed; move relevant parts of parameter handling to
4103 : // simulate consistent parameter handling.
4104 :
4105 : // Building the parameter initialization block declares the parameters.
4106 : // TODO(verwaest): Rely on ArrowHeadParsingScope instead.
4107 30241 : if (!formal_parameters.is_simple) {
4108 6251 : impl()->BuildParameterInitializationBlock(formal_parameters);
4109 11998 : if (has_error()) return impl()->FailureExpression();
4110 : }
4111 :
4112 : // For arrow functions, we don't need to retrieve data about function
4113 : // parameters.
4114 30241 : int dummy_num_parameters = -1;
4115 : DCHECK_NE(kind & FunctionKind::kArrowFunction, 0);
4116 : bool did_preparse_successfully = impl()->SkipFunction(
4117 : nullptr, kind, FunctionLiteral::kAnonymousExpression,
4118 : formal_parameters.scope, &dummy_num_parameters,
4119 30241 : &produced_preparse_data);
4120 :
4121 : DCHECK_NULL(produced_preparse_data);
4122 :
4123 30240 : if (did_preparse_successfully) {
4124 : // Validate parameter names. We can do this only after preparsing the
4125 : // function, since the function can declare itself strict.
4126 24493 : ValidateFormalParameters(language_mode(), formal_parameters, false);
4127 : } else {
4128 : // In case we did not sucessfully preparse the function because of an
4129 : // unidentified error we do a full reparse to return the error.
4130 : // Parse again in the outer scope, since the language mode may change.
4131 : BlockState block_state(&scope_, scope()->outer_scope());
4132 : ExpressionT expression = ParseConditionalExpression();
4133 : // Reparsing the head may have caused a stack overflow.
4134 5747 : if (has_error()) return impl()->FailureExpression();
4135 :
4136 5726 : DeclarationScope* function_scope = next_arrow_function_info_.scope;
4137 : FunctionState function_state(&function_state_, &scope_,
4138 : function_scope);
4139 : Scanner::Location loc(function_scope->start_position(),
4140 : end_position());
4141 : FormalParametersT parameters(function_scope);
4142 5726 : parameters.is_simple = function_scope->has_simple_parameters();
4143 5726 : impl()->DeclareArrowFunctionFormalParameters(¶meters, expression,
4144 : loc);
4145 : next_arrow_function_info_.Reset();
4146 :
4147 : Consume(Token::ARROW);
4148 : Consume(Token::LBRACE);
4149 :
4150 : AcceptINScope scope(this, true);
4151 5726 : ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
4152 : parameters, kind,
4153 : FunctionLiteral::kAnonymousExpression,
4154 : FunctionBodyType::kBlock);
4155 5726 : CHECK(has_error());
4156 : return impl()->FailureExpression();
4157 : }
4158 : } else {
4159 : Consume(Token::LBRACE);
4160 : AcceptINScope scope(this, true);
4161 347832 : ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
4162 : formal_parameters, kind,
4163 : FunctionLiteral::kAnonymousExpression,
4164 : FunctionBodyType::kBlock);
4165 : expected_property_count = function_state.expected_property_count();
4166 : }
4167 : } else {
4168 : // Single-expression body
4169 : has_braces = false;
4170 704671 : ParseFunctionBody(&body, impl()->NullIdentifier(), kNoSourcePosition,
4171 : formal_parameters, kind,
4172 : FunctionLiteral::kAnonymousExpression,
4173 : FunctionBodyType::kExpression);
4174 : expected_property_count = function_state.expected_property_count();
4175 : }
4176 :
4177 1076984 : formal_parameters.scope->set_end_position(end_position());
4178 :
4179 : // Validate strict mode.
4180 1076984 : if (is_strict(language_mode())) {
4181 627440 : CheckStrictOctalLiteral(formal_parameters.scope->start_position(),
4182 : end_position());
4183 : }
4184 : suspend_count = function_state.suspend_count();
4185 : }
4186 :
4187 : FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
4188 : impl()->EmptyIdentifierString(), formal_parameters.scope, body,
4189 : expected_property_count, formal_parameters.num_parameters(),
4190 : formal_parameters.function_length,
4191 : FunctionLiteral::kNoDuplicateParameters,
4192 : FunctionLiteral::kAnonymousExpression, eager_compile_hint,
4193 1076982 : formal_parameters.scope->start_position(), has_braces,
4194 1597395 : function_literal_id, produced_preparse_data);
4195 :
4196 : function_literal->set_suspend_count(suspend_count);
4197 : function_literal->set_function_token_position(
4198 532470 : formal_parameters.scope->start_position());
4199 :
4200 : impl()->AddFunctionForNameInference(function_literal);
4201 :
4202 1076988 : if (V8_UNLIKELY((FLAG_log_function_events))) {
4203 3 : Scope* scope = formal_parameters.scope;
4204 6 : double ms = timer.Elapsed().InMillisecondsF();
4205 : const char* event_name =
4206 3 : is_lazy_top_level_function ? "preparse-no-resolution" : "parse";
4207 : const char* name = "arrow function";
4208 6 : logger_->FunctionEvent(event_name, script_id(), ms, scope->start_position(),
4209 : scope->end_position(), name, strlen(name));
4210 : }
4211 :
4212 544517 : return function_literal;
4213 : }
4214 :
4215 : template <typename Impl>
4216 314597 : typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
4217 : IdentifierT name, Scanner::Location class_name_location,
4218 : bool name_is_strict_reserved, int class_token_pos) {
4219 : bool is_anonymous = impl()->IsNull(name);
4220 :
4221 : // All parts of a ClassDeclaration and ClassExpression are strict code.
4222 314598 : if (!impl()->HasCheckedSyntax() && !is_anonymous) {
4223 195709 : if (name_is_strict_reserved) {
4224 1080 : impl()->ReportMessageAt(class_name_location,
4225 : MessageTemplate::kUnexpectedStrictReserved);
4226 1080 : return impl()->FailureExpression();
4227 : }
4228 194629 : if (impl()->IsEvalOrArguments(name)) {
4229 320 : impl()->ReportMessageAt(class_name_location,
4230 : MessageTemplate::kStrictEvalArguments);
4231 320 : return impl()->FailureExpression();
4232 : }
4233 : }
4234 :
4235 : Scope* block_scope = NewScope(BLOCK_SCOPE);
4236 313198 : BlockState block_state(&scope_, block_scope);
4237 : RaiseLanguageMode(LanguageMode::kStrict);
4238 :
4239 184758 : ClassInfo class_info(this);
4240 313197 : class_info.is_anonymous = is_anonymous;
4241 : impl()->DeclareClassVariable(name, &class_info, class_token_pos);
4242 :
4243 : scope()->set_start_position(end_position());
4244 313197 : if (Check(Token::EXTENDS)) {
4245 58918 : FuncNameInferrerState fni_state(&fni_);
4246 110180 : ExpressionParsingScope scope(impl());
4247 110180 : class_info.extends = ParseLeftHandSideExpression();
4248 110180 : scope.ValidateExpression();
4249 : }
4250 :
4251 313196 : Expect(Token::LBRACE);
4252 :
4253 313190 : const bool has_extends = !impl()->IsNull(class_info.extends);
4254 830421 : while (peek() != Token::RBRACE) {
4255 704960 : if (Check(Token::SEMICOLON)) continue;
4256 484575 : FuncNameInferrerState fni_state(&fni_);
4257 : // If we haven't seen the constructor yet, it potentially is the next
4258 : // property.
4259 484575 : bool is_constructor = !class_info.has_seen_constructor;
4260 : ParsePropertyInfo prop_info(this);
4261 : prop_info.position = PropertyPosition::kClassLiteral;
4262 : ClassLiteralPropertyT property =
4263 626490 : ParseClassPropertyDefinition(&class_info, &prop_info, has_extends);
4264 :
4265 626496 : if (has_error()) return impl()->FailureExpression();
4266 :
4267 : ClassLiteralProperty::Kind property_kind =
4268 477997 : ClassPropertyKindFor(prop_info.kind);
4269 477997 : if (!class_info.has_static_computed_names && prop_info.is_static &&
4270 : prop_info.is_computed_name) {
4271 5127 : class_info.has_static_computed_names = true;
4272 : }
4273 410082 : is_constructor &= class_info.has_seen_constructor;
4274 :
4275 477997 : if (V8_UNLIKELY(property_kind == ClassLiteralProperty::FIELD)) {
4276 61476 : if (prop_info.is_computed_name) {
4277 : DCHECK(!prop_info.is_private);
4278 9928 : class_info.computed_field_count++;
4279 : }
4280 :
4281 61476 : impl()->DeclareClassField(property, prop_info.name, prop_info.is_static,
4282 : prop_info.is_computed_name,
4283 : prop_info.is_private, &class_info);
4284 : } else {
4285 378198 : impl()->DeclareClassProperty(name, property, is_constructor, &class_info);
4286 : }
4287 : impl()->InferFunctionName();
4288 : }
4289 :
4290 164698 : Expect(Token::RBRACE);
4291 : int end_pos = end_position();
4292 : block_scope->set_end_position(end_pos);
4293 : return impl()->RewriteClassLiteral(block_scope, name, &class_info,
4294 110260 : class_token_pos, end_pos);
4295 : }
4296 :
4297 : template <typename Impl>
4298 92979 : void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope,
4299 : StatementListT* body) {
4300 : BlockT block = impl()->NullBlock();
4301 : {
4302 : StatementListT statements(pointer_buffer());
4303 : ParseStatementList(&statements, Token::RBRACE);
4304 40783 : block = factory()->NewBlock(true, statements);
4305 : }
4306 40783 : impl()->RewriteAsyncFunctionBody(
4307 : body, block, factory()->NewUndefinedLiteral(kNoSourcePosition));
4308 : scope->set_end_position(end_position());
4309 92979 : }
4310 :
4311 : template <typename Impl>
4312 : typename ParserBase<Impl>::ExpressionT
4313 21486 : ParserBase<Impl>::ParseAsyncFunctionLiteral() {
4314 : // AsyncFunctionLiteral ::
4315 : // async [no LineTerminator here] function ( FormalParameters[Await] )
4316 : // { AsyncFunctionBody }
4317 : //
4318 : // async [no LineTerminator here] function BindingIdentifier[Await]
4319 : // ( FormalParameters[Await] ) { AsyncFunctionBody }
4320 : DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
4321 21486 : if (V8_UNLIKELY(scanner()->literal_contains_escapes())) {
4322 0 : impl()->ReportUnexpectedToken(Token::ESCAPED_KEYWORD);
4323 : }
4324 : int pos = position();
4325 : Consume(Token::FUNCTION);
4326 8060 : IdentifierT name = impl()->NullIdentifier();
4327 : FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression;
4328 :
4329 : ParseFunctionFlags flags = ParseFunctionFlag::kIsAsync;
4330 21486 : if (Check(Token::MUL)) flags |= ParseFunctionFlag::kIsGenerator;
4331 : const FunctionKind kind = FunctionKindFor(flags);
4332 : bool is_strict_reserved = Token::IsStrictReservedWord(peek());
4333 :
4334 13426 : if (impl()->ParsingDynamicFunctionDeclaration()) {
4335 : // We don't want dynamic functions to actually declare their name
4336 : // "anonymous". We just want that name in the toString().
4337 :
4338 : // Consuming token we did not peek yet, which could lead to a ILLEGAL token
4339 : // in the case of a stackoverflow.
4340 : Consume(Token::IDENTIFIER);
4341 : DCHECK_IMPLIES(!has_error(),
4342 : scanner()->CurrentSymbol(ast_value_factory()) ==
4343 : ast_value_factory()->anonymous_string());
4344 20876 : } else if (peek_any_identifier()) {
4345 : type = FunctionLiteral::kNamedExpression;
4346 3604 : name = ParseIdentifier(kind);
4347 : }
4348 : FunctionLiteralT result = impl()->ParseFunctionLiteral(
4349 : name, scanner()->location(),
4350 : is_strict_reserved ? kFunctionNameIsStrictReserved
4351 : : kFunctionNameValidityUnknown,
4352 42972 : kind, pos, type, language_mode(), nullptr);
4353 21486 : if (impl()->IsNull(result)) return impl()->FailureExpression();
4354 8060 : return result;
4355 : }
4356 :
4357 : template <typename Impl>
4358 73278 : typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral(
4359 : ExpressionT tag, int start, bool tagged) {
4360 : // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
4361 : // text followed by a substitution expression), finalized by a single
4362 : // TEMPLATE_TAIL.
4363 : //
4364 : // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
4365 : // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
4366 : // NoSubstitutionTemplate.
4367 : //
4368 : // When parsing a TemplateLiteral, we must have scanned either an initial
4369 : // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
4370 : DCHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
4371 :
4372 73278 : if (tagged) {
4373 : // TaggedTemplate expressions prevent the eval compilation cache from being
4374 : // used. This flag is only used if an eval is being parsed.
4375 : set_allow_eval_cache(false);
4376 : }
4377 :
4378 73278 : bool forbid_illegal_escapes = !tagged;
4379 :
4380 : // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
4381 : // In this case we may simply consume the token and build a template with a
4382 : // single TEMPLATE_SPAN and no expressions.
4383 73278 : if (peek() == Token::TEMPLATE_TAIL) {
4384 : Consume(Token::TEMPLATE_TAIL);
4385 : int pos = position();
4386 9834 : typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
4387 18437 : bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes);
4388 9834 : impl()->AddTemplateSpan(&ts, is_valid, true);
4389 9834 : return impl()->CloseTemplateLiteral(&ts, start, tag);
4390 : }
4391 :
4392 : Consume(Token::TEMPLATE_SPAN);
4393 : int pos = position();
4394 28724 : typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos);
4395 54841 : bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes);
4396 28724 : impl()->AddTemplateSpan(&ts, is_valid, false);
4397 : Token::Value next;
4398 :
4399 : // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
4400 : // and repeat if the following token is a TEMPLATE_SPAN as well (in this
4401 : // case, representing a TemplateMiddle).
4402 :
4403 79847 : do {
4404 : next = peek();
4405 :
4406 : int expr_pos = peek_position();
4407 : AcceptINScope scope(this, true);
4408 86404 : ExpressionT expression = ParseExpressionCoverGrammar();
4409 : impl()->AddTemplateExpression(&ts, expression);
4410 :
4411 86404 : if (peek() != Token::RBRACE) {
4412 6557 : impl()->ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
4413 : MessageTemplate::kUnterminatedTemplateExpr);
4414 3460 : return impl()->FailureExpression();
4415 : }
4416 :
4417 : // If we didn't die parsing that expression, our next token should be a
4418 : // TEMPLATE_SPAN or TEMPLATE_TAIL.
4419 : next = scanner()->ScanTemplateContinuation();
4420 : Next();
4421 : pos = position();
4422 :
4423 79847 : bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes);
4424 45280 : impl()->AddTemplateSpan(&ts, is_valid, next == Token::TEMPLATE_TAIL);
4425 : } while (next == Token::TEMPLATE_SPAN);
4426 :
4427 : DCHECK_IMPLIES(!has_error(), next == Token::TEMPLATE_TAIL);
4428 : // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
4429 25627 : return impl()->CloseTemplateLiteral(&ts, start, tag);
4430 : }
4431 :
4432 : template <typename Impl>
4433 : typename ParserBase<Impl>::ExpressionT
4434 27451 : ParserBase<Impl>::RewriteInvalidReferenceExpression(ExpressionT expression,
4435 : int beg_pos, int end_pos,
4436 : MessageTemplate message,
4437 : ParseErrorType type) {
4438 : DCHECK(!IsValidReferenceExpression(expression));
4439 27451 : if (impl()->IsIdentifier(expression)) {
4440 : DCHECK(is_strict(language_mode()));
4441 : DCHECK(impl()->IsEvalOrArguments(impl()->AsIdentifier(expression)));
4442 :
4443 5383 : ReportMessageAt(Scanner::Location(beg_pos, end_pos),
4444 : MessageTemplate::kStrictEvalArguments, kSyntaxError);
4445 5383 : return impl()->FailureExpression();
4446 : }
4447 24436 : if (expression->IsCall() && !expression->AsCall()->is_tagged_template()) {
4448 2288 : expression_scope()->RecordPatternError(
4449 : Scanner::Location(beg_pos, end_pos),
4450 : MessageTemplate::kInvalidDestructuringTarget);
4451 : // If it is a call, make it a runtime error for legacy web compatibility.
4452 : // Bug: https://bugs.chromium.org/p/v8/issues/detail?id=4480
4453 : // Rewrite `expr' to `expr[throw ReferenceError]'.
4454 2288 : impl()->CountUsage(
4455 : is_strict(language_mode())
4456 : ? v8::Isolate::kAssigmentExpressionLHSIsCallInStrict
4457 : : v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy);
4458 1058 : ExpressionT error = impl()->NewThrowReferenceError(message, beg_pos);
4459 2288 : return factory()->NewProperty(expression, error, beg_pos);
4460 : }
4461 19780 : ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type);
4462 19780 : return impl()->FailureExpression();
4463 : }
4464 :
4465 : template <typename Impl>
4466 11307992 : void ParserBase<Impl>::ClassifyParameter(IdentifierT parameter, int begin,
4467 : int end) {
4468 15488383 : if (impl()->IsEvalOrArguments(parameter)) {
4469 15825 : expression_scope()->RecordStrictModeParameterError(
4470 : Scanner::Location(begin, end), MessageTemplate::kStrictEvalArguments);
4471 : }
4472 11307992 : }
4473 :
4474 : template <typename Impl>
4475 40245755 : void ParserBase<Impl>::ClassifyArrowParameter(
4476 : AccumulationScope* accumulation_scope, int position,
4477 : ExpressionT parameter) {
4478 : accumulation_scope->Accumulate();
4479 119934157 : if (parameter->is_parenthesized() ||
4480 52803095 : !(impl()->IsIdentifier(parameter) || parameter->IsPattern() ||
4481 : parameter->IsAssignment())) {
4482 23626615 : expression_scope()->RecordDeclarationError(
4483 : Scanner::Location(position, end_position()),
4484 : MessageTemplate::kInvalidDestructuringTarget);
4485 16619140 : } else if (impl()->IsIdentifier(parameter)) {
4486 2367604 : ClassifyParameter(impl()->AsIdentifier(parameter), position,
4487 : end_position());
4488 : } else {
4489 : expression_scope()->RecordNonSimpleParameter();
4490 : }
4491 40245800 : }
4492 :
4493 : template <typename Impl>
4494 4076990 : bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) {
4495 23084263 : return IsAssignableIdentifier(expression) || expression->IsProperty();
4496 : }
4497 :
4498 : template <typename Impl>
4499 : typename ParserBase<Impl>::ExpressionT
4500 12038970 : ParserBase<Impl>::ParsePossibleDestructuringSubPattern(
4501 : AccumulationScope* scope) {
4502 12038970 : if (scope) scope->Accumulate();
4503 : int begin = peek_position();
4504 12038970 : ExpressionT result = ParseAssignmentExpressionCoverGrammar();
4505 :
4506 12038921 : if (IsValidReferenceExpression(result)) {
4507 : // Parenthesized identifiers and property references are allowed as part of
4508 : // a larger assignment pattern, even though parenthesized patterns
4509 : // themselves are not allowed, e.g., "[(x)] = []". Only accumulate
4510 : // assignment pattern errors if the parsed expression is more complex.
4511 2459730 : if (impl()->IsIdentifier(result)) {
4512 2142997 : if (result->is_parenthesized()) {
4513 8353 : expression_scope()->RecordDeclarationError(
4514 : Scanner::Location(begin, end_position()),
4515 : MessageTemplate::kInvalidDestructuringTarget);
4516 : }
4517 : IdentifierT identifier = impl()->AsIdentifier(result);
4518 1066096 : ClassifyParameter(identifier, begin, end_position());
4519 : } else {
4520 : DCHECK(result->IsProperty());
4521 316733 : expression_scope()->RecordDeclarationError(
4522 : Scanner::Location(begin, end_position()),
4523 : MessageTemplate::kInvalidPropertyBindingPattern);
4524 316733 : if (scope != nullptr) scope->ValidateExpression();
4525 : }
4526 21058867 : } else if (result->is_parenthesized() ||
4527 : (!result->IsPattern() && !result->IsAssignment())) {
4528 9227853 : expression_scope()->RecordPatternError(
4529 : Scanner::Location(begin, end_position()),
4530 : MessageTemplate::kInvalidDestructuringTarget);
4531 : }
4532 :
4533 12039104 : return result;
4534 : }
4535 :
4536 : template <typename Impl>
4537 136091 : typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseV8Intrinsic() {
4538 : // CallRuntime ::
4539 : // '%' Identifier Arguments
4540 :
4541 : int pos = peek_position();
4542 : Consume(Token::MOD);
4543 : // Allow "eval" or "arguments" for backward compatibility.
4544 : IdentifierT name = ParseIdentifier();
4545 136091 : if (peek() != Token::LPAREN) {
4546 0 : impl()->ReportUnexpectedToken(peek());
4547 0 : return impl()->FailureExpression();
4548 : }
4549 : bool has_spread;
4550 : ExpressionListT args(pointer_buffer());
4551 136091 : ParseArguments(&args, &has_spread);
4552 :
4553 136093 : if (has_spread) {
4554 9 : ReportMessageAt(Scanner::Location(pos, position()),
4555 : MessageTemplate::kIntrinsicWithSpread, kSyntaxError);
4556 9 : return impl()->FailureExpression();
4557 : }
4558 :
4559 62635 : return impl()->NewV8Intrinsic(name, args, pos);
4560 : }
4561 :
4562 : template <typename Impl>
4563 : void ParserBase<Impl>::ParseStatementList(StatementListT* body,
4564 : Token::Value end_token) {
4565 : // StatementList ::
4566 : // (StatementListItem)* <end_token>
4567 : DCHECK_NOT_NULL(body);
4568 :
4569 8280987 : while (peek() == Token::STRING) {
4570 : bool use_strict = false;
4571 : bool use_asm = false;
4572 :
4573 1520451 : Scanner::Location token_loc = scanner()->peek_location();
4574 :
4575 1520451 : if (scanner()->NextLiteralExactlyEquals("use strict")) {
4576 : use_strict = true;
4577 1099674 : } else if (scanner()->NextLiteralExactlyEquals("use asm")) {
4578 : use_asm = true;
4579 : }
4580 :
4581 1520451 : StatementT stat = ParseStatementListItem();
4582 1529025 : if (impl()->IsNull(stat)) return;
4583 :
4584 : body->Add(stat);
4585 :
4586 1520413 : if (!impl()->IsStringLiteral(stat)) break;
4587 :
4588 1514028 : if (use_strict) {
4589 : // Directive "use strict" (ES5 14.1).
4590 38870 : RaiseLanguageMode(LanguageMode::kStrict);
4591 420773 : if (!scope()->HasSimpleParameters()) {
4592 : // TC39 deemed "use strict" directives to be an error when occurring
4593 : // in the body of a function with non-simple parameter list, on
4594 : // 29/7/2015. https://goo.gl/ueA7Ln
4595 8533 : impl()->ReportMessageAt(token_loc,
4596 : MessageTemplate::kIllegalLanguageModeDirective,
4597 : "use strict");
4598 : return;
4599 : }
4600 1093255 : } else if (use_asm) {
4601 : // Directive "use asm".
4602 4288 : impl()->SetAsmModule();
4603 : } else {
4604 : // Possibly an unknown directive.
4605 : // Should not change mode, but will increment usage counters
4606 : // as appropriate. Ditto usages below.
4607 159 : RaiseLanguageMode(LanguageMode::kSloppy);
4608 : }
4609 : }
4610 :
4611 : // Allocate a target stack to use for this set of source elements. This way,
4612 : // all scripts and functions get their own target stack thus avoiding illegal
4613 : // breaks and continues across functions.
4614 : TargetScopeT target_scope(this);
4615 39674014 : while (peek() != end_token) {
4616 33796592 : StatementT stat = ParseStatementListItem();
4617 33796591 : if (impl()->IsNull(stat)) return;
4618 18766148 : if (stat->IsEmptyStatement()) continue;
4619 : body->Add(stat);
4620 : }
4621 : }
4622 :
4623 : template <typename Impl>
4624 : typename ParserBase<Impl>::StatementT
4625 42782565 : ParserBase<Impl>::ParseStatementListItem() {
4626 : // ECMA 262 6th Edition
4627 : // StatementListItem[Yield, Return] :
4628 : // Statement[?Yield, ?Return]
4629 : // Declaration[?Yield]
4630 : //
4631 : // Declaration[Yield] :
4632 : // HoistableDeclaration[?Yield]
4633 : // ClassDeclaration[?Yield]
4634 : // LexicalDeclaration[In, ?Yield]
4635 : //
4636 : // HoistableDeclaration[Yield, Default] :
4637 : // FunctionDeclaration[?Yield, ?Default]
4638 : // GeneratorDeclaration[?Yield, ?Default]
4639 : //
4640 : // LexicalDeclaration[In, Yield] :
4641 : // LetOrConst BindingList[?In, ?Yield] ;
4642 :
4643 42782565 : switch (peek()) {
4644 : case Token::FUNCTION:
4645 1059571 : return ParseHoistableDeclaration(nullptr, false);
4646 : case Token::CLASS:
4647 : Consume(Token::CLASS);
4648 177631 : return ParseClassDeclaration(nullptr, false);
4649 : case Token::VAR:
4650 : case Token::CONST:
4651 11568166 : return ParseVariableStatement(kStatementListItem, nullptr);
4652 : case Token::LET:
4653 1421993 : if (IsNextLetKeyword()) {
4654 1414060 : return ParseVariableStatement(kStatementListItem, nullptr);
4655 : }
4656 : break;
4657 : case Token::ASYNC:
4658 318006 : if (PeekAhead() == Token::FUNCTION &&
4659 : !scanner()->HasLineTerminatorAfterNext()) {
4660 : Consume(Token::ASYNC);
4661 158128 : return ParseAsyncFunctionDeclaration(nullptr, false);
4662 : }
4663 : break;
4664 : default:
4665 : break;
4666 : }
4667 28405043 : return ParseStatement(nullptr, nullptr, kAllowLabelledFunctionStatement);
4668 : }
4669 :
4670 : template <typename Impl>
4671 33334764 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement(
4672 : ZonePtrList<const AstRawString>* labels,
4673 : ZonePtrList<const AstRawString>* own_labels,
4674 : AllowLabelledFunctionStatement allow_function) {
4675 : // Statement ::
4676 : // Block
4677 : // VariableStatement
4678 : // EmptyStatement
4679 : // ExpressionStatement
4680 : // IfStatement
4681 : // IterationStatement
4682 : // ContinueStatement
4683 : // BreakStatement
4684 : // ReturnStatement
4685 : // WithStatement
4686 : // LabelledStatement
4687 : // SwitchStatement
4688 : // ThrowStatement
4689 : // TryStatement
4690 : // DebuggerStatement
4691 :
4692 : // {own_labels} is always a subset of {labels}.
4693 : DCHECK_IMPLIES(labels == nullptr, own_labels == nullptr);
4694 :
4695 : // Note: Since labels can only be used by 'break' and 'continue'
4696 : // statements, which themselves are only valid within blocks,
4697 : // iterations or 'switch' statements (i.e., BreakableStatements),
4698 : // labels can be simply ignored in all other cases; except for
4699 : // trivial labeled break statements 'label: break label' which is
4700 : // parsed into an empty statement.
4701 33334764 : switch (peek()) {
4702 : case Token::LBRACE:
4703 3010143 : return ParseBlock(labels);
4704 : case Token::SEMICOLON:
4705 : Next();
4706 262909 : return factory()->EmptyStatement();
4707 : case Token::IF:
4708 3449443 : return ParseIfStatement(labels);
4709 : case Token::DO:
4710 18030 : return ParseDoWhileStatement(labels, own_labels);
4711 : case Token::WHILE:
4712 35668 : return ParseWhileStatement(labels, own_labels);
4713 : case Token::FOR:
4714 1072710 : if (V8_UNLIKELY(is_async_function() && PeekAhead() == Token::AWAIT)) {
4715 128569 : return ParseForAwaitStatement(labels, own_labels);
4716 : }
4717 810136 : return ParseForStatement(labels, own_labels);
4718 : case Token::CONTINUE:
4719 54367 : return ParseContinueStatement();
4720 : case Token::BREAK:
4721 192624 : return ParseBreakStatement(labels);
4722 : case Token::RETURN:
4723 3600284 : return ParseReturnStatement();
4724 : case Token::THROW:
4725 309639 : return ParseThrowStatement();
4726 : case Token::TRY: {
4727 : // It is somewhat complicated to have labels on try-statements.
4728 : // When breaking out of a try-finally statement, one must take
4729 : // great care not to treat it as a fall-through. It is much easier
4730 : // just to wrap the entire try-statement in a statement block and
4731 : // put the labels there.
4732 507435 : if (labels == nullptr) return ParseTryStatement();
4733 : StatementListT statements(pointer_buffer());
4734 112 : BlockT result = factory()->NewBlock(false, labels);
4735 : TargetT target(this, result);
4736 : StatementT statement = ParseTryStatement();
4737 : statements.Add(statement);
4738 : result->InitializeStatements(statements, zone());
4739 0 : return result;
4740 : }
4741 : case Token::WITH:
4742 101441 : return ParseWithStatement(labels);
4743 : case Token::SWITCH:
4744 136216 : return ParseSwitchStatement(labels);
4745 : case Token::FUNCTION:
4746 : // FunctionDeclaration only allowed as a StatementListItem, not in
4747 : // an arbitrary Statement position. Exceptions such as
4748 : // ES#sec-functiondeclarations-in-ifstatement-statement-clauses
4749 : // are handled by calling ParseScopedStatement rather than
4750 : // ParseStatement directly.
4751 17196 : impl()->ReportMessageAt(scanner()->peek_location(),
4752 : is_strict(language_mode())
4753 : ? MessageTemplate::kStrictFunction
4754 : : MessageTemplate::kSloppyFunction);
4755 8598 : return impl()->NullStatement();
4756 : case Token::DEBUGGER:
4757 52577 : return ParseDebuggerStatement();
4758 : case Token::VAR:
4759 454 : return ParseVariableStatement(kStatement, nullptr);
4760 : case Token::ASYNC:
4761 7572 : if (!impl()->HasCheckedSyntax() &&
4762 : !scanner()->HasLineTerminatorAfterNext() &&
4763 : PeekAhead() == Token::FUNCTION) {
4764 1280 : impl()->ReportMessageAt(
4765 : scanner()->peek_location(),
4766 : MessageTemplate::kAsyncFunctionInSingleStatementContext);
4767 1280 : return impl()->NullStatement();
4768 : }
4769 : V8_FALLTHROUGH;
4770 : default:
4771 : return ParseExpressionOrLabelledStatement(labels, own_labels,
4772 20547721 : allow_function);
4773 : }
4774 : }
4775 :
4776 : template <typename Impl>
4777 3826770 : typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock(
4778 : ZonePtrList<const AstRawString>* labels) {
4779 : // Block ::
4780 : // '{' StatementList '}'
4781 :
4782 : // Parse the statements and collect escaping labels.
4783 962472 : BlockT body = factory()->NewBlock(false, labels);
4784 : StatementListT statements(pointer_buffer());
4785 :
4786 3826777 : CheckStackOverflow();
4787 :
4788 : {
4789 3826819 : BlockState block_state(zone(), &scope_);
4790 : scope()->set_start_position(peek_position());
4791 : TargetT target(this, body);
4792 :
4793 3826858 : Expect(Token::LBRACE);
4794 :
4795 10036648 : while (peek() != Token::RBRACE) {
4796 6250306 : StatementT stat = ParseStatementListItem();
4797 6250256 : if (impl()->IsNull(stat)) return body;
4798 1670298 : if (stat->IsEmptyStatement()) continue;
4799 : statements.Add(stat);
4800 : }
4801 :
4802 3786342 : Expect(Token::RBRACE);
4803 :
4804 : int end_pos = end_position();
4805 : scope()->set_end_position(end_pos);
4806 :
4807 : impl()->RecordBlockSourceRange(body, end_pos);
4808 3786393 : body->set_scope(scope()->FinalizeBlockScope());
4809 : }
4810 :
4811 935768 : body->InitializeStatements(statements, zone_);
4812 3786358 : return body;
4813 : }
4814 :
4815 : template <typename Impl>
4816 3843023 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseScopedStatement(
4817 : ZonePtrList<const AstRawString>* labels) {
4818 7229727 : if (is_strict(language_mode()) || peek() != Token::FUNCTION) {
4819 698226 : return ParseStatement(labels, nullptr);
4820 : } else {
4821 : // Make a block around the statement for a lexical binding
4822 : // is introduced by a FunctionDeclaration.
4823 929 : BlockState block_state(zone(), &scope_);
4824 929 : scope()->set_start_position(scanner()->location().beg_pos);
4825 490 : BlockT block = factory()->NewBlock(1, false);
4826 929 : StatementT body = ParseFunctionDeclaration();
4827 490 : block->statements()->Add(body, zone());
4828 : scope()->set_end_position(end_position());
4829 929 : block->set_scope(scope()->FinalizeBlockScope());
4830 439 : return block;
4831 : }
4832 : }
4833 :
4834 : template <typename Impl>
4835 13000282 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseVariableStatement(
4836 : VariableDeclarationContext var_context,
4837 : ZonePtrList<const AstRawString>* names) {
4838 : // VariableStatement ::
4839 : // VariableDeclarations ';'
4840 :
4841 : // The scope of a var declared variable anywhere inside a function
4842 : // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
4843 : // transform a source-level var declaration into a (Function) Scope
4844 : // declaration, and rewrite the source-level initialization into an assignment
4845 : // statement. We use a block to collect multiple assignments.
4846 : //
4847 : // We mark the block as initializer block because we don't want the
4848 : // rewriter to add a '.result' assignment to such a block (to get compliant
4849 : // behavior for code such as print(eval('var x = 7')), and for cosmetic
4850 : // reasons when pretty-printing. Also, unless an assignment (initialization)
4851 : // is inside an initializer block, it is ignored.
4852 :
4853 : DeclarationParsingResult parsing_result;
4854 13000282 : ParseVariableDeclarations(var_context, &parsing_result, names);
4855 13000302 : ExpectSemicolon();
4856 21639152 : return impl()->BuildInitializationBlock(&parsing_result);
4857 : }
4858 :
4859 : template <typename Impl>
4860 : typename ParserBase<Impl>::StatementT
4861 52577 : ParserBase<Impl>::ParseDebuggerStatement() {
4862 : // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
4863 : // contexts this is used as a statement which invokes the debugger as i a
4864 : // break point is present.
4865 : // DebuggerStatement ::
4866 : // 'debugger' ';'
4867 :
4868 : int pos = peek_position();
4869 : Consume(Token::DEBUGGER);
4870 142034 : ExpectSemicolon();
4871 52577 : return factory()->NewDebuggerStatement(pos);
4872 : }
4873 :
4874 : template <typename Impl>
4875 : typename ParserBase<Impl>::StatementT
4876 20549103 : ParserBase<Impl>::ParseExpressionOrLabelledStatement(
4877 : ZonePtrList<const AstRawString>* labels,
4878 : ZonePtrList<const AstRawString>* own_labels,
4879 : AllowLabelledFunctionStatement allow_function) {
4880 : // ExpressionStatement | LabelledStatement ::
4881 : // Expression ';'
4882 : // Identifier ':' Statement
4883 : //
4884 : // ExpressionStatement[Yield] :
4885 : // [lookahead notin {{, function, class, let [}] Expression[In, ?Yield] ;
4886 :
4887 : int pos = peek_position();
4888 :
4889 20549103 : switch (peek()) {
4890 : case Token::FUNCTION:
4891 : case Token::LBRACE:
4892 0 : UNREACHABLE(); // Always handled by the callers.
4893 : case Token::CLASS:
4894 308 : ReportUnexpectedToken(Next());
4895 308 : return impl()->NullStatement();
4896 : case Token::LET: {
4897 : Token::Value next_next = PeekAhead();
4898 : // "let" followed by either "[", "{" or an identifier means a lexical
4899 : // declaration, which should not appear here.
4900 : // However, ASI may insert a line break before an identifier or a brace.
4901 9212 : if (next_next != Token::LBRACK &&
4902 : ((next_next != Token::LBRACE && next_next != Token::IDENTIFIER) ||
4903 560 : scanner_->HasLineTerminatorAfterNext())) {
4904 : break;
4905 : }
4906 326 : impl()->ReportMessageAt(scanner()->peek_location(),
4907 : MessageTemplate::kUnexpectedLexicalDeclaration);
4908 326 : return impl()->NullStatement();
4909 : }
4910 : default:
4911 : break;
4912 : }
4913 :
4914 : bool starts_with_identifier = peek_any_identifier();
4915 : ExpressionT expr = ParseExpression();
4916 20581827 : if (peek() == Token::COLON && starts_with_identifier &&
4917 : impl()->IsIdentifier(expr)) {
4918 : // The whole expression was a single identifier, and not, e.g.,
4919 : // something starting with an identifier or a parenthesized identifier.
4920 15713 : impl()->DeclareLabel(&labels, &own_labels,
4921 : impl()->AsIdentifierExpression(expr));
4922 : Consume(Token::COLON);
4923 : // ES#sec-labelled-function-declarations Labelled Function Declarations
4924 37271 : if (peek() == Token::FUNCTION && is_sloppy(language_mode()) &&
4925 : allow_function == kAllowLabelledFunctionStatement) {
4926 507 : return ParseFunctionDeclaration();
4927 : }
4928 32079 : return ParseStatement(labels, own_labels, allow_function);
4929 : }
4930 :
4931 : // If we have an extension, we allow a native function declaration.
4932 : // A native function declaration starts with "native function" with
4933 : // no line-terminator between the two words.
4934 10528583 : if (extension_ != nullptr && peek() == Token::FUNCTION &&
4935 : !scanner()->HasLineTerminatorBeforeNext() && impl()->IsNative(expr) &&
4936 : !scanner()->literal_contains_escapes()) {
4937 1814 : return ParseNativeDeclaration();
4938 : }
4939 :
4940 : // Parsed expression statement, followed by semicolon.
4941 20514023 : ExpectSemicolon();
4942 20514151 : if (expr->IsFailureExpression()) return impl()->NullStatement();
4943 10009416 : return factory()->NewExpressionStatement(expr, pos);
4944 : }
4945 :
4946 : template <typename Impl>
4947 3449444 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseIfStatement(
4948 : ZonePtrList<const AstRawString>* labels) {
4949 : // IfStatement ::
4950 : // 'if' '(' Expression ')' Statement ('else' Statement)?
4951 :
4952 : int pos = peek_position();
4953 : Consume(Token::IF);
4954 3449440 : Expect(Token::LPAREN);
4955 : ExpressionT condition = ParseExpression();
4956 3449459 : Expect(Token::RPAREN);
4957 :
4958 : SourceRange then_range, else_range;
4959 : StatementT then_statement = impl()->NullStatement();
4960 : {
4961 : SourceRangeScope range_scope(scanner(), &then_range);
4962 : // Make a copy of {labels} to avoid conflicts with any
4963 : // labels that may be applied to the else clause below.
4964 : auto labels_copy =
4965 : labels == nullptr
4966 : ? labels
4967 3450030 : : new (zone()) ZonePtrList<const AstRawString>(*labels, zone());
4968 3449464 : then_statement = ParseScopedStatement(labels_copy);
4969 : }
4970 :
4971 : StatementT else_statement = impl()->NullStatement();
4972 3449451 : if (Check(Token::ELSE)) {
4973 393595 : else_statement = ParseScopedStatement(labels);
4974 : else_range = SourceRange::ContinuationOf(then_range, end_position());
4975 : } else {
4976 : else_statement = factory()->EmptyStatement();
4977 : }
4978 : StatementT stmt =
4979 : factory()->NewIfStatement(condition, then_statement, else_statement, pos);
4980 : impl()->RecordIfStatementSourceRange(stmt, then_range, else_range);
4981 3449449 : return stmt;
4982 : }
4983 :
4984 : template <typename Impl>
4985 : typename ParserBase<Impl>::StatementT
4986 54367 : ParserBase<Impl>::ParseContinueStatement() {
4987 : // ContinueStatement ::
4988 : // 'continue' Identifier? ';'
4989 :
4990 : int pos = peek_position();
4991 : Consume(Token::CONTINUE);
4992 : IdentifierT label = impl()->NullIdentifier();
4993 : Token::Value tok = peek();
4994 108562 : if (!scanner()->HasLineTerminatorBeforeNext() &&
4995 : !Token::IsAutoSemicolon(tok)) {
4996 : // ECMA allows "eval" or "arguments" as labels even in strict mode.
4997 : label = ParseIdentifier();
4998 : }
4999 13655 : IterationStatementT target = impl()->LookupContinueTarget(label);
5000 13655 : if (impl()->IsNull(target)) {
5001 : // Illegal continue statement.
5002 : MessageTemplate message = MessageTemplate::kIllegalContinue;
5003 457 : BreakableStatementT breakable_target = impl()->LookupBreakTarget(label);
5004 457 : if (impl()->IsNull(label)) {
5005 : message = MessageTemplate::kNoIterationStatement;
5006 362 : } else if (impl()->IsNull(breakable_target)) {
5007 : message = MessageTemplate::kUnknownLabel;
5008 : }
5009 457 : ReportMessage(message, label);
5010 457 : return impl()->NullStatement();
5011 : }
5012 53911 : ExpectSemicolon();
5013 : StatementT stmt = factory()->NewContinueStatement(target, pos);
5014 : impl()->RecordJumpStatementSourceRange(stmt, end_position());
5015 40713 : return stmt;
5016 : }
5017 :
5018 : template <typename Impl>
5019 192624 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement(
5020 : ZonePtrList<const AstRawString>* labels) {
5021 : // BreakStatement ::
5022 : // 'break' Identifier? ';'
5023 :
5024 : int pos = peek_position();
5025 : Consume(Token::BREAK);
5026 : IdentifierT label = impl()->NullIdentifier();
5027 : Token::Value tok = peek();
5028 385007 : if (!scanner()->HasLineTerminatorBeforeNext() &&
5029 : !Token::IsAutoSemicolon(tok)) {
5030 : // ECMA allows "eval" or "arguments" as labels even in strict mode.
5031 : label = ParseIdentifier();
5032 : }
5033 : // Parse labeled break statements that target themselves into
5034 : // empty statements, e.g. 'l1: l2: l3: break l2;'
5035 50586 : if (!impl()->IsNull(label) && impl()->ContainsLabel(labels, label)) {
5036 99 : ExpectSemicolon();
5037 99 : return factory()->EmptyStatement();
5038 : }
5039 43167 : BreakableStatementT target = impl()->LookupBreakTarget(label);
5040 43167 : if (impl()->IsNull(target)) {
5041 : // Illegal break statement.
5042 : MessageTemplate message = MessageTemplate::kIllegalBreak;
5043 133 : if (!impl()->IsNull(label)) {
5044 : message = MessageTemplate::kUnknownLabel;
5045 : }
5046 133 : ReportMessage(message, label);
5047 133 : return impl()->NullStatement();
5048 : }
5049 192392 : ExpectSemicolon();
5050 : StatementT stmt = factory()->NewBreakStatement(target, pos);
5051 : impl()->RecordJumpStatementSourceRange(stmt, end_position());
5052 149359 : return stmt;
5053 : }
5054 :
5055 : template <typename Impl>
5056 3600289 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseReturnStatement() {
5057 : // ReturnStatement ::
5058 : // 'return' [no line terminator] Expression? ';'
5059 :
5060 : // Consume the return token. It is necessary to do that before
5061 : // reporting any errors on it, because of the way errors are
5062 : // reported (underlining).
5063 : Consume(Token::RETURN);
5064 3600337 : Scanner::Location loc = scanner()->location();
5065 :
5066 : switch (GetDeclarationScope()->scope_type()) {
5067 : case SCRIPT_SCOPE:
5068 : case EVAL_SCOPE:
5069 : case MODULE_SCOPE:
5070 103 : impl()->ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
5071 103 : return impl()->NullStatement();
5072 : default:
5073 : break;
5074 : }
5075 :
5076 : Token::Value tok = peek();
5077 : ExpressionT return_value = impl()->NullExpression();
5078 7200256 : if (scanner()->HasLineTerminatorBeforeNext() || Token::IsAutoSemicolon(tok)) {
5079 646397 : if (IsDerivedConstructor(function_state_->kind())) {
5080 39 : ExpressionParsingScope expression_scope(impl());
5081 15 : return_value = impl()->ThisExpression();
5082 39 : expression_scope.ValidateExpression();
5083 : }
5084 : } else {
5085 : return_value = ParseExpression();
5086 : }
5087 3600246 : ExpectSemicolon();
5088 :
5089 987844 : return_value = impl()->RewriteReturn(return_value, loc.beg_pos);
5090 : int continuation_pos = end_position();
5091 : StatementT stmt =
5092 3600246 : BuildReturnStatement(return_value, loc.beg_pos, continuation_pos);
5093 : impl()->RecordJumpStatementSourceRange(stmt, end_position());
5094 2612384 : return stmt;
5095 : }
5096 :
5097 : template <typename Impl>
5098 101441 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWithStatement(
5099 : ZonePtrList<const AstRawString>* labels) {
5100 : // WithStatement ::
5101 : // 'with' '(' Expression ')' Statement
5102 :
5103 : Consume(Token::WITH);
5104 : int pos = position();
5105 :
5106 101441 : if (is_strict(language_mode())) {
5107 701 : ReportMessage(MessageTemplate::kStrictWith);
5108 701 : return impl()->NullStatement();
5109 : }
5110 :
5111 100740 : Expect(Token::LPAREN);
5112 : ExpressionT expr = ParseExpression();
5113 100740 : Expect(Token::RPAREN);
5114 :
5115 : Scope* with_scope = NewScope(WITH_SCOPE);
5116 : StatementT body = impl()->NullStatement();
5117 : {
5118 100740 : BlockState block_state(&scope_, with_scope);
5119 100740 : with_scope->set_start_position(scanner()->peek_location().beg_pos);
5120 : body = ParseStatement(labels, nullptr);
5121 : with_scope->set_end_position(end_position());
5122 : }
5123 38429 : return factory()->NewWithStatement(with_scope, expr, body, pos);
5124 : }
5125 :
5126 : template <typename Impl>
5127 18030 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDoWhileStatement(
5128 : ZonePtrList<const AstRawString>* labels,
5129 : ZonePtrList<const AstRawString>* own_labels) {
5130 : // DoStatement ::
5131 : // 'do' Statement 'while' '(' Expression ')' ';'
5132 18030 : typename FunctionState::LoopScope loop_scope(function_state_);
5133 :
5134 : auto loop =
5135 : factory()->NewDoWhileStatement(labels, own_labels, peek_position());
5136 : TargetT target(this, loop);
5137 :
5138 : SourceRange body_range;
5139 : StatementT body = impl()->NullStatement();
5140 :
5141 : Consume(Token::DO);
5142 :
5143 18030 : CheckStackOverflow();
5144 : {
5145 : SourceRangeScope range_scope(scanner(), &body_range);
5146 : body = ParseStatement(nullptr, nullptr);
5147 : }
5148 18030 : Expect(Token::WHILE);
5149 18030 : Expect(Token::LPAREN);
5150 :
5151 : ExpressionT cond = ParseExpression();
5152 18030 : Expect(Token::RPAREN);
5153 :
5154 : // Allow do-statements to be terminated with and without
5155 : // semi-colons. This allows code such as 'do;while(0)return' to
5156 : // parse, which would not be the case if we had used the
5157 : // ExpectSemicolon() functionality here.
5158 : Check(Token::SEMICOLON);
5159 :
5160 : loop->Initialize(cond, body);
5161 : impl()->RecordIterationStatementSourceRange(loop, body_range);
5162 :
5163 31969 : return loop;
5164 : }
5165 :
5166 : template <typename Impl>
5167 35668 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWhileStatement(
5168 : ZonePtrList<const AstRawString>* labels,
5169 : ZonePtrList<const AstRawString>* own_labels) {
5170 : // WhileStatement ::
5171 : // 'while' '(' Expression ')' Statement
5172 35668 : typename FunctionState::LoopScope loop_scope(function_state_);
5173 :
5174 : auto loop = factory()->NewWhileStatement(labels, own_labels, peek_position());
5175 : TargetT target(this, loop);
5176 :
5177 : SourceRange body_range;
5178 : StatementT body = impl()->NullStatement();
5179 :
5180 : Consume(Token::WHILE);
5181 35668 : Expect(Token::LPAREN);
5182 : ExpressionT cond = ParseExpression();
5183 35668 : Expect(Token::RPAREN);
5184 : {
5185 : SourceRangeScope range_scope(scanner(), &body_range);
5186 : body = ParseStatement(nullptr, nullptr);
5187 : }
5188 :
5189 : loop->Initialize(cond, body);
5190 : impl()->RecordIterationStatementSourceRange(loop, body_range);
5191 :
5192 54148 : return loop;
5193 : }
5194 :
5195 : template <typename Impl>
5196 309639 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseThrowStatement() {
5197 : // ThrowStatement ::
5198 : // 'throw' Expression ';'
5199 :
5200 : Consume(Token::THROW);
5201 : int pos = position();
5202 309643 : if (scanner()->HasLineTerminatorBeforeNext()) {
5203 177 : ReportMessage(MessageTemplate::kNewlineAfterThrow);
5204 177 : return impl()->NullStatement();
5205 : }
5206 : ExpressionT exception = ParseExpression();
5207 309465 : ExpectSemicolon();
5208 :
5209 : StatementT stmt = impl()->NewThrowStatement(exception, pos);
5210 : impl()->RecordThrowSourceRange(stmt, end_position());
5211 :
5212 267697 : return stmt;
5213 : }
5214 :
5215 : template <typename Impl>
5216 136206 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseSwitchStatement(
5217 : ZonePtrList<const AstRawString>* labels) {
5218 : // SwitchStatement ::
5219 : // 'switch' '(' Expression ')' '{' CaseClause* '}'
5220 : // CaseClause ::
5221 : // 'case' Expression ':' StatementList
5222 : // 'default' ':' StatementList
5223 :
5224 : int switch_pos = peek_position();
5225 :
5226 : Consume(Token::SWITCH);
5227 136224 : Expect(Token::LPAREN);
5228 : ExpressionT tag = ParseExpression();
5229 136224 : Expect(Token::RPAREN);
5230 :
5231 : auto switch_statement =
5232 14375 : factory()->NewSwitchStatement(labels, tag, switch_pos);
5233 :
5234 : {
5235 136224 : BlockState cases_block_state(zone(), &scope_);
5236 : scope()->set_start_position(switch_pos);
5237 : scope()->SetNonlinear();
5238 : TargetT target(this, switch_statement);
5239 :
5240 : bool default_seen = false;
5241 136223 : Expect(Token::LBRACE);
5242 1362704 : while (peek() != Token::RBRACE) {
5243 : // An empty label indicates the default case.
5244 : ExpressionT label = impl()->NullExpression();
5245 : StatementListT statements(pointer_buffer());
5246 : SourceRange clause_range;
5247 : {
5248 : SourceRangeScope range_scope(scanner(), &clause_range);
5249 1227724 : if (Check(Token::CASE)) {
5250 : label = ParseExpression();
5251 : } else {
5252 127917 : Expect(Token::DEFAULT);
5253 127919 : if (default_seen) {
5254 18 : ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
5255 18 : return impl()->NullStatement();
5256 : }
5257 : default_seen = true;
5258 : }
5259 1227723 : Expect(Token::COLON);
5260 2323638 : while (peek() != Token::CASE && peek() != Token::DEFAULT &&
5261 : peek() != Token::RBRACE) {
5262 1097151 : StatementT stat = ParseStatementListItem();
5263 1097147 : if (impl()->IsNull(stat)) return stat;
5264 106768 : if (stat->IsEmptyStatement()) continue;
5265 : statements.Add(stat);
5266 : }
5267 : }
5268 91625 : auto clause = factory()->NewCaseClause(label, statements);
5269 : impl()->RecordCaseClauseSourceRange(clause, clause_range);
5270 91625 : switch_statement->cases()->Add(clause, zone());
5271 : }
5272 134991 : Expect(Token::RBRACE);
5273 :
5274 : int end_pos = end_position();
5275 : scope()->set_end_position(end_pos);
5276 : impl()->RecordSwitchStatementSourceRange(switch_statement, end_pos);
5277 134990 : Scope* switch_scope = scope()->FinalizeBlockScope();
5278 134991 : if (switch_scope != nullptr) {
5279 922 : return impl()->RewriteSwitchStatement(switch_statement, switch_scope);
5280 : }
5281 120009 : return switch_statement;
5282 : }
5283 : }
5284 :
5285 : template <typename Impl>
5286 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseTryStatement() {
5287 : // TryStatement ::
5288 : // 'try' Block Catch
5289 : // 'try' Block Finally
5290 : // 'try' Block Catch Finally
5291 : //
5292 : // Catch ::
5293 : // 'catch' '(' Identifier ')' Block
5294 : //
5295 : // Finally ::
5296 : // 'finally' Block
5297 :
5298 : Consume(Token::TRY);
5299 : int pos = position();
5300 :
5301 410372 : BlockT try_block = ParseBlock(nullptr);
5302 :
5303 : CatchInfo catch_info(this);
5304 :
5305 410343 : if (peek() != Token::CATCH && peek() != Token::FINALLY) {
5306 1029 : ReportMessage(MessageTemplate::kNoCatchOrFinally);
5307 : return impl()->NullStatement();
5308 : }
5309 :
5310 : SourceRange catch_range, finally_range;
5311 :
5312 : BlockT catch_block = impl()->NullBlock();
5313 : {
5314 : SourceRangeScope catch_range_scope(scanner(), &catch_range);
5315 409312 : if (Check(Token::CATCH)) {
5316 : bool has_binding;
5317 : has_binding = Check(Token::LPAREN);
5318 :
5319 371316 : if (has_binding) {
5320 91600 : catch_info.scope = NewScope(CATCH_SCOPE);
5321 369999 : catch_info.scope->set_start_position(scanner()->location().beg_pos);
5322 :
5323 : {
5324 369999 : BlockState catch_block_state(&scope_, catch_info.scope);
5325 : StatementListT catch_statements(pointer_buffer());
5326 :
5327 : // Create a block scope to hold any lexical declarations created
5328 : // as part of destructuring the catch parameter.
5329 : {
5330 369999 : BlockState catch_variable_block_state(zone(), &scope_);
5331 : scope()->set_start_position(position());
5332 :
5333 370005 : if (peek_any_identifier()) {
5334 361030 : IdentifierT identifier = ParseNonRestrictedIdentifier();
5335 361027 : RETURN_IF_PARSE_ERROR;
5336 172160 : catch_info.variable = impl()->DeclareCatchVariableName(
5337 : catch_info.scope, identifier);
5338 : } else {
5339 8975 : catch_info.variable = catch_info.scope->DeclareCatchVariableName(
5340 : ast_value_factory()->dot_catch_string());
5341 :
5342 : auto declaration_it = scope()->declarations()->end();
5343 :
5344 : VariableDeclarationParsingScope destructuring(
5345 : impl(), VariableMode::kLet, nullptr);
5346 8975 : catch_info.pattern = ParseBindingPattern();
5347 :
5348 : int initializer_position = end_position();
5349 : auto declaration_end = scope()->declarations()->end();
5350 14804 : for (; declaration_it != declaration_end; ++declaration_it) {
5351 : declaration_it->var()->set_initializer_position(
5352 : initializer_position);
5353 : }
5354 :
5355 8975 : RETURN_IF_PARSE_ERROR;
5356 3024 : catch_statements.Add(impl()->RewriteCatchPattern(&catch_info));
5357 : }
5358 :
5359 364843 : Expect(Token::RPAREN);
5360 :
5361 364838 : BlockT inner_block = ParseBlock(nullptr);
5362 : catch_statements.Add(inner_block);
5363 :
5364 : // Check for `catch(e) { let e; }` and similar errors.
5365 89102 : if (!impl()->HasCheckedSyntax()) {
5366 : Scope* inner_scope = inner_block->scope();
5367 364040 : if (inner_scope != nullptr) {
5368 : const AstRawString* conflict = nullptr;
5369 1650 : if (impl()->IsNull(catch_info.pattern)) {
5370 809 : const AstRawString* name = catch_info.variable->raw_name();
5371 1120 : if (inner_scope->LookupLocal(name)) conflict = name;
5372 : } else {
5373 530 : conflict = inner_scope->FindVariableDeclaredIn(
5374 : scope(), VariableMode::kVar);
5375 : }
5376 1650 : if (conflict != nullptr) {
5377 354 : impl()->ReportVarRedeclarationIn(conflict, inner_scope);
5378 : }
5379 : }
5380 : }
5381 :
5382 : scope()->set_end_position(end_position());
5383 89102 : catch_block = factory()->NewBlock(false, catch_statements);
5384 364838 : catch_block->set_scope(scope()->FinalizeBlockScope());
5385 : }
5386 : }
5387 :
5388 89102 : catch_info.scope->set_end_position(end_position());
5389 : } else {
5390 1310 : catch_block = ParseBlock(nullptr);
5391 : }
5392 : }
5393 : }
5394 :
5395 : BlockT finally_block = impl()->NullBlock();
5396 : DCHECK(has_error() || peek() == Token::FINALLY ||
5397 : !impl()->IsNull(catch_block));
5398 : {
5399 : SourceRangeScope range_scope(scanner(), &finally_range);
5400 404167 : if (Check(Token::FINALLY)) {
5401 40169 : finally_block = ParseBlock(nullptr);
5402 : }
5403 : }
5404 :
5405 404175 : RETURN_IF_PARSE_ERROR;
5406 : return impl()->RewriteTryStatement(try_block, catch_block, catch_range,
5407 : finally_block, finally_range, catch_info,
5408 93173 : pos);
5409 : }
5410 :
5411 : template <typename Impl>
5412 810126 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
5413 : ZonePtrList<const AstRawString>* labels,
5414 : ZonePtrList<const AstRawString>* own_labels) {
5415 : // Either a standard for loop
5416 : // for (<init>; <cond>; <next>) { ... }
5417 : // or a for-each loop
5418 : // for (<each> of|in <iterable>) { ... }
5419 : //
5420 : // We parse a declaration/expression after the 'for (' and then read the first
5421 : // expression/declaration before we know if this is a for or a for-each.
5422 810126 : typename FunctionState::LoopScope loop_scope(function_state_);
5423 :
5424 : int stmt_pos = peek_position();
5425 810126 : ForInfo for_info(this);
5426 :
5427 : Consume(Token::FOR);
5428 810143 : Expect(Token::LPAREN);
5429 :
5430 810122 : if (peek() == Token::CONST || (peek() == Token::LET && IsNextLetKeyword())) {
5431 : // The initializer contains lexical declarations,
5432 : // so create an in-between scope.
5433 256254 : BlockState for_state(zone(), &scope_);
5434 : scope()->set_start_position(position());
5435 :
5436 : // Also record whether inner functions or evals are found inside
5437 : // this loop, as this information is used to simplify the desugaring
5438 : // if none are found.
5439 : typename FunctionState::FunctionOrEvalRecordingScope recording_scope(
5440 256255 : function_state_);
5441 :
5442 : // Create an inner block scope which will be the parent scope of scopes
5443 : // possibly created by ParseVariableDeclarations.
5444 : Scope* inner_block_scope = NewScope(BLOCK_SCOPE);
5445 : {
5446 : BlockState inner_state(&scope_, inner_block_scope);
5447 256255 : ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
5448 : &for_info.bound_names);
5449 : }
5450 : DCHECK(IsLexicalVariableMode(for_info.parsing_result.descriptor.mode));
5451 256256 : for_info.position = position();
5452 :
5453 256256 : if (CheckInOrOf(&for_info.mode)) {
5454 : scope()->set_is_hidden();
5455 : return ParseForEachStatementWithDeclarations(
5456 132378 : stmt_pos, &for_info, labels, own_labels, inner_block_scope);
5457 : }
5458 :
5459 123877 : Expect(Token::SEMICOLON);
5460 :
5461 : // Parse the remaining code in the inner block scope since the declaration
5462 : // above was parsed there. We'll finalize the unnecessary outer block scope
5463 : // after parsing the rest of the loop.
5464 : StatementT result = impl()->NullStatement();
5465 : inner_block_scope->set_start_position(scope()->start_position());
5466 : {
5467 : BlockState inner_state(&scope_, inner_block_scope);
5468 : StatementT init =
5469 123878 : impl()->BuildInitializationBlock(&for_info.parsing_result);
5470 :
5471 123878 : result = ParseStandardForLoopWithLexicalDeclarations(
5472 : stmt_pos, init, &for_info, labels, own_labels);
5473 : }
5474 123876 : Scope* finalized = scope()->FinalizeBlockScope();
5475 : DCHECK_NULL(finalized);
5476 : USE(finalized);
5477 123877 : return result;
5478 : }
5479 :
5480 : StatementT init = impl()->NullStatement();
5481 553869 : if (peek() == Token::VAR) {
5482 384188 : ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
5483 : &for_info.bound_names);
5484 : DCHECK_EQ(for_info.parsing_result.descriptor.mode, VariableMode::kVar);
5485 384205 : for_info.position = scanner()->location().beg_pos;
5486 :
5487 384205 : if (CheckInOrOf(&for_info.mode)) {
5488 : return ParseForEachStatementWithDeclarations(stmt_pos, &for_info, labels,
5489 32898 : own_labels, scope());
5490 : }
5491 :
5492 196103 : init = impl()->BuildInitializationBlock(&for_info.parsing_result);
5493 169681 : } else if (peek() != Token::SEMICOLON) {
5494 : // The initializer does not contain declarations.
5495 : int lhs_beg_pos = peek_position();
5496 : int lhs_end_pos;
5497 : bool is_for_each;
5498 : ExpressionT expression;
5499 : {
5500 152857 : ExpressionParsingScope parsing_scope(impl());
5501 : AcceptINScope scope(this, false);
5502 152857 : expression = ParseExpressionCoverGrammar();
5503 : // Initializer is reference followed by in/of.
5504 : lhs_end_pos = end_position();
5505 152857 : is_for_each = CheckInOrOf(&for_info.mode);
5506 152856 : if (is_for_each) {
5507 116967 : if (expression->IsPattern()) {
5508 24210 : parsing_scope.ValidatePattern(expression, lhs_beg_pos, lhs_end_pos);
5509 : } else {
5510 92757 : expression = parsing_scope.ValidateAndRewriteReference(
5511 : expression, lhs_beg_pos, lhs_end_pos);
5512 : }
5513 : } else {
5514 35889 : parsing_scope.ValidateExpression();
5515 : }
5516 : }
5517 :
5518 152856 : if (is_for_each) {
5519 : return ParseForEachStatementWithoutDeclarations(
5520 : stmt_pos, expression, lhs_beg_pos, lhs_end_pos, &for_info, labels,
5521 116967 : own_labels);
5522 : }
5523 : // Initializer is just an expression.
5524 : init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
5525 : }
5526 :
5527 404015 : Expect(Token::SEMICOLON);
5528 :
5529 : // Standard 'for' loop, we have parsed the initializer at this point.
5530 404013 : ExpressionT cond = impl()->NullExpression();
5531 404013 : StatementT next = impl()->NullStatement();
5532 404013 : StatementT body = impl()->NullStatement();
5533 : ForStatementT loop =
5534 404013 : ParseStandardForLoop(stmt_pos, labels, own_labels, &cond, &next, &body);
5535 404019 : RETURN_IF_PARSE_ERROR;
5536 223909 : loop->Initialize(init, cond, next, body);
5537 397485 : return loop;
5538 : }
5539 :
5540 : template <typename Impl>
5541 : typename ParserBase<Impl>::StatementT
5542 165276 : ParserBase<Impl>::ParseForEachStatementWithDeclarations(
5543 : int stmt_pos, ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
5544 : ZonePtrList<const AstRawString>* own_labels, Scope* inner_block_scope) {
5545 : // Just one declaration followed by in/of.
5546 165276 : if (for_info->parsing_result.declarations.size() != 1) {
5547 6012 : impl()->ReportMessageAt(for_info->parsing_result.bindings_loc,
5548 : MessageTemplate::kForInOfLoopMultiBindings,
5549 : ForEachStatement::VisitModeString(for_info->mode));
5550 3006 : return impl()->NullStatement();
5551 : }
5552 171025 : if (for_info->parsing_result.first_initializer_loc.IsValid() &&
5553 : (is_strict(language_mode()) ||
5554 2489 : for_info->mode == ForEachStatement::ITERATE ||
5555 1443 : IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) ||
5556 213 : !impl()->IsIdentifier(
5557 : for_info->parsing_result.declarations[0].pattern))) {
5558 7158 : impl()->ReportMessageAt(for_info->parsing_result.first_initializer_loc,
5559 : MessageTemplate::kForInOfLoopInitializer,
5560 : ForEachStatement::VisitModeString(for_info->mode));
5561 3579 : return impl()->NullStatement();
5562 : }
5563 :
5564 91408 : BlockT init_block = impl()->RewriteForVarInLegacy(*for_info);
5565 :
5566 : auto loop = factory()->NewForEachStatement(for_info->mode, labels, own_labels,
5567 182816 : stmt_pos);
5568 : TargetT target(this, loop);
5569 :
5570 : ExpressionT enumerable = impl()->NullExpression();
5571 158691 : if (for_info->mode == ForEachStatement::ITERATE) {
5572 : AcceptINScope scope(this, true);
5573 : enumerable = ParseAssignmentExpression();
5574 : } else {
5575 : enumerable = ParseExpression();
5576 : }
5577 :
5578 158690 : Expect(Token::RPAREN);
5579 :
5580 158690 : if (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode)) {
5581 : inner_block_scope->set_start_position(position());
5582 : }
5583 :
5584 91407 : ExpressionT each_variable = impl()->NullExpression();
5585 91407 : BlockT body_block = impl()->NullBlock();
5586 : {
5587 158690 : BlockState block_state(&scope_, inner_block_scope);
5588 :
5589 : SourceRange body_range;
5590 91407 : StatementT body = impl()->NullStatement();
5591 : {
5592 : SourceRangeScope range_scope(scanner(), &body_range);
5593 91408 : body = ParseStatement(nullptr, nullptr);
5594 : }
5595 : impl()->RecordIterationStatementSourceRange(loop, body_range);
5596 :
5597 91408 : impl()->DesugarBindingInForEachStatement(for_info, &body_block,
5598 : &each_variable);
5599 182814 : body_block->statements()->Add(body, zone());
5600 :
5601 158690 : if (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode)) {
5602 : scope()->set_end_position(end_position());
5603 128008 : body_block->set_scope(scope()->FinalizeBlockScope());
5604 : }
5605 : }
5606 :
5607 91407 : loop->Initialize(each_variable, enumerable, body_block);
5608 :
5609 91407 : init_block = impl()->CreateForEachStatementTDZ(init_block, *for_info);
5610 :
5611 : // Parsed for-in loop w/ variable declarations.
5612 158691 : if (!impl()->IsNull(init_block)) {
5613 149816 : init_block->statements()->Add(loop, zone());
5614 128221 : if (IsLexicalVariableMode(for_info->parsing_result.descriptor.mode)) {
5615 : scope()->set_end_position(end_position());
5616 128009 : init_block->set_scope(scope()->FinalizeBlockScope());
5617 : }
5618 53313 : return init_block;
5619 : }
5620 :
5621 13970 : return loop;
5622 : }
5623 :
5624 : template <typename Impl>
5625 : typename ParserBase<Impl>::StatementT
5626 116967 : ParserBase<Impl>::ParseForEachStatementWithoutDeclarations(
5627 : int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos,
5628 : ForInfo* for_info, ZonePtrList<const AstRawString>* labels,
5629 : ZonePtrList<const AstRawString>* own_labels) {
5630 : auto loop = factory()->NewForEachStatement(for_info->mode, labels, own_labels,
5631 119614 : stmt_pos);
5632 : TargetT target(this, loop);
5633 :
5634 : ExpressionT enumerable = impl()->NullExpression();
5635 116967 : if (for_info->mode == ForEachStatement::ITERATE) {
5636 : AcceptINScope scope(this, true);
5637 : enumerable = ParseAssignmentExpression();
5638 : } else {
5639 : enumerable = ParseExpression();
5640 : }
5641 :
5642 116967 : Expect(Token::RPAREN);
5643 :
5644 : StatementT body = impl()->NullStatement();
5645 : SourceRange body_range;
5646 : {
5647 : SourceRangeScope range_scope(scanner(), &body_range);
5648 : body = ParseStatement(nullptr, nullptr);
5649 : }
5650 : impl()->RecordIterationStatementSourceRange(loop, body_range);
5651 116967 : RETURN_IF_PARSE_ERROR;
5652 : loop->Initialize(expression, enumerable, body);
5653 96082 : return loop;
5654 : }
5655 :
5656 : template <typename Impl>
5657 : typename ParserBase<Impl>::StatementT
5658 123876 : ParserBase<Impl>::ParseStandardForLoopWithLexicalDeclarations(
5659 : int stmt_pos, StatementT init, ForInfo* for_info,
5660 : ZonePtrList<const AstRawString>* labels,
5661 : ZonePtrList<const AstRawString>* own_labels) {
5662 : // The condition and the next statement of the for loop must be parsed
5663 : // in a new scope.
5664 : Scope* inner_scope = NewScope(BLOCK_SCOPE);
5665 : ForStatementT loop = impl()->NullStatement();
5666 123877 : ExpressionT cond = impl()->NullExpression();
5667 123877 : StatementT next = impl()->NullStatement();
5668 123877 : StatementT body = impl()->NullStatement();
5669 : {
5670 123877 : BlockState block_state(&scope_, inner_scope);
5671 123877 : scope()->set_start_position(scanner()->location().beg_pos);
5672 123877 : loop =
5673 : ParseStandardForLoop(stmt_pos, labels, own_labels, &cond, &next, &body);
5674 123878 : RETURN_IF_PARSE_ERROR;
5675 : scope()->set_end_position(end_position());
5676 : }
5677 :
5678 : scope()->set_end_position(end_position());
5679 233740 : if (for_info->bound_names.length() > 0 &&
5680 116870 : function_state_->contains_function_or_eval()) {
5681 : scope()->set_is_hidden();
5682 : return impl()->DesugarLexicalBindingsInForStatement(
5683 17509 : loop, init, cond, next, body, inner_scope, *for_info);
5684 : } else {
5685 99031 : inner_scope = inner_scope->FinalizeBlockScope();
5686 : DCHECK_NULL(inner_scope);
5687 : USE(inner_scope);
5688 : }
5689 :
5690 99030 : Scope* for_scope = scope()->FinalizeBlockScope();
5691 99030 : if (for_scope != nullptr) {
5692 : // Rewrite a for statement of the form
5693 : // for (const x = i; c; n) b
5694 : //
5695 : // into
5696 : //
5697 : // {
5698 : // const x = i;
5699 : // for (; c; n) b
5700 : // }
5701 : //
5702 : DCHECK(!impl()->IsNull(init));
5703 39592 : BlockT block = factory()->NewBlock(2, false);
5704 39592 : block->statements()->Add(init, zone());
5705 39592 : block->statements()->Add(loop, zone());
5706 : block->set_scope(for_scope);
5707 39592 : loop->Initialize(impl()->NullStatement(), cond, next, body);
5708 99030 : return block;
5709 : }
5710 :
5711 0 : loop->Initialize(init, cond, next, body);
5712 0 : return loop;
5713 : }
5714 :
5715 : template <typename Impl>
5716 527871 : typename ParserBase<Impl>::ForStatementT ParserBase<Impl>::ParseStandardForLoop(
5717 : int stmt_pos, ZonePtrList<const AstRawString>* labels,
5718 : ZonePtrList<const AstRawString>* own_labels, ExpressionT* cond,
5719 : StatementT* next, StatementT* body) {
5720 : ForStatementT loop = factory()->NewForStatement(labels, own_labels, stmt_pos);
5721 : TargetT target(this, loop);
5722 :
5723 527871 : if (peek() != Token::SEMICOLON) {
5724 513702 : *cond = ParseExpression();
5725 : }
5726 527890 : Expect(Token::SEMICOLON);
5727 :
5728 527904 : if (peek() != Token::RPAREN) {
5729 : ExpressionT exp = ParseExpression();
5730 471597 : *next = factory()->NewExpressionStatement(exp, exp->position());
5731 : }
5732 527901 : Expect(Token::RPAREN);
5733 :
5734 : SourceRange body_range;
5735 : {
5736 : SourceRangeScope range_scope(scanner(), &body_range);
5737 527896 : *body = ParseStatement(nullptr, nullptr);
5738 : }
5739 : impl()->RecordIterationStatementSourceRange(loop, body_range);
5740 :
5741 527896 : return loop;
5742 : }
5743 :
5744 : template <typename Impl>
5745 128569 : typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
5746 : ZonePtrList<const AstRawString>* labels,
5747 : ZonePtrList<const AstRawString>* own_labels) {
5748 : // for await '(' ForDeclaration of AssignmentExpression ')'
5749 : DCHECK(is_async_function());
5750 128569 : typename FunctionState::LoopScope loop_scope(function_state_);
5751 :
5752 : int stmt_pos = peek_position();
5753 :
5754 128569 : ForInfo for_info(this);
5755 128569 : for_info.mode = ForEachStatement::ITERATE;
5756 :
5757 : // Create an in-between scope for let-bound iteration variables.
5758 128569 : BlockState for_state(zone(), &scope_);
5759 128569 : Expect(Token::FOR);
5760 128569 : Expect(Token::AWAIT);
5761 128569 : Expect(Token::LPAREN);
5762 128569 : scope()->set_start_position(scanner()->location().beg_pos);
5763 : scope()->set_is_hidden();
5764 :
5765 : auto loop = factory()->NewForOfStatement(labels, own_labels, stmt_pos,
5766 : IteratorType::kAsync);
5767 : // Two suspends: one for next() and one for return()
5768 128569 : function_state_->AddSuspend();
5769 128569 : function_state_->AddSuspend();
5770 :
5771 : TargetT target(this, loop);
5772 :
5773 34665 : ExpressionT each_variable = impl()->NullExpression();
5774 :
5775 : bool has_declarations = false;
5776 : Scope* inner_block_scope = NewScope(BLOCK_SCOPE);
5777 :
5778 162147 : if (peek() == Token::VAR || peek() == Token::CONST ||
5779 33578 : (peek() == Token::LET && IsNextLetKeyword())) {
5780 : // The initializer contains declarations
5781 : // 'for' 'await' '(' ForDeclaration 'of' AssignmentExpression ')'
5782 : // Statement
5783 : // 'for' 'await' '(' 'var' ForBinding 'of' AssignmentExpression ')'
5784 : // Statement
5785 : has_declarations = true;
5786 :
5787 : {
5788 : BlockState inner_state(&scope_, inner_block_scope);
5789 88802 : ParseVariableDeclarations(kForStatement, &for_info.parsing_result,
5790 : &for_info.bound_names);
5791 : }
5792 88802 : for_info.position = scanner()->location().beg_pos;
5793 :
5794 : // Only a single declaration is allowed in for-await-of loops
5795 88802 : if (for_info.parsing_result.declarations.size() != 1) {
5796 15760 : impl()->ReportMessageAt(for_info.parsing_result.bindings_loc,
5797 : MessageTemplate::kForInOfLoopMultiBindings,
5798 : "for-await-of");
5799 15760 : return impl()->NullStatement();
5800 : }
5801 :
5802 : // for-await-of's declarations do not permit initializers.
5803 73042 : if (for_info.parsing_result.first_initializer_loc.IsValid()) {
5804 14720 : impl()->ReportMessageAt(for_info.parsing_result.first_initializer_loc,
5805 : MessageTemplate::kForInOfLoopInitializer,
5806 : "for-await-of");
5807 14720 : return impl()->NullStatement();
5808 : }
5809 : } else {
5810 : // The initializer does not contain declarations.
5811 : // 'for' 'await' '(' LeftHandSideExpression 'of' AssignmentExpression ')'
5812 : // Statement
5813 : int lhs_beg_pos = peek_position();
5814 : BlockState inner_state(&scope_, inner_block_scope);
5815 39767 : ExpressionParsingScope parsing_scope(impl());
5816 12245 : ExpressionT lhs = each_variable = ParseLeftHandSideExpression();
5817 : int lhs_end_pos = end_position();
5818 :
5819 39767 : if (lhs->IsPattern()) {
5820 28070 : parsing_scope.ValidatePattern(lhs, lhs_beg_pos, lhs_end_pos);
5821 : } else {
5822 11697 : each_variable = parsing_scope.ValidateAndRewriteReference(
5823 : lhs, lhs_beg_pos, lhs_end_pos);
5824 : }
5825 : }
5826 :
5827 98089 : ExpectContextualKeyword(ast_value_factory()->of_string());
5828 :
5829 : const bool kAllowIn = true;
5830 : ExpressionT iterable = impl()->NullExpression();
5831 :
5832 : {
5833 : AcceptINScope scope(this, kAllowIn);
5834 : iterable = ParseAssignmentExpression();
5835 : }
5836 :
5837 98089 : Expect(Token::RPAREN);
5838 :
5839 26985 : StatementT body = impl()->NullStatement();
5840 : {
5841 : BlockState block_state(&scope_, inner_block_scope);
5842 98089 : scope()->set_start_position(scanner()->location().beg_pos);
5843 :
5844 : SourceRange body_range;
5845 : {
5846 : SourceRangeScope range_scope(scanner(), &body_range);
5847 26985 : body = ParseStatement(nullptr, nullptr);
5848 : scope()->set_end_position(end_position());
5849 : }
5850 : impl()->RecordIterationStatementSourceRange(loop, body_range);
5851 :
5852 98089 : if (has_declarations) {
5853 14740 : BlockT body_block = impl()->NullBlock();
5854 14740 : impl()->DesugarBindingInForEachStatement(&for_info, &body_block,
5855 : &each_variable);
5856 29480 : body_block->statements()->Add(body, zone());
5857 58322 : body_block->set_scope(scope()->FinalizeBlockScope());
5858 14740 : body = body_block;
5859 : } else {
5860 39767 : Scope* block_scope = scope()->FinalizeBlockScope();
5861 : DCHECK_NULL(block_scope);
5862 : USE(block_scope);
5863 : }
5864 : }
5865 :
5866 26985 : loop->Initialize(each_variable, iterable, body);
5867 :
5868 98089 : if (!has_declarations) {
5869 39767 : Scope* for_scope = scope()->FinalizeBlockScope();
5870 : DCHECK_NULL(for_scope);
5871 : USE(for_scope);
5872 27522 : return loop;
5873 : }
5874 :
5875 : BlockT init_block =
5876 14740 : impl()->CreateForEachStatementTDZ(impl()->NullBlock(), for_info);
5877 :
5878 : scope()->set_end_position(end_position());
5879 58322 : Scope* for_scope = scope()->FinalizeBlockScope();
5880 : // Parsed for-in loop w/ variable declarations.
5881 58322 : if (!impl()->IsNull(init_block)) {
5882 23456 : init_block->statements()->Add(loop, zone());
5883 : init_block->set_scope(for_scope);
5884 46516 : return init_block;
5885 : }
5886 : DCHECK_NULL(for_scope);
5887 8794 : return loop;
5888 : }
5889 :
5890 : template <typename Impl>
5891 452931 : void ParserBase<Impl>::CheckClassMethodName(IdentifierT name,
5892 : ParsePropertyKind type,
5893 : ParseFunctionFlags flags,
5894 : bool is_static,
5895 : bool* has_seen_constructor) {
5896 : DCHECK(type == ParsePropertyKind::kMethod || IsAccessor(type));
5897 :
5898 : AstValueFactory* avf = ast_value_factory();
5899 :
5900 452931 : if (is_static) {
5901 37993 : if (impl()->IdentifierEquals(name, avf->prototype_string())) {
5902 1094 : ReportMessage(MessageTemplate::kStaticPrototype);
5903 1094 : return;
5904 : }
5905 414938 : } else if (impl()->IdentifierEquals(name,
5906 : avf->private_constructor_string())) {
5907 960 : ReportMessage(MessageTemplate::kConstructorIsPrivate);
5908 960 : return;
5909 413978 : } else if (impl()->IdentifierEquals(name, avf->constructor_string())) {
5910 23817 : if (flags != ParseFunctionFlag::kIsNormal || IsAccessor(type)) {
5911 : MessageTemplate msg = (flags & ParseFunctionFlag::kIsGenerator) != 0
5912 : ? MessageTemplate::kConstructorIsGenerator
5913 : : (flags & ParseFunctionFlag::kIsAsync) != 0
5914 : ? MessageTemplate::kConstructorIsAsync
5915 1690 : : MessageTemplate::kConstructorIsAccessor;
5916 1008 : ReportMessage(msg);
5917 1008 : return;
5918 : }
5919 22809 : if (*has_seen_constructor) {
5920 98 : ReportMessage(MessageTemplate::kDuplicateConstructor);
5921 98 : return;
5922 : }
5923 22711 : *has_seen_constructor = true;
5924 22711 : return;
5925 : }
5926 : }
5927 :
5928 : template <typename Impl>
5929 91868 : void ParserBase<Impl>::CheckClassFieldName(IdentifierT name, bool is_static) {
5930 : AstValueFactory* avf = ast_value_factory();
5931 91868 : if (is_static && impl()->IdentifierEquals(name, avf->prototype_string())) {
5932 166 : ReportMessage(MessageTemplate::kStaticPrototype);
5933 166 : return;
5934 : }
5935 :
5936 91702 : if (impl()->IdentifierEquals(name, avf->constructor_string()) ||
5937 : impl()->IdentifierEquals(name, avf->private_constructor_string())) {
5938 1132 : ReportMessage(MessageTemplate::kConstructorClassField);
5939 1132 : return;
5940 : }
5941 : }
5942 :
5943 : #undef RETURN_IF_PARSE_ERROR
5944 :
5945 : } // namespace internal
5946 : } // namespace v8
5947 :
5948 : #endif // V8_PARSING_PARSER_BASE_H_
|