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