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 "src/ast/ast.h" 9 #include "src/ast/scopes.h" 10 #include "src/bailout-reason.h" 11 #include "src/base/hashmap.h" 12 #include "src/counters.h" 13 #include "src/globals.h" 14 #include "src/messages.h" 15 #include "src/parsing/expression-classifier.h" 16 #include "src/parsing/func-name-inferrer.h" 17 #include "src/parsing/scanner.h" 18 #include "src/parsing/token.h" 19 20 namespace v8 { 21 namespace internal { 22 23 24 enum FunctionNameValidity { 25 kFunctionNameIsStrictReserved, 26 kSkipFunctionNameCheck, 27 kFunctionNameValidityUnknown 28 }; 29 30 enum AllowLabelledFunctionStatement { 31 kAllowLabelledFunctionStatement, 32 kDisallowLabelledFunctionStatement, 33 }; 34 35 enum class ParseFunctionFlags { 36 kIsNormal = 0, 37 kIsGenerator = 1, 38 kIsAsync = 2, 39 kIsDefault = 4 40 }; 41 42 static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs, 43 ParseFunctionFlags rhs) { 44 typedef unsigned char T; 45 return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) | 46 static_cast<T>(rhs)); 47 } 48 49 static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs, 50 const ParseFunctionFlags& rhs) { 51 lhs = lhs | rhs; 52 return lhs; 53 } 54 55 static inline bool operator&(ParseFunctionFlags bitfield, 56 ParseFunctionFlags mask) { 57 typedef unsigned char T; 58 return static_cast<T>(bitfield) & static_cast<T>(mask); 59 } 60 61 struct FormalParametersBase { 62 explicit FormalParametersBase(DeclarationScope* scope) : scope(scope) {} 63 64 int num_parameters() const { 65 // Don't include the rest parameter into the function's formal parameter 66 // count (esp. the SharedFunctionInfo::internal_formal_parameter_count, 67 // which says whether we need to create an arguments adaptor frame). 68 return arity - has_rest; 69 } 70 71 void UpdateArityAndFunctionLength(bool is_optional, bool is_rest) { 72 if (!is_optional && !is_rest && function_length == arity) { 73 ++function_length; 74 } 75 ++arity; 76 } 77 78 DeclarationScope* scope; 79 bool has_rest = false; 80 bool is_simple = true; 81 int materialized_literals_count = 0; 82 int function_length = 0; 83 int arity = 0; 84 }; 85 86 87 // ---------------------------------------------------------------------------- 88 // The CHECK_OK macro is a convenient macro to enforce error 89 // handling for functions that may fail (by returning !*ok). 90 // 91 // CAUTION: This macro appends extra statements after a call, 92 // thus it must never be used where only a single statement 93 // is correct (e.g. an if statement branch w/o braces)! 94 95 #define CHECK_OK_CUSTOM(x, ...) ok); \ 96 if (!*ok) return impl()->x(__VA_ARGS__); \ 97 ((void)0 98 #define DUMMY ) // to make indentation work 99 #undef DUMMY 100 101 // Used in functions where the return type is ExpressionT. 102 #define CHECK_OK CHECK_OK_CUSTOM(EmptyExpression) 103 104 #define CHECK_OK_VOID ok); \ 105 if (!*ok) return; \ 106 ((void)0 107 #define DUMMY ) // to make indentation work 108 #undef DUMMY 109 110 // Common base class template shared between parser and pre-parser. 111 // The Impl parameter is the actual class of the parser/pre-parser, 112 // following the Curiously Recurring Template Pattern (CRTP). 113 // The structure of the parser objects is roughly the following: 114 // 115 // // A structure template containing type definitions, needed to 116 // // avoid a cyclic dependency. 117 // template <typename Impl> 118 // struct ParserTypes; 119 // 120 // // The parser base object, which should just implement pure 121 // // parser behavior. The Impl parameter is the actual derived 122 // // class (according to CRTP), which implements impure parser 123 // // behavior. 124 // template <typename Impl> 125 // class ParserBase { ... }; 126 // 127 // // And then, for each parser variant (e.g., parser, preparser, etc): 128 // class Parser; 129 // 130 // template <> 131 // class ParserTypes<Parser> { ... }; 132 // 133 // class Parser : public ParserBase<Parser> { ... }; 134 // 135 // The parser base object implements pure parsing, according to the 136 // language grammar. Different parser implementations may exhibit 137 // different parser-driven behavior that is not considered as pure 138 // parsing, e.g., early error detection and reporting, AST generation, etc. 139 140 // The ParserTypes structure encapsulates the differences in the 141 // types used in parsing methods. E.g., Parser methods use Expression* 142 // and PreParser methods use PreParserExpression. For any given parser 143 // implementation class Impl, it is expected to contain the following typedefs: 144 // 145 // template <> 146 // struct ParserTypes<Impl> { 147 // // Synonyms for ParserBase<Impl> and Impl, respectively. 148 // typedef Base; 149 // typedef Impl; 150 // // TODO(nikolaos): this one will probably go away, as it is 151 // // not related to pure parsing. 152 // typedef Variable; 153 // // Return types for traversing functions. 154 // typedef Identifier; 155 // typedef Expression; 156 // typedef FunctionLiteral; 157 // typedef ObjectLiteralProperty; 158 // typedef ClassLiteralProperty; 159 // typedef ExpressionList; 160 // typedef ObjectPropertyList; 161 // typedef ClassPropertyList; 162 // typedef FormalParameters; 163 // typedef Statement; 164 // typedef StatementList; 165 // typedef Block; 166 // typedef BreakableStatement; 167 // typedef IterationStatement; 168 // // For constructing objects returned by the traversing functions. 169 // typedef Factory; 170 // // For other implementation-specific tasks. 171 // typedef Target; 172 // typedef TargetScope; 173 // }; 174 175 template <typename Impl> 176 struct ParserTypes; 177 178 template <typename Impl> 179 class ParserBase { 180 public: 181 // Shorten type names defined by ParserTypes<Impl>. 182 typedef ParserTypes<Impl> Types; 183 typedef typename Types::Identifier IdentifierT; 184 typedef typename Types::Expression ExpressionT; 185 typedef typename Types::FunctionLiteral FunctionLiteralT; 186 typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT; 187 typedef typename Types::ClassLiteralProperty ClassLiteralPropertyT; 188 typedef typename Types::ExpressionList ExpressionListT; 189 typedef typename Types::FormalParameters FormalParametersT; 190 typedef typename Types::Statement StatementT; 191 typedef typename Types::StatementList StatementListT; 192 typedef typename Types::Block BlockT; 193 typedef typename v8::internal::ExpressionClassifier<Types> 194 ExpressionClassifier; 195 196 // All implementation-specific methods must be called through this. 197 Impl* impl() { return static_cast<Impl*>(this); } 198 const Impl* impl() const { return static_cast<const Impl*>(this); } 199 200 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, 201 v8::Extension* extension, AstValueFactory* ast_value_factory, 202 RuntimeCallStats* runtime_call_stats, 203 bool parsing_on_main_thread = true) 204 : scope_(nullptr), 205 function_state_(nullptr), 206 extension_(extension), 207 fni_(nullptr), 208 ast_value_factory_(ast_value_factory), 209 ast_node_factory_(ast_value_factory), 210 runtime_call_stats_(runtime_call_stats), 211 parsing_on_main_thread_(parsing_on_main_thread), 212 parsing_module_(false), 213 stack_limit_(stack_limit), 214 zone_(zone), 215 classifier_(nullptr), 216 scanner_(scanner), 217 stack_overflow_(false), 218 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), 219 function_literal_id_(0), 220 allow_natives_(false), 221 allow_tailcalls_(false), 222 allow_harmony_do_expressions_(false), 223 allow_harmony_function_sent_(false), 224 allow_harmony_restrictive_generators_(false), 225 allow_harmony_trailing_commas_(false), 226 allow_harmony_class_fields_(false), 227 allow_harmony_object_rest_spread_(false), 228 allow_harmony_dynamic_import_(false), 229 allow_harmony_async_iteration_(false), 230 allow_harmony_template_escapes_(false) {} 231 232 #define ALLOW_ACCESSORS(name) \ 233 bool allow_##name() const { return allow_##name##_; } \ 234 void set_allow_##name(bool allow) { allow_##name##_ = allow; } 235 236 ALLOW_ACCESSORS(natives); 237 ALLOW_ACCESSORS(tailcalls); 238 ALLOW_ACCESSORS(harmony_do_expressions); 239 ALLOW_ACCESSORS(harmony_function_sent); 240 ALLOW_ACCESSORS(harmony_restrictive_generators); 241 ALLOW_ACCESSORS(harmony_trailing_commas); 242 ALLOW_ACCESSORS(harmony_class_fields); 243 ALLOW_ACCESSORS(harmony_object_rest_spread); 244 ALLOW_ACCESSORS(harmony_dynamic_import); 245 ALLOW_ACCESSORS(harmony_async_iteration); 246 ALLOW_ACCESSORS(harmony_template_escapes); 247 248 #undef ALLOW_ACCESSORS 249 250 uintptr_t stack_limit() const { return stack_limit_; } 251 252 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } 253 254 void set_default_eager_compile_hint( 255 FunctionLiteral::EagerCompileHint eager_compile_hint) { 256 default_eager_compile_hint_ = eager_compile_hint; 257 } 258 259 FunctionLiteral::EagerCompileHint default_eager_compile_hint() const { 260 return default_eager_compile_hint_; 261 } 262 263 int GetNextFunctionLiteralId() { return ++function_literal_id_; } 264 int GetLastFunctionLiteralId() const { return function_literal_id_; } 265 266 void SkipFunctionLiterals(int delta) { function_literal_id_ += delta; } 267 268 void ResetFunctionLiteralId() { function_literal_id_ = 0; } 269 270 Zone* zone() const { return zone_; } 271 272 protected: 273 friend class v8::internal::ExpressionClassifier<ParserTypes<Impl>>; 274 275 enum AllowRestrictedIdentifiers { 276 kAllowRestrictedIdentifiers, 277 kDontAllowRestrictedIdentifiers 278 }; 279 280 enum LazyParsingResult { kLazyParsingComplete, kLazyParsingAborted }; 281 282 enum VariableDeclarationContext { 283 kStatementListItem, 284 kStatement, 285 kForStatement 286 }; 287 288 enum class FunctionBodyType { kNormal, kSingleExpression }; 289 290 class Checkpoint; 291 class ClassLiteralChecker; 292 class ObjectLiteralChecker; 293 294 // --------------------------------------------------------------------------- 295 // BlockState and FunctionState implement the parser's scope stack. 296 // The parser's current scope is in scope_. BlockState and FunctionState 297 // constructors push on the scope stack and the destructors pop. They are also 298 // used to hold the parser's per-funcion state. 299 class BlockState BASE_EMBEDDED { 300 public: 301 BlockState(Scope** scope_stack, Scope* scope) 302 : scope_stack_(scope_stack), outer_scope_(*scope_stack) { 303 *scope_stack_ = scope; 304 } 305 306 BlockState(Zone* zone, Scope** scope_stack) 307 : BlockState(scope_stack, 308 new (zone) Scope(zone, *scope_stack, BLOCK_SCOPE)) {} 309 310 ~BlockState() { *scope_stack_ = outer_scope_; } 311 312 private: 313 Scope** const scope_stack_; 314 Scope* const outer_scope_; 315 }; 316 317 struct DestructuringAssignment { 318 public: 319 DestructuringAssignment(ExpressionT expression, Scope* scope) 320 : assignment(expression), scope(scope) {} 321 322 ExpressionT assignment; 323 Scope* scope; 324 }; 325 326 class TailCallExpressionList { 327 public: 328 explicit TailCallExpressionList(Zone* zone) 329 : zone_(zone), expressions_(0, zone), has_explicit_tail_calls_(false) {} 330 331 const ZoneList<ExpressionT>& expressions() const { return expressions_; } 332 const Scanner::Location& location() const { return loc_; } 333 334 bool has_explicit_tail_calls() const { return has_explicit_tail_calls_; } 335 336 void Swap(TailCallExpressionList& other) { 337 expressions_.Swap(&other.expressions_); 338 std::swap(loc_, other.loc_); 339 std::swap(has_explicit_tail_calls_, other.has_explicit_tail_calls_); 340 } 341 342 void AddImplicitTailCall(ExpressionT expr) { 343 expressions_.Add(expr, zone_); 344 } 345 346 void Append(const TailCallExpressionList& other) { 347 if (!has_explicit_tail_calls()) { 348 loc_ = other.loc_; 349 has_explicit_tail_calls_ = other.has_explicit_tail_calls_; 350 } 351 expressions_.AddAll(other.expressions_, zone_); 352 } 353 354 private: 355 Zone* zone_; 356 ZoneList<ExpressionT> expressions_; 357 Scanner::Location loc_; 358 bool has_explicit_tail_calls_; 359 }; 360 361 // Defines whether tail call expressions are allowed or not. 362 enum class ReturnExprContext { 363 // We are inside return statement which is allowed to contain tail call 364 // expressions. Tail call expressions are allowed. 365 kInsideValidReturnStatement, 366 367 // We are inside a block in which tail call expressions are allowed but 368 // not yet inside a return statement. 369 kInsideValidBlock, 370 371 // Tail call expressions are not allowed in the following blocks. 372 kInsideTryBlock, 373 kInsideForInOfBody, 374 }; 375 376 class FunctionState final : public BlockState { 377 public: 378 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, 379 DeclarationScope* scope); 380 ~FunctionState(); 381 382 DeclarationScope* scope() const { return scope_->AsDeclarationScope(); } 383 384 void AddProperty() { expected_property_count_++; } 385 int expected_property_count() { return expected_property_count_; } 386 387 FunctionKind kind() const { return scope()->function_kind(); } 388 FunctionState* outer() const { return outer_function_state_; } 389 390 typename Types::Variable* generator_object_variable() const { 391 return scope()->generator_object_var(); 392 } 393 394 typename Types::Variable* promise_variable() const { 395 return scope()->promise_var(); 396 } 397 398 void RewindDestructuringAssignments(int pos) { 399 destructuring_assignments_to_rewrite_.Rewind(pos); 400 } 401 402 void SetDestructuringAssignmentsScope(int pos, Scope* scope) { 403 for (int i = pos; i < destructuring_assignments_to_rewrite_.length(); 404 ++i) { 405 destructuring_assignments_to_rewrite_[i].scope = scope; 406 } 407 } 408 409 const ZoneList<DestructuringAssignment>& 410 destructuring_assignments_to_rewrite() const { 411 return destructuring_assignments_to_rewrite_; 412 } 413 414 TailCallExpressionList& tail_call_expressions() { 415 return tail_call_expressions_; 416 } 417 void AddImplicitTailCallExpression(ExpressionT expression) { 418 if (return_expr_context() == 419 ReturnExprContext::kInsideValidReturnStatement) { 420 tail_call_expressions_.AddImplicitTailCall(expression); 421 } 422 } 423 424 ZoneList<typename ExpressionClassifier::Error>* GetReportedErrorList() { 425 return &reported_errors_; 426 } 427 428 ReturnExprContext return_expr_context() const { 429 return return_expr_context_; 430 } 431 void set_return_expr_context(ReturnExprContext context) { 432 return_expr_context_ = context; 433 } 434 435 ZoneList<ExpressionT>* non_patterns_to_rewrite() { 436 return &non_patterns_to_rewrite_; 437 } 438 439 bool next_function_is_likely_called() const { 440 return next_function_is_likely_called_; 441 } 442 443 bool previous_function_was_likely_called() const { 444 return previous_function_was_likely_called_; 445 } 446 447 void set_next_function_is_likely_called() { 448 next_function_is_likely_called_ = true; 449 } 450 451 private: 452 void AddDestructuringAssignment(DestructuringAssignment pair) { 453 destructuring_assignments_to_rewrite_.Add(pair, scope_->zone()); 454 } 455 456 void AddNonPatternForRewriting(ExpressionT expr, bool* ok) { 457 non_patterns_to_rewrite_.Add(expr, scope_->zone()); 458 if (non_patterns_to_rewrite_.length() >= 459 std::numeric_limits<uint16_t>::max()) 460 *ok = false; 461 } 462 463 // Used to assign an index to each literal that needs materialization in 464 // the function. Includes regexp literals, and boilerplate for object and 465 // array literals. 466 int next_materialized_literal_index_; 467 468 // Properties count estimation. 469 int expected_property_count_; 470 471 FunctionState** function_state_stack_; 472 FunctionState* outer_function_state_; 473 DeclarationScope* scope_; 474 475 ZoneList<DestructuringAssignment> destructuring_assignments_to_rewrite_; 476 TailCallExpressionList tail_call_expressions_; 477 ReturnExprContext return_expr_context_; 478 ZoneList<ExpressionT> non_patterns_to_rewrite_; 479 480 ZoneList<typename ExpressionClassifier::Error> reported_errors_; 481 482 // Record whether the next (=== immediately following) function literal is 483 // preceded by a parenthesis / exclamation mark. Also record the previous 484 // state. 485 // These are managed by the FunctionState constructor; the caller may only 486 // call set_next_function_is_likely_called. 487 bool next_function_is_likely_called_; 488 bool previous_function_was_likely_called_; 489 490 friend Impl; 491 friend class Checkpoint; 492 }; 493 494 // This scope sets current ReturnExprContext to given value. 495 class ReturnExprScope { 496 public: 497 explicit ReturnExprScope(FunctionState* function_state, 498 ReturnExprContext return_expr_context) 499 : function_state_(function_state), 500 sav_return_expr_context_(function_state->return_expr_context()) { 501 // Don't update context if we are requested to enable tail call 502 // expressions but current block does not allow them. 503 if (return_expr_context != 504 ReturnExprContext::kInsideValidReturnStatement || 505 sav_return_expr_context_ == ReturnExprContext::kInsideValidBlock) { 506 function_state->set_return_expr_context(return_expr_context); 507 } 508 } 509 ~ReturnExprScope() { 510 function_state_->set_return_expr_context(sav_return_expr_context_); 511 } 512 513 private: 514 FunctionState* function_state_; 515 ReturnExprContext sav_return_expr_context_; 516 }; 517 518 // Collects all return expressions at tail call position in this scope 519 // to a separate list. 520 class CollectExpressionsInTailPositionToListScope { 521 public: 522 CollectExpressionsInTailPositionToListScope(FunctionState* function_state, 523 TailCallExpressionList* list) 524 : function_state_(function_state), list_(list) { 525 function_state->tail_call_expressions().Swap(*list_); 526 } 527 ~CollectExpressionsInTailPositionToListScope() { 528 function_state_->tail_call_expressions().Swap(*list_); 529 } 530 531 private: 532 FunctionState* function_state_; 533 TailCallExpressionList* list_; 534 }; 535 536 // Annoyingly, arrow functions first parse as comma expressions, then when we 537 // see the => we have to go back and reinterpret the arguments as being formal 538 // parameters. To do so we need to reset some of the parser state back to 539 // what it was before the arguments were first seen. 540 class Checkpoint BASE_EMBEDDED { 541 public: 542 explicit Checkpoint(ParserBase* parser) { 543 function_state_ = parser->function_state_; 544 next_materialized_literal_index_ = 545 function_state_->next_materialized_literal_index_; 546 expected_property_count_ = function_state_->expected_property_count_; 547 } 548 549 void Restore(int* materialized_literal_index_delta) { 550 *materialized_literal_index_delta = 551 function_state_->next_materialized_literal_index_ - 552 next_materialized_literal_index_; 553 function_state_->next_materialized_literal_index_ = 554 next_materialized_literal_index_; 555 function_state_->expected_property_count_ = expected_property_count_; 556 } 557 558 private: 559 FunctionState* function_state_; 560 int next_materialized_literal_index_; 561 int expected_property_count_; 562 }; 563 564 struct DeclarationDescriptor { 565 enum Kind { NORMAL, PARAMETER }; 566 Scope* scope; 567 VariableMode mode; 568 int declaration_pos; 569 int initialization_pos; 570 Kind declaration_kind; 571 }; 572 573 struct DeclarationParsingResult { 574 struct Declaration { 575 Declaration(ExpressionT pattern, int initializer_position, 576 ExpressionT initializer) 577 : pattern(pattern), 578 initializer_position(initializer_position), 579 initializer(initializer) {} 580 581 ExpressionT pattern; 582 int initializer_position; 583 ExpressionT initializer; 584 }; 585 586 DeclarationParsingResult() 587 : declarations(4), 588 first_initializer_loc(Scanner::Location::invalid()), 589 bindings_loc(Scanner::Location::invalid()) {} 590 591 DeclarationDescriptor descriptor; 592 List<Declaration> declarations; 593 Scanner::Location first_initializer_loc; 594 Scanner::Location bindings_loc; 595 }; 596 597 struct CatchInfo { 598 public: 599 explicit CatchInfo(ParserBase* parser) 600 : name(parser->impl()->EmptyIdentifier()), 601 variable(nullptr), 602 pattern(parser->impl()->EmptyExpression()), 603 scope(nullptr), 604 init_block(parser->impl()->NullBlock()), 605 inner_block(parser->impl()->NullBlock()), 606 bound_names(1, parser->zone()), 607 tail_call_expressions(parser->zone()) {} 608 IdentifierT name; 609 Variable* variable; 610 ExpressionT pattern; 611 Scope* scope; 612 BlockT init_block; 613 BlockT inner_block; 614 ZoneList<const AstRawString*> bound_names; 615 TailCallExpressionList tail_call_expressions; 616 }; 617 618 struct ForInfo { 619 public: 620 explicit ForInfo(ParserBase* parser) 621 : bound_names(1, parser->zone()), 622 mode(ForEachStatement::ENUMERATE), 623 position(kNoSourcePosition), 624 parsing_result() {} 625 ZoneList<const AstRawString*> bound_names; 626 ForEachStatement::VisitMode mode; 627 int position; 628 DeclarationParsingResult parsing_result; 629 }; 630 631 struct ClassInfo { 632 public: 633 explicit ClassInfo(ParserBase* parser) 634 : proxy(nullptr), 635 extends(parser->impl()->EmptyExpression()), 636 properties(parser->impl()->NewClassPropertyList(4)), 637 constructor(parser->impl()->EmptyFunctionLiteral()), 638 has_seen_constructor(false), 639 has_name_static_property(false), 640 has_static_computed_names(false) {} 641 VariableProxy* proxy; 642 ExpressionT extends; 643 typename Types::ClassPropertyList properties; 644 FunctionLiteralT constructor; 645 bool has_seen_constructor; 646 bool has_name_static_property; 647 bool has_static_computed_names; 648 }; 649 650 DeclarationScope* NewScriptScope() const { 651 return new (zone()) DeclarationScope(zone(), ast_value_factory()); 652 } 653 654 DeclarationScope* NewVarblockScope() const { 655 return new (zone()) DeclarationScope(zone(), scope(), BLOCK_SCOPE); 656 } 657 658 ModuleScope* NewModuleScope(DeclarationScope* parent) const { 659 return new (zone()) ModuleScope(parent, ast_value_factory()); 660 } 661 662 DeclarationScope* NewEvalScope(Scope* parent) const { 663 return new (zone()) DeclarationScope(zone(), parent, EVAL_SCOPE); 664 } 665 666 Scope* NewScope(ScopeType scope_type) const { 667 return NewScopeWithParent(scope(), scope_type); 668 } 669 670 // This constructor should only be used when absolutely necessary. Most scopes 671 // should automatically use scope() as parent, and be fine with 672 // NewScope(ScopeType) above. 673 Scope* NewScopeWithParent(Scope* parent, ScopeType scope_type) const { 674 // Must always use the specific constructors for the blacklisted scope 675 // types. 676 DCHECK_NE(FUNCTION_SCOPE, scope_type); 677 DCHECK_NE(SCRIPT_SCOPE, scope_type); 678 DCHECK_NE(MODULE_SCOPE, scope_type); 679 DCHECK_NOT_NULL(parent); 680 return new (zone()) Scope(zone(), parent, scope_type); 681 } 682 683 // Creates a function scope that always allocates in zone(). The function 684 // scope itself is either allocated in zone() or in target_zone if one is 685 // passed in. 686 DeclarationScope* NewFunctionScope(FunctionKind kind, 687 Zone* target_zone = nullptr) const { 688 DCHECK(ast_value_factory()); 689 if (target_zone == nullptr) target_zone = zone(); 690 DeclarationScope* result = new (target_zone) 691 DeclarationScope(zone(), scope(), FUNCTION_SCOPE, kind); 692 // TODO(verwaest): Move into the DeclarationScope constructor. 693 if (!IsArrowFunction(kind)) { 694 result->DeclareDefaultFunctionVariables(ast_value_factory()); 695 } 696 return result; 697 } 698 699 V8_INLINE DeclarationScope* GetDeclarationScope() const { 700 return scope()->GetDeclarationScope(); 701 } 702 V8_INLINE DeclarationScope* GetClosureScope() const { 703 return scope()->GetClosureScope(); 704 } 705 706 Scanner* scanner() const { return scanner_; } 707 AstValueFactory* ast_value_factory() const { return ast_value_factory_; } 708 int position() const { return scanner_->location().beg_pos; } 709 int peek_position() const { return scanner_->peek_location().beg_pos; } 710 bool stack_overflow() const { return stack_overflow_; } 711 void set_stack_overflow() { stack_overflow_ = true; } 712 713 INLINE(Token::Value peek()) { 714 if (stack_overflow_) return Token::ILLEGAL; 715 return scanner()->peek(); 716 } 717 718 INLINE(Token::Value PeekAhead()) { 719 if (stack_overflow_) return Token::ILLEGAL; 720 return scanner()->PeekAhead(); 721 } 722 723 INLINE(Token::Value Next()) { 724 if (stack_overflow_) return Token::ILLEGAL; 725 { 726 if (GetCurrentStackPosition() < stack_limit_) { 727 // Any further calls to Next or peek will return the illegal token. 728 // The current call must return the next token, which might already 729 // have been peek'ed. 730 stack_overflow_ = true; 731 } 732 } 733 return scanner()->Next(); 734 } 735 736 void Consume(Token::Value token) { 737 Token::Value next = Next(); 738 USE(next); 739 USE(token); 740 DCHECK(next == token); 741 } 742 743 bool Check(Token::Value token) { 744 Token::Value next = peek(); 745 if (next == token) { 746 Consume(next); 747 return true; 748 } 749 return false; 750 } 751 752 void Expect(Token::Value token, bool* ok) { 753 Token::Value next = Next(); 754 if (next != token) { 755 ReportUnexpectedToken(next); 756 *ok = false; 757 } 758 } 759 760 void ExpectSemicolon(bool* ok) { 761 // Check for automatic semicolon insertion according to 762 // the rules given in ECMA-262, section 7.9, page 21. 763 Token::Value tok = peek(); 764 if (tok == Token::SEMICOLON) { 765 Next(); 766 return; 767 } 768 if (scanner()->HasAnyLineTerminatorBeforeNext() || 769 tok == Token::RBRACE || 770 tok == Token::EOS) { 771 return; 772 } 773 Expect(Token::SEMICOLON, ok); 774 } 775 776 // Dummy functions, just useful as arguments to CHECK_OK_CUSTOM. 777 static void Void() {} 778 template <typename T> 779 static T Return(T result) { 780 return result; 781 } 782 783 bool is_any_identifier(Token::Value token) { 784 return token == Token::IDENTIFIER || token == Token::ENUM || 785 token == Token::AWAIT || token == Token::ASYNC || 786 token == Token::ESCAPED_STRICT_RESERVED_WORD || 787 token == Token::FUTURE_STRICT_RESERVED_WORD || token == Token::LET || 788 token == Token::STATIC || token == Token::YIELD; 789 } 790 bool peek_any_identifier() { return is_any_identifier(peek()); } 791 792 bool CheckContextualKeyword(Vector<const char> keyword) { 793 if (PeekContextualKeyword(keyword)) { 794 Consume(Token::IDENTIFIER); 795 return true; 796 } 797 return false; 798 } 799 800 bool PeekContextualKeyword(Vector<const char> keyword) { 801 return peek() == Token::IDENTIFIER && 802 scanner()->is_next_contextual_keyword(keyword); 803 } 804 805 void ExpectMetaProperty(Vector<const char> property_name, 806 const char* full_name, int pos, bool* ok); 807 808 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { 809 Expect(Token::IDENTIFIER, CHECK_OK_CUSTOM(Void)); 810 if (!scanner()->is_literal_contextual_keyword(keyword)) { 811 ReportUnexpectedToken(scanner()->current_token()); 812 *ok = false; 813 } 814 } 815 816 bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode) { 817 if (Check(Token::IN)) { 818 *visit_mode = ForEachStatement::ENUMERATE; 819 return true; 820 } else if (CheckContextualKeyword(CStrVector("of"))) { 821 *visit_mode = ForEachStatement::ITERATE; 822 return true; 823 } 824 return false; 825 } 826 827 bool PeekInOrOf() { 828 return peek() == Token::IN || PeekContextualKeyword(CStrVector("of")); 829 } 830 831 // Checks whether an octal literal was last seen between beg_pos and end_pos. 832 // Only called for strict mode strings. 833 void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) { 834 Scanner::Location octal = scanner()->octal_position(); 835 if (octal.IsValid() && beg_pos <= octal.beg_pos && 836 octal.end_pos <= end_pos) { 837 MessageTemplate::Template message = scanner()->octal_message(); 838 DCHECK_NE(message, MessageTemplate::kNone); 839 impl()->ReportMessageAt(octal, message); 840 scanner()->clear_octal_position(); 841 if (message == MessageTemplate::kStrictDecimalWithLeadingZero) { 842 impl()->CountUsage(v8::Isolate::kDecimalWithLeadingZeroInStrictMode); 843 } 844 *ok = false; 845 } 846 } 847 848 // Checks if an octal literal or an invalid hex or unicode escape sequence 849 // appears in a template literal. In the presence of such, either 850 // returns false or reports an error, depending on should_throw. Otherwise 851 // returns true. 852 inline bool CheckTemplateEscapes(bool should_throw, bool* ok) { 853 if (!scanner()->has_invalid_template_escape()) { 854 return true; 855 } 856 857 // Handle error case(s) 858 if (should_throw) { 859 impl()->ReportMessageAt(scanner()->invalid_template_escape_location(), 860 scanner()->invalid_template_escape_message()); 861 *ok = false; 862 } 863 scanner()->clear_invalid_template_escape(); 864 return false; 865 } 866 867 void CheckDestructuringElement(ExpressionT element, int beg_pos, int end_pos); 868 869 // Checking the name of a function literal. This has to be done after parsing 870 // the function, since the function can declare itself strict. 871 void CheckFunctionName(LanguageMode language_mode, IdentifierT function_name, 872 FunctionNameValidity function_name_validity, 873 const Scanner::Location& function_name_loc, bool* ok) { 874 if (function_name_validity == kSkipFunctionNameCheck) return; 875 // The function name needs to be checked in strict mode. 876 if (is_sloppy(language_mode)) return; 877 878 if (impl()->IsEvalOrArguments(function_name)) { 879 impl()->ReportMessageAt(function_name_loc, 880 MessageTemplate::kStrictEvalArguments); 881 *ok = false; 882 return; 883 } 884 if (function_name_validity == kFunctionNameIsStrictReserved) { 885 impl()->ReportMessageAt(function_name_loc, 886 MessageTemplate::kUnexpectedStrictReserved); 887 *ok = false; 888 return; 889 } 890 } 891 892 // Determine precedence of given token. 893 static int Precedence(Token::Value token, bool accept_IN) { 894 if (token == Token::IN && !accept_IN) 895 return 0; // 0 precedence will terminate binary expression parsing 896 return Token::Precedence(token); 897 } 898 899 typename Types::Factory* factory() { return &ast_node_factory_; } 900 901 DeclarationScope* GetReceiverScope() const { 902 return scope()->GetReceiverScope(); 903 } 904 LanguageMode language_mode() { return scope()->language_mode(); } 905 void RaiseLanguageMode(LanguageMode mode) { 906 LanguageMode old = scope()->language_mode(); 907 impl()->SetLanguageMode(scope(), old > mode ? old : mode); 908 } 909 bool is_generator() const { 910 return IsGeneratorFunction(function_state_->kind()); 911 } 912 bool is_async_function() const { 913 return IsAsyncFunction(function_state_->kind()); 914 } 915 bool is_resumable() const { 916 return IsResumableFunction(function_state_->kind()); 917 } 918 919 // Report syntax errors. 920 void ReportMessage(MessageTemplate::Template message) { 921 Scanner::Location source_location = scanner()->location(); 922 impl()->ReportMessageAt(source_location, message, 923 static_cast<const char*>(nullptr), kSyntaxError); 924 } 925 926 template <typename T> 927 void ReportMessage(MessageTemplate::Template message, T arg, 928 ParseErrorType error_type = kSyntaxError) { 929 Scanner::Location source_location = scanner()->location(); 930 impl()->ReportMessageAt(source_location, message, arg, error_type); 931 } 932 933 void ReportMessageAt(Scanner::Location location, 934 MessageTemplate::Template message, 935 ParseErrorType error_type) { 936 impl()->ReportMessageAt(location, message, 937 static_cast<const char*>(nullptr), error_type); 938 } 939 940 void GetUnexpectedTokenMessage( 941 Token::Value token, MessageTemplate::Template* message, 942 Scanner::Location* location, const char** arg, 943 MessageTemplate::Template default_ = MessageTemplate::kUnexpectedToken); 944 945 void ReportUnexpectedToken(Token::Value token); 946 void ReportUnexpectedTokenAt( 947 Scanner::Location location, Token::Value token, 948 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken); 949 950 void ReportClassifierError( 951 const typename ExpressionClassifier::Error& error) { 952 impl()->ReportMessageAt(error.location, error.message, error.arg, 953 error.type); 954 } 955 956 void ValidateExpression(bool* ok) { 957 if (!classifier()->is_valid_expression()) { 958 ReportClassifierError(classifier()->expression_error()); 959 *ok = false; 960 } 961 } 962 963 void ValidateFormalParameterInitializer(bool* ok) { 964 if (!classifier()->is_valid_formal_parameter_initializer()) { 965 ReportClassifierError(classifier()->formal_parameter_initializer_error()); 966 *ok = false; 967 } 968 } 969 970 void ValidateBindingPattern(bool* ok) { 971 if (!classifier()->is_valid_binding_pattern()) { 972 ReportClassifierError(classifier()->binding_pattern_error()); 973 *ok = false; 974 } 975 } 976 977 void ValidateAssignmentPattern(bool* ok) { 978 if (!classifier()->is_valid_assignment_pattern()) { 979 ReportClassifierError(classifier()->assignment_pattern_error()); 980 *ok = false; 981 } 982 } 983 984 void ValidateFormalParameters(LanguageMode language_mode, 985 bool allow_duplicates, bool* ok) { 986 if (!allow_duplicates && 987 !classifier()->is_valid_formal_parameter_list_without_duplicates()) { 988 ReportClassifierError(classifier()->duplicate_formal_parameter_error()); 989 *ok = false; 990 } else if (is_strict(language_mode) && 991 !classifier()->is_valid_strict_mode_formal_parameters()) { 992 ReportClassifierError(classifier()->strict_mode_formal_parameter_error()); 993 *ok = false; 994 } 995 } 996 997 bool IsValidArrowFormalParametersStart(Token::Value token) { 998 return is_any_identifier(token) || token == Token::LPAREN; 999 } 1000 1001 void ValidateArrowFormalParameters(ExpressionT expr, 1002 bool parenthesized_formals, bool is_async, 1003 bool* ok) { 1004 if (classifier()->is_valid_binding_pattern()) { 1005 // A simple arrow formal parameter: IDENTIFIER => BODY. 1006 if (!impl()->IsIdentifier(expr)) { 1007 impl()->ReportMessageAt(scanner()->location(), 1008 MessageTemplate::kUnexpectedToken, 1009 Token::String(scanner()->current_token())); 1010 *ok = false; 1011 } 1012 } else if (!classifier()->is_valid_arrow_formal_parameters()) { 1013 // If after parsing the expr, we see an error but the expression is 1014 // neither a valid binding pattern nor a valid parenthesized formal 1015 // parameter list, show the "arrow formal parameters" error if the formals 1016 // started with a parenthesis, and the binding pattern error otherwise. 1017 const typename ExpressionClassifier::Error& error = 1018 parenthesized_formals ? classifier()->arrow_formal_parameters_error() 1019 : classifier()->binding_pattern_error(); 1020 ReportClassifierError(error); 1021 *ok = false; 1022 } 1023 if (is_async && !classifier()->is_valid_async_arrow_formal_parameters()) { 1024 const typename ExpressionClassifier::Error& error = 1025 classifier()->async_arrow_formal_parameters_error(); 1026 ReportClassifierError(error); 1027 *ok = false; 1028 } 1029 } 1030 1031 void ValidateLetPattern(bool* ok) { 1032 if (!classifier()->is_valid_let_pattern()) { 1033 ReportClassifierError(classifier()->let_pattern_error()); 1034 *ok = false; 1035 } 1036 } 1037 1038 void BindingPatternUnexpectedToken() { 1039 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; 1040 const char* arg; 1041 Scanner::Location location = scanner()->peek_location(); 1042 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); 1043 classifier()->RecordBindingPatternError(location, message, arg); 1044 } 1045 1046 void ArrowFormalParametersUnexpectedToken() { 1047 MessageTemplate::Template message = MessageTemplate::kUnexpectedToken; 1048 const char* arg; 1049 Scanner::Location location = scanner()->peek_location(); 1050 GetUnexpectedTokenMessage(peek(), &message, &location, &arg); 1051 classifier()->RecordArrowFormalParametersError(location, message, arg); 1052 } 1053 1054 // Recursive descent functions. 1055 // All ParseXXX functions take as the last argument an *ok parameter 1056 // which is set to false if parsing failed; it is unchanged otherwise. 1057 // By making the 'exception handling' explicit, we are forced to check 1058 // for failure at the call sites. The family of CHECK_OK* macros can 1059 // be useful for this. 1060 1061 // Parses an identifier that is valid for the current scope, in particular it 1062 // fails on strict mode future reserved keywords in a strict scope. If 1063 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or 1064 // "arguments" as identifier even in strict mode (this is needed in cases like 1065 // "var foo = eval;"). 1066 IdentifierT ParseIdentifier(AllowRestrictedIdentifiers, bool* ok); 1067 IdentifierT ParseAndClassifyIdentifier(bool* ok); 1068 // Parses an identifier or a strict mode future reserved word, and indicate 1069 // whether it is strict mode future reserved. Allows passing in function_kind 1070 // for the case of parsing the identifier in a function expression, where the 1071 // relevant "function_kind" bit is of the function being parsed, not the 1072 // containing function. 1073 IdentifierT ParseIdentifierOrStrictReservedWord(FunctionKind function_kind, 1074 bool* is_strict_reserved, 1075 bool* ok); 1076 IdentifierT ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, 1077 bool* ok) { 1078 return ParseIdentifierOrStrictReservedWord(function_state_->kind(), 1079 is_strict_reserved, ok); 1080 } 1081 1082 IdentifierT ParseIdentifierName(bool* ok); 1083 1084 ExpressionT ParseRegExpLiteral(bool* ok); 1085 1086 ExpressionT ParsePrimaryExpression(bool* is_async, bool* ok); 1087 ExpressionT ParsePrimaryExpression(bool* ok) { 1088 bool is_async; 1089 return ParsePrimaryExpression(&is_async, ok); 1090 } 1091 1092 // This method wraps the parsing of the expression inside a new expression 1093 // classifier and calls RewriteNonPattern if parsing is successful. 1094 // It should be used whenever we're parsing an expression that will be 1095 // used as a non-pattern (i.e., in most cases). 1096 V8_INLINE ExpressionT ParseExpression(bool accept_IN, bool* ok); 1097 1098 // This method does not wrap the parsing of the expression inside a 1099 // new expression classifier; it uses the top-level classifier instead. 1100 // It should be used whenever we're parsing something with the "cover" 1101 // grammar that recognizes both patterns and non-patterns (which roughly 1102 // corresponds to what's inside the parentheses generated by the symbol 1103 // "CoverParenthesizedExpressionAndArrowParameterList" in the ES 2017 1104 // specification). 1105 ExpressionT ParseExpressionCoverGrammar(bool accept_IN, bool* ok); 1106 1107 ExpressionT ParseArrayLiteral(bool* ok); 1108 1109 enum class PropertyKind { 1110 kAccessorProperty, 1111 kValueProperty, 1112 kShorthandProperty, 1113 kMethodProperty, 1114 kClassField, 1115 kSpreadProperty, 1116 kNotSet 1117 }; 1118 1119 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind); 1120 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind, 1121 bool* is_generator, bool* is_get, bool* is_set, 1122 bool* is_async, bool* is_computed_name, 1123 bool* ok); 1124 ExpressionT ParseObjectLiteral(bool* ok); 1125 ClassLiteralPropertyT ParseClassPropertyDefinition( 1126 ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name, 1127 bool* has_seen_constructor, ClassLiteralProperty::Kind* property_kind, 1128 bool* is_static, bool* has_name_static_property, bool* ok); 1129 FunctionLiteralT ParseClassFieldForInitializer(bool has_initializer, 1130 bool* ok); 1131 ObjectLiteralPropertyT ParseObjectPropertyDefinition( 1132 ObjectLiteralChecker* checker, bool* is_computed_name, 1133 bool* is_rest_property, bool* ok); 1134 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, 1135 bool maybe_arrow, bool* ok); 1136 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, 1137 bool* ok) { 1138 return ParseArguments(first_spread_pos, false, ok); 1139 } 1140 1141 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); 1142 ExpressionT ParseYieldExpression(bool accept_IN, bool* ok); 1143 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); 1144 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 1145 ExpressionT ParseUnaryExpression(bool* ok); 1146 ExpressionT ParsePostfixExpression(bool* ok); 1147 ExpressionT ParseLeftHandSideExpression(bool* ok); 1148 ExpressionT ParseMemberWithNewPrefixesExpression(bool* is_async, bool* ok); 1149 ExpressionT ParseMemberExpression(bool* is_async, bool* ok); 1150 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 1151 bool* is_async, bool* ok); 1152 1153 // `rewritable_length`: length of the destructuring_assignments_to_rewrite() 1154 // queue in the parent function state, prior to parsing of formal parameters. 1155 // If the arrow function is lazy, any items added during formal parameter 1156 // parsing are removed from the queue. 1157 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, 1158 const FormalParametersT& parameters, 1159 int rewritable_length, bool* ok); 1160 void ParseAsyncFunctionBody(Scope* scope, StatementListT body, 1161 FunctionKind kind, FunctionBodyType type, 1162 bool accept_IN, int pos, bool* ok); 1163 ExpressionT ParseAsyncFunctionLiteral(bool* ok); 1164 ExpressionT ParseClassLiteral(IdentifierT name, 1165 Scanner::Location class_name_location, 1166 bool name_is_strict_reserved, 1167 int class_token_pos, bool* ok); 1168 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool tagged, 1169 bool* ok); 1170 ExpressionT ParseSuperExpression(bool is_new, bool* ok); 1171 ExpressionT ParseDynamicImportExpression(bool* ok); 1172 ExpressionT ParseNewTargetExpression(bool* ok); 1173 1174 void ParseFormalParameter(FormalParametersT* parameters, bool* ok); 1175 void ParseFormalParameterList(FormalParametersT* parameters, bool* ok); 1176 void CheckArityRestrictions(int param_count, FunctionKind function_type, 1177 bool has_rest, int formals_start_pos, 1178 int formals_end_pos, bool* ok); 1179 1180 BlockT ParseVariableDeclarations(VariableDeclarationContext var_context, 1181 DeclarationParsingResult* parsing_result, 1182 ZoneList<const AstRawString*>* names, 1183 bool* ok); 1184 StatementT ParseAsyncFunctionDeclaration(ZoneList<const AstRawString*>* names, 1185 bool default_export, bool* ok); 1186 StatementT ParseFunctionDeclaration(bool* ok); 1187 StatementT ParseHoistableDeclaration(ZoneList<const AstRawString*>* names, 1188 bool default_export, bool* ok); 1189 StatementT ParseHoistableDeclaration(int pos, ParseFunctionFlags flags, 1190 ZoneList<const AstRawString*>* names, 1191 bool default_export, bool* ok); 1192 StatementT ParseClassDeclaration(ZoneList<const AstRawString*>* names, 1193 bool default_export, bool* ok); 1194 StatementT ParseNativeDeclaration(bool* ok); 1195 1196 // Consumes the ending }. 1197 void ParseFunctionBody(StatementListT result, IdentifierT function_name, 1198 int pos, const FormalParametersT& parameters, 1199 FunctionKind kind, 1200 FunctionLiteral::FunctionType function_type, bool* ok); 1201 1202 // Under some circumstances, we allow preparsing to abort if the preparsed 1203 // function is "long and trivial", and fully parse instead. Our current 1204 // definition of "long and trivial" is: 1205 // - over kLazyParseTrialLimit statements 1206 // - all starting with an identifier (i.e., no if, for, while, etc.) 1207 static const int kLazyParseTrialLimit = 200; 1208 1209 // TODO(nikolaos, marja): The first argument should not really be passed 1210 // by value. The method is expected to add the parsed statements to the 1211 // list. This works because in the case of the parser, StatementListT is 1212 // a pointer whereas the preparser does not really modify the body. 1213 V8_INLINE void ParseStatementList(StatementListT body, int end_token, 1214 bool* ok) { 1215 LazyParsingResult result = ParseStatementList(body, end_token, false, ok); 1216 USE(result); 1217 DCHECK_EQ(result, kLazyParsingComplete); 1218 } 1219 LazyParsingResult ParseStatementList(StatementListT body, int end_token, 1220 bool may_abort, bool* ok); 1221 StatementT ParseStatementListItem(bool* ok); 1222 StatementT ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok) { 1223 return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok); 1224 } 1225 StatementT ParseStatement(ZoneList<const AstRawString*>* labels, 1226 AllowLabelledFunctionStatement allow_function, 1227 bool* ok); 1228 StatementT ParseStatementAsUnlabelled(ZoneList<const AstRawString*>* labels, 1229 bool* ok); 1230 BlockT ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok); 1231 1232 // Parse a SubStatement in strict mode, or with an extra block scope in 1233 // sloppy mode to handle 1234 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses 1235 StatementT ParseScopedStatement(ZoneList<const AstRawString*>* labels, 1236 bool* ok); 1237 1238 StatementT ParseVariableStatement(VariableDeclarationContext var_context, 1239 ZoneList<const AstRawString*>* names, 1240 bool* ok); 1241 1242 // Magical syntax support. 1243 ExpressionT ParseV8Intrinsic(bool* ok); 1244 1245 ExpressionT ParseDoExpression(bool* ok); 1246 1247 StatementT ParseDebuggerStatement(bool* ok); 1248 1249 StatementT ParseExpressionOrLabelledStatement( 1250 ZoneList<const AstRawString*>* labels, 1251 AllowLabelledFunctionStatement allow_function, bool* ok); 1252 StatementT ParseIfStatement(ZoneList<const AstRawString*>* labels, bool* ok); 1253 StatementT ParseContinueStatement(bool* ok); 1254 StatementT ParseBreakStatement(ZoneList<const AstRawString*>* labels, 1255 bool* ok); 1256 StatementT ParseReturnStatement(bool* ok); 1257 StatementT ParseWithStatement(ZoneList<const AstRawString*>* labels, 1258 bool* ok); 1259 StatementT ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, 1260 bool* ok); 1261 StatementT ParseWhileStatement(ZoneList<const AstRawString*>* labels, 1262 bool* ok); 1263 StatementT ParseThrowStatement(bool* ok); 1264 StatementT ParseSwitchStatement(ZoneList<const AstRawString*>* labels, 1265 bool* ok); 1266 StatementT ParseTryStatement(bool* ok); 1267 StatementT ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok); 1268 StatementT ParseForEachStatementWithDeclarations( 1269 int stmt_pos, ForInfo* for_info, ZoneList<const AstRawString*>* labels, 1270 bool* ok); 1271 StatementT ParseForEachStatementWithoutDeclarations( 1272 int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos, 1273 ForInfo* for_info, ZoneList<const AstRawString*>* labels, bool* ok); 1274 1275 // Parse a C-style for loop: 'for (<init>; <cond>; <step>) { ... }' 1276 StatementT ParseStandardForLoop(int stmt_pos, StatementT init, 1277 bool bound_names_are_lexical, 1278 ForInfo* for_info, BlockState* for_state, 1279 ZoneList<const AstRawString*>* labels, 1280 bool* ok); 1281 StatementT ParseForAwaitStatement(ZoneList<const AstRawString*>* labels, 1282 bool* ok); 1283 1284 bool IsNextLetKeyword(); 1285 bool IsTrivialExpression(); 1286 1287 // Checks if the expression is a valid reference expression (e.g., on the 1288 // left-hand side of assignments). Although ruled out by ECMA as early errors, 1289 // we allow calls for web compatibility and rewrite them to a runtime throw. 1290 ExpressionT CheckAndRewriteReferenceExpression( 1291 ExpressionT expression, int beg_pos, int end_pos, 1292 MessageTemplate::Template message, bool* ok); 1293 ExpressionT CheckAndRewriteReferenceExpression( 1294 ExpressionT expression, int beg_pos, int end_pos, 1295 MessageTemplate::Template message, ParseErrorType type, bool* ok); 1296 1297 bool IsValidReferenceExpression(ExpressionT expression); 1298 1299 bool IsAssignableIdentifier(ExpressionT expression) { 1300 if (!impl()->IsIdentifier(expression)) return false; 1301 if (is_strict(language_mode()) && 1302 impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) { 1303 return false; 1304 } 1305 return true; 1306 } 1307 1308 bool IsValidPattern(ExpressionT expression) { 1309 return expression->IsObjectLiteral() || expression->IsArrayLiteral(); 1310 } 1311 1312 // Due to hoisting, the value of a 'var'-declared variable may actually change 1313 // even if the code contains only the "initial" assignment, namely when that 1314 // assignment occurs inside a loop. For example: 1315 // 1316 // let i = 10; 1317 // do { var x = i } while (i--): 1318 // 1319 // As a simple and very conservative approximation of this, we explicitly mark 1320 // as maybe-assigned any non-lexical variable whose initializing "declaration" 1321 // does not syntactically occur in the function scope. (In the example above, 1322 // it occurs in a block scope.) 1323 // 1324 // Note that non-lexical variables include temporaries, which may also get 1325 // assigned inside a loop due to the various rewritings that the parser 1326 // performs. 1327 // 1328 static void MarkLoopVariableAsAssigned(Scope* scope, Variable* var); 1329 1330 // Keep track of eval() calls since they disable all local variable 1331 // optimizations. This checks if expression is an eval call, and if yes, 1332 // forwards the information to scope. 1333 Call::PossiblyEval CheckPossibleEvalCall(ExpressionT expression, 1334 Scope* scope) { 1335 if (impl()->IsIdentifier(expression) && 1336 impl()->IsEval(impl()->AsIdentifier(expression))) { 1337 scope->RecordEvalCall(); 1338 if (is_sloppy(scope->language_mode())) { 1339 // For sloppy scopes we also have to record the call at function level, 1340 // in case it includes declarations that will be hoisted. 1341 scope->GetDeclarationScope()->RecordEvalCall(); 1342 } 1343 return Call::IS_POSSIBLY_EVAL; 1344 } 1345 return Call::NOT_EVAL; 1346 } 1347 1348 // Convenience method which determines the type of return statement to emit 1349 // depending on the current function type. 1350 inline StatementT BuildReturnStatement(ExpressionT expr, int pos) { 1351 if (V8_UNLIKELY(is_async_function())) { 1352 return factory()->NewAsyncReturnStatement(expr, pos); 1353 } 1354 return factory()->NewReturnStatement(expr, pos); 1355 } 1356 1357 // Validation per ES6 object literals. 1358 class ObjectLiteralChecker { 1359 public: 1360 explicit ObjectLiteralChecker(ParserBase* parser) 1361 : parser_(parser), has_seen_proto_(false) {} 1362 1363 void CheckDuplicateProto(Token::Value property); 1364 1365 private: 1366 bool IsProto() { return this->scanner()->LiteralMatches("__proto__", 9); } 1367 1368 ParserBase* parser() const { return parser_; } 1369 Scanner* scanner() const { return parser_->scanner(); } 1370 1371 ParserBase* parser_; 1372 bool has_seen_proto_; 1373 }; 1374 1375 // Validation per ES6 class literals. 1376 class ClassLiteralChecker { 1377 public: 1378 explicit ClassLiteralChecker(ParserBase* parser) 1379 : parser_(parser), has_seen_constructor_(false) {} 1380 1381 void CheckClassMethodName(Token::Value property, PropertyKind type, 1382 bool is_generator, bool is_async, bool is_static, 1383 bool* ok); 1384 1385 private: 1386 bool IsConstructor() { 1387 return this->scanner()->LiteralMatches("constructor", 11); 1388 } 1389 bool IsPrototype() { 1390 return this->scanner()->LiteralMatches("prototype", 9); 1391 } 1392 1393 ParserBase* parser() const { return parser_; } 1394 Scanner* scanner() const { return parser_->scanner(); } 1395 1396 ParserBase* parser_; 1397 bool has_seen_constructor_; 1398 }; 1399 1400 ModuleDescriptor* module() const { 1401 return scope()->AsModuleScope()->module(); 1402 } 1403 Scope* scope() const { return scope_; } 1404 1405 // Stack of expression classifiers. 1406 // The top of the stack is always pointed to by classifier(). 1407 V8_INLINE ExpressionClassifier* classifier() const { 1408 DCHECK_NOT_NULL(classifier_); 1409 return classifier_; 1410 } 1411 1412 // Accumulates the classifier that is on top of the stack (inner) to 1413 // the one that is right below (outer) and pops the inner. 1414 V8_INLINE void Accumulate(unsigned productions, 1415 bool merge_non_patterns = true) { 1416 DCHECK_NOT_NULL(classifier_); 1417 ExpressionClassifier* previous = classifier_->previous(); 1418 DCHECK_NOT_NULL(previous); 1419 previous->Accumulate(classifier_, productions, merge_non_patterns); 1420 classifier_ = previous; 1421 } 1422 1423 // Pops and discards the classifier that is on top of the stack 1424 // without accumulating. 1425 V8_INLINE void Discard() { 1426 DCHECK_NOT_NULL(classifier_); 1427 classifier_->Discard(); 1428 classifier_ = classifier_->previous(); 1429 } 1430 1431 // Accumulate errors that can be arbitrarily deep in an expression. 1432 // These correspond to the ECMAScript spec's 'Contains' operation 1433 // on productions. This includes: 1434 // 1435 // - YieldExpression is disallowed in arrow parameters in a generator. 1436 // - AwaitExpression is disallowed in arrow parameters in an async function. 1437 // - AwaitExpression is disallowed in async arrow parameters. 1438 // 1439 V8_INLINE void AccumulateFormalParameterContainmentErrors() { 1440 Accumulate(ExpressionClassifier::FormalParameterInitializerProduction | 1441 ExpressionClassifier::AsyncArrowFormalParametersProduction); 1442 } 1443 1444 // Parser base's protected field members. 1445 1446 Scope* scope_; // Scope stack. 1447 FunctionState* function_state_; // Function state stack. 1448 v8::Extension* extension_; 1449 FuncNameInferrer* fni_; 1450 AstValueFactory* ast_value_factory_; // Not owned. 1451 typename Types::Factory ast_node_factory_; 1452 RuntimeCallStats* runtime_call_stats_; 1453 bool parsing_on_main_thread_; 1454 bool parsing_module_; 1455 uintptr_t stack_limit_; 1456 1457 // Parser base's private field members. 1458 1459 private: 1460 Zone* zone_; 1461 ExpressionClassifier* classifier_; 1462 1463 Scanner* scanner_; 1464 bool stack_overflow_; 1465 1466 FunctionLiteral::EagerCompileHint default_eager_compile_hint_; 1467 1468 int function_literal_id_; 1469 1470 bool allow_natives_; 1471 bool allow_tailcalls_; 1472 bool allow_harmony_do_expressions_; 1473 bool allow_harmony_function_sent_; 1474 bool allow_harmony_restrictive_generators_; 1475 bool allow_harmony_trailing_commas_; 1476 bool allow_harmony_class_fields_; 1477 bool allow_harmony_object_rest_spread_; 1478 bool allow_harmony_dynamic_import_; 1479 bool allow_harmony_async_iteration_; 1480 bool allow_harmony_template_escapes_; 1481 1482 friend class DiscardableZoneScope; 1483 }; 1484 1485 template <typename Impl> 1486 ParserBase<Impl>::FunctionState::FunctionState( 1487 FunctionState** function_state_stack, Scope** scope_stack, 1488 DeclarationScope* scope) 1489 : BlockState(scope_stack, scope), 1490 next_materialized_literal_index_(0), 1491 expected_property_count_(0), 1492 function_state_stack_(function_state_stack), 1493 outer_function_state_(*function_state_stack), 1494 scope_(scope), 1495 destructuring_assignments_to_rewrite_(16, scope->zone()), 1496 tail_call_expressions_(scope->zone()), 1497 return_expr_context_(ReturnExprContext::kInsideValidBlock), 1498 non_patterns_to_rewrite_(0, scope->zone()), 1499 reported_errors_(16, scope->zone()), 1500 next_function_is_likely_called_(false), 1501 previous_function_was_likely_called_(false) { 1502 *function_state_stack = this; 1503 if (outer_function_state_) { 1504 outer_function_state_->previous_function_was_likely_called_ = 1505 outer_function_state_->next_function_is_likely_called_; 1506 outer_function_state_->next_function_is_likely_called_ = false; 1507 } 1508 } 1509 1510 template <typename Impl> 1511 ParserBase<Impl>::FunctionState::~FunctionState() { 1512 *function_state_stack_ = outer_function_state_; 1513 } 1514 1515 template <typename Impl> 1516 void ParserBase<Impl>::GetUnexpectedTokenMessage( 1517 Token::Value token, MessageTemplate::Template* message, 1518 Scanner::Location* location, const char** arg, 1519 MessageTemplate::Template default_) { 1520 *arg = nullptr; 1521 switch (token) { 1522 case Token::EOS: 1523 *message = MessageTemplate::kUnexpectedEOS; 1524 break; 1525 case Token::SMI: 1526 case Token::NUMBER: 1527 *message = MessageTemplate::kUnexpectedTokenNumber; 1528 break; 1529 case Token::STRING: 1530 *message = MessageTemplate::kUnexpectedTokenString; 1531 break; 1532 case Token::IDENTIFIER: 1533 *message = MessageTemplate::kUnexpectedTokenIdentifier; 1534 break; 1535 case Token::AWAIT: 1536 case Token::ENUM: 1537 *message = MessageTemplate::kUnexpectedReserved; 1538 break; 1539 case Token::LET: 1540 case Token::STATIC: 1541 case Token::YIELD: 1542 case Token::FUTURE_STRICT_RESERVED_WORD: 1543 *message = is_strict(language_mode()) 1544 ? MessageTemplate::kUnexpectedStrictReserved 1545 : MessageTemplate::kUnexpectedTokenIdentifier; 1546 break; 1547 case Token::TEMPLATE_SPAN: 1548 case Token::TEMPLATE_TAIL: 1549 *message = MessageTemplate::kUnexpectedTemplateString; 1550 break; 1551 case Token::ESCAPED_STRICT_RESERVED_WORD: 1552 case Token::ESCAPED_KEYWORD: 1553 *message = MessageTemplate::kInvalidEscapedReservedWord; 1554 break; 1555 case Token::ILLEGAL: 1556 if (scanner()->has_error()) { 1557 *message = scanner()->error(); 1558 *location = scanner()->error_location(); 1559 } else { 1560 *message = MessageTemplate::kInvalidOrUnexpectedToken; 1561 } 1562 break; 1563 case Token::REGEXP_LITERAL: 1564 *message = MessageTemplate::kUnexpectedTokenRegExp; 1565 break; 1566 default: 1567 const char* name = Token::String(token); 1568 DCHECK(name != NULL); 1569 *arg = name; 1570 break; 1571 } 1572 } 1573 1574 template <typename Impl> 1575 void ParserBase<Impl>::ReportUnexpectedToken(Token::Value token) { 1576 return ReportUnexpectedTokenAt(scanner_->location(), token); 1577 } 1578 1579 template <typename Impl> 1580 void ParserBase<Impl>::ReportUnexpectedTokenAt( 1581 Scanner::Location source_location, Token::Value token, 1582 MessageTemplate::Template message) { 1583 const char* arg; 1584 GetUnexpectedTokenMessage(token, &message, &source_location, &arg); 1585 impl()->ReportMessageAt(source_location, message, arg); 1586 } 1587 1588 template <typename Impl> 1589 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifier( 1590 AllowRestrictedIdentifiers allow_restricted_identifiers, bool* ok) { 1591 ExpressionClassifier classifier(this); 1592 auto result = ParseAndClassifyIdentifier(CHECK_OK_CUSTOM(EmptyIdentifier)); 1593 1594 if (allow_restricted_identifiers == kDontAllowRestrictedIdentifiers) { 1595 ValidateAssignmentPattern(CHECK_OK_CUSTOM(EmptyIdentifier)); 1596 ValidateBindingPattern(CHECK_OK_CUSTOM(EmptyIdentifier)); 1597 } 1598 1599 return result; 1600 } 1601 1602 template <typename Impl> 1603 typename ParserBase<Impl>::IdentifierT 1604 ParserBase<Impl>::ParseAndClassifyIdentifier(bool* ok) { 1605 Token::Value next = Next(); 1606 if (next == Token::IDENTIFIER || next == Token::ASYNC || 1607 (next == Token::AWAIT && !parsing_module_ && !is_async_function())) { 1608 IdentifierT name = impl()->GetSymbol(); 1609 // When this function is used to read a formal parameter, we don't always 1610 // know whether the function is going to be strict or sloppy. Indeed for 1611 // arrow functions we don't always know that the identifier we are reading 1612 // is actually a formal parameter. Therefore besides the errors that we 1613 // must detect because we know we're in strict mode, we also record any 1614 // error that we might make in the future once we know the language mode. 1615 if (impl()->IsEvalOrArguments(name)) { 1616 classifier()->RecordStrictModeFormalParameterError( 1617 scanner()->location(), MessageTemplate::kStrictEvalArguments); 1618 if (is_strict(language_mode())) { 1619 classifier()->RecordBindingPatternError( 1620 scanner()->location(), MessageTemplate::kStrictEvalArguments); 1621 } 1622 } else if (next == Token::AWAIT) { 1623 classifier()->RecordAsyncArrowFormalParametersError( 1624 scanner()->location(), MessageTemplate::kAwaitBindingIdentifier); 1625 } 1626 1627 if (classifier()->duplicate_finder() != nullptr && 1628 scanner()->FindSymbol(classifier()->duplicate_finder())) { 1629 classifier()->RecordDuplicateFormalParameterError(scanner()->location()); 1630 } 1631 return name; 1632 } else if (is_sloppy(language_mode()) && 1633 (next == Token::FUTURE_STRICT_RESERVED_WORD || 1634 next == Token::ESCAPED_STRICT_RESERVED_WORD || 1635 next == Token::LET || next == Token::STATIC || 1636 (next == Token::YIELD && !is_generator()))) { 1637 classifier()->RecordStrictModeFormalParameterError( 1638 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); 1639 if (next == Token::ESCAPED_STRICT_RESERVED_WORD && 1640 is_strict(language_mode())) { 1641 ReportUnexpectedToken(next); 1642 *ok = false; 1643 return impl()->EmptyIdentifier(); 1644 } 1645 if (next == Token::LET || 1646 (next == Token::ESCAPED_STRICT_RESERVED_WORD && 1647 scanner()->is_literal_contextual_keyword(CStrVector("let")))) { 1648 classifier()->RecordLetPatternError( 1649 scanner()->location(), MessageTemplate::kLetInLexicalBinding); 1650 } 1651 return impl()->GetSymbol(); 1652 } else { 1653 ReportUnexpectedToken(next); 1654 *ok = false; 1655 return impl()->EmptyIdentifier(); 1656 } 1657 } 1658 1659 template <class Impl> 1660 typename ParserBase<Impl>::IdentifierT 1661 ParserBase<Impl>::ParseIdentifierOrStrictReservedWord( 1662 FunctionKind function_kind, bool* is_strict_reserved, bool* ok) { 1663 Token::Value next = Next(); 1664 if (next == Token::IDENTIFIER || (next == Token::AWAIT && !parsing_module_ && 1665 !IsAsyncFunction(function_kind)) || 1666 next == Token::ASYNC) { 1667 *is_strict_reserved = false; 1668 } else if (next == Token::ESCAPED_STRICT_RESERVED_WORD || 1669 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || 1670 next == Token::STATIC || 1671 (next == Token::YIELD && !IsGeneratorFunction(function_kind))) { 1672 *is_strict_reserved = true; 1673 } else { 1674 ReportUnexpectedToken(next); 1675 *ok = false; 1676 return impl()->EmptyIdentifier(); 1677 } 1678 1679 return impl()->GetSymbol(); 1680 } 1681 1682 template <typename Impl> 1683 typename ParserBase<Impl>::IdentifierT ParserBase<Impl>::ParseIdentifierName( 1684 bool* ok) { 1685 Token::Value next = Next(); 1686 if (next != Token::IDENTIFIER && next != Token::ASYNC && 1687 next != Token::ENUM && next != Token::AWAIT && next != Token::LET && 1688 next != Token::STATIC && next != Token::YIELD && 1689 next != Token::FUTURE_STRICT_RESERVED_WORD && 1690 next != Token::ESCAPED_KEYWORD && 1691 next != Token::ESCAPED_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { 1692 ReportUnexpectedToken(next); 1693 *ok = false; 1694 return impl()->EmptyIdentifier(); 1695 } 1696 1697 return impl()->GetSymbol(); 1698 } 1699 1700 template <typename Impl> 1701 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral( 1702 bool* ok) { 1703 int pos = peek_position(); 1704 if (!scanner()->ScanRegExpPattern()) { 1705 Next(); 1706 ReportMessage(MessageTemplate::kUnterminatedRegExp); 1707 *ok = false; 1708 return impl()->EmptyExpression(); 1709 } 1710 1711 IdentifierT js_pattern = impl()->GetNextSymbol(); 1712 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags(); 1713 if (flags.IsNothing()) { 1714 Next(); 1715 ReportMessage(MessageTemplate::kMalformedRegExpFlags); 1716 *ok = false; 1717 return impl()->EmptyExpression(); 1718 } 1719 int js_flags = flags.FromJust(); 1720 Next(); 1721 return factory()->NewRegExpLiteral(js_pattern, js_flags, pos); 1722 } 1723 1724 template <typename Impl> 1725 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePrimaryExpression( 1726 bool* is_async, bool* ok) { 1727 // PrimaryExpression :: 1728 // 'this' 1729 // 'null' 1730 // 'true' 1731 // 'false' 1732 // Identifier 1733 // Number 1734 // String 1735 // ArrayLiteral 1736 // ObjectLiteral 1737 // RegExpLiteral 1738 // ClassLiteral 1739 // '(' Expression ')' 1740 // TemplateLiteral 1741 // do Block 1742 // AsyncFunctionLiteral 1743 1744 int beg_pos = peek_position(); 1745 switch (peek()) { 1746 case Token::THIS: { 1747 BindingPatternUnexpectedToken(); 1748 Consume(Token::THIS); 1749 return impl()->ThisExpression(beg_pos); 1750 } 1751 1752 case Token::NULL_LITERAL: 1753 case Token::TRUE_LITERAL: 1754 case Token::FALSE_LITERAL: 1755 case Token::SMI: 1756 case Token::NUMBER: 1757 BindingPatternUnexpectedToken(); 1758 return impl()->ExpressionFromLiteral(Next(), beg_pos); 1759 1760 case Token::ASYNC: 1761 if (!scanner()->HasAnyLineTerminatorAfterNext() && 1762 PeekAhead() == Token::FUNCTION) { 1763 Consume(Token::ASYNC); 1764 return ParseAsyncFunctionLiteral(CHECK_OK); 1765 } 1766 // CoverCallExpressionAndAsyncArrowHead 1767 *is_async = true; 1768 /* falls through */ 1769 case Token::IDENTIFIER: 1770 case Token::LET: 1771 case Token::STATIC: 1772 case Token::YIELD: 1773 case Token::AWAIT: 1774 case Token::ESCAPED_STRICT_RESERVED_WORD: 1775 case Token::FUTURE_STRICT_RESERVED_WORD: { 1776 // Using eval or arguments in this context is OK even in strict mode. 1777 IdentifierT name = ParseAndClassifyIdentifier(CHECK_OK); 1778 return impl()->ExpressionFromIdentifier(name, beg_pos); 1779 } 1780 1781 case Token::STRING: { 1782 BindingPatternUnexpectedToken(); 1783 Consume(Token::STRING); 1784 return impl()->ExpressionFromString(beg_pos); 1785 } 1786 1787 case Token::ASSIGN_DIV: 1788 case Token::DIV: 1789 classifier()->RecordBindingPatternError( 1790 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenRegExp); 1791 return ParseRegExpLiteral(ok); 1792 1793 case Token::LBRACK: 1794 return ParseArrayLiteral(ok); 1795 1796 case Token::LBRACE: 1797 return ParseObjectLiteral(ok); 1798 1799 case Token::LPAREN: { 1800 // Arrow function formal parameters are either a single identifier or a 1801 // list of BindingPattern productions enclosed in parentheses. 1802 // Parentheses are not valid on the LHS of a BindingPattern, so we use the 1803 // is_valid_binding_pattern() check to detect multiple levels of 1804 // parenthesization. 1805 bool pattern_error = !classifier()->is_valid_binding_pattern(); 1806 classifier()->RecordPatternError(scanner()->peek_location(), 1807 MessageTemplate::kUnexpectedToken, 1808 Token::String(Token::LPAREN)); 1809 if (pattern_error) ArrowFormalParametersUnexpectedToken(); 1810 Consume(Token::LPAREN); 1811 if (Check(Token::RPAREN)) { 1812 // ()=>x. The continuation that looks for the => is in 1813 // ParseAssignmentExpression. 1814 classifier()->RecordExpressionError(scanner()->location(), 1815 MessageTemplate::kUnexpectedToken, 1816 Token::String(Token::RPAREN)); 1817 return factory()->NewEmptyParentheses(beg_pos); 1818 } 1819 // Heuristically try to detect immediately called functions before 1820 // seeing the call parentheses. 1821 if (peek() == Token::FUNCTION || 1822 (peek() == Token::ASYNC && PeekAhead() == Token::FUNCTION)) { 1823 function_state_->set_next_function_is_likely_called(); 1824 } 1825 ExpressionT expr = ParseExpressionCoverGrammar(true, CHECK_OK); 1826 Expect(Token::RPAREN, CHECK_OK); 1827 return expr; 1828 } 1829 1830 case Token::CLASS: { 1831 BindingPatternUnexpectedToken(); 1832 Consume(Token::CLASS); 1833 int class_token_pos = position(); 1834 IdentifierT name = impl()->EmptyIdentifier(); 1835 bool is_strict_reserved_name = false; 1836 Scanner::Location class_name_location = Scanner::Location::invalid(); 1837 if (peek_any_identifier()) { 1838 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, 1839 CHECK_OK); 1840 class_name_location = scanner()->location(); 1841 } 1842 return ParseClassLiteral(name, class_name_location, 1843 is_strict_reserved_name, class_token_pos, ok); 1844 } 1845 1846 case Token::TEMPLATE_SPAN: 1847 case Token::TEMPLATE_TAIL: 1848 BindingPatternUnexpectedToken(); 1849 return ParseTemplateLiteral(impl()->NoTemplateTag(), beg_pos, false, ok); 1850 1851 case Token::MOD: 1852 if (allow_natives() || extension_ != NULL) { 1853 BindingPatternUnexpectedToken(); 1854 return ParseV8Intrinsic(ok); 1855 } 1856 break; 1857 1858 case Token::DO: 1859 if (allow_harmony_do_expressions()) { 1860 BindingPatternUnexpectedToken(); 1861 return ParseDoExpression(ok); 1862 } 1863 break; 1864 1865 default: 1866 break; 1867 } 1868 1869 ReportUnexpectedToken(Next()); 1870 *ok = false; 1871 return impl()->EmptyExpression(); 1872 } 1873 1874 template <typename Impl> 1875 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseExpression( 1876 bool accept_IN, bool* ok) { 1877 ExpressionClassifier classifier(this); 1878 ExpressionT result = ParseExpressionCoverGrammar(accept_IN, CHECK_OK); 1879 impl()->RewriteNonPattern(CHECK_OK); 1880 return result; 1881 } 1882 1883 template <typename Impl> 1884 typename ParserBase<Impl>::ExpressionT 1885 ParserBase<Impl>::ParseExpressionCoverGrammar(bool accept_IN, bool* ok) { 1886 // Expression :: 1887 // AssignmentExpression 1888 // Expression ',' AssignmentExpression 1889 1890 ExpressionT result = impl()->EmptyExpression(); 1891 while (true) { 1892 int comma_pos = position(); 1893 ExpressionClassifier binding_classifier(this); 1894 ExpressionT right; 1895 if (Check(Token::ELLIPSIS)) { 1896 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only 1897 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a 1898 // valid expression. 1899 classifier()->RecordExpressionError(scanner()->location(), 1900 MessageTemplate::kUnexpectedToken, 1901 Token::String(Token::ELLIPSIS)); 1902 int ellipsis_pos = position(); 1903 int pattern_pos = peek_position(); 1904 ExpressionT pattern = ParsePrimaryExpression(CHECK_OK); 1905 ValidateBindingPattern(CHECK_OK); 1906 right = factory()->NewSpread(pattern, ellipsis_pos, pattern_pos); 1907 } else { 1908 right = ParseAssignmentExpression(accept_IN, CHECK_OK); 1909 } 1910 // No need to accumulate binding pattern-related errors, since 1911 // an Expression can't be a binding pattern anyway. 1912 impl()->Accumulate(ExpressionClassifier::AllProductions & 1913 ~(ExpressionClassifier::BindingPatternProduction | 1914 ExpressionClassifier::LetPatternProduction)); 1915 if (!impl()->IsIdentifier(right)) classifier()->RecordNonSimpleParameter(); 1916 if (impl()->IsEmptyExpression(result)) { 1917 // First time through the loop. 1918 result = right; 1919 } else { 1920 result = 1921 factory()->NewBinaryOperation(Token::COMMA, result, right, comma_pos); 1922 } 1923 1924 if (!Check(Token::COMMA)) break; 1925 1926 if (right->IsSpread()) { 1927 classifier()->RecordArrowFormalParametersError( 1928 scanner()->location(), MessageTemplate::kParamAfterRest); 1929 } 1930 1931 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN && 1932 PeekAhead() == Token::ARROW) { 1933 // a trailing comma is allowed at the end of an arrow parameter list 1934 break; 1935 } 1936 1937 // Pass on the 'set_next_function_is_likely_called' flag if we have 1938 // several function literals separated by comma. 1939 if (peek() == Token::FUNCTION && 1940 function_state_->previous_function_was_likely_called()) { 1941 function_state_->set_next_function_is_likely_called(); 1942 } 1943 } 1944 1945 return result; 1946 } 1947 1948 template <typename Impl> 1949 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseArrayLiteral( 1950 bool* ok) { 1951 // ArrayLiteral :: 1952 // '[' Expression? (',' Expression?)* ']' 1953 1954 int pos = peek_position(); 1955 ExpressionListT values = impl()->NewExpressionList(4); 1956 int first_spread_index = -1; 1957 Expect(Token::LBRACK, CHECK_OK); 1958 while (peek() != Token::RBRACK) { 1959 ExpressionT elem; 1960 if (peek() == Token::COMMA) { 1961 elem = impl()->GetLiteralTheHole(peek_position()); 1962 } else if (peek() == Token::ELLIPSIS) { 1963 int start_pos = peek_position(); 1964 Consume(Token::ELLIPSIS); 1965 int expr_pos = peek_position(); 1966 ExpressionT argument = ParseAssignmentExpression(true, CHECK_OK); 1967 elem = factory()->NewSpread(argument, start_pos, expr_pos); 1968 1969 if (first_spread_index < 0) { 1970 first_spread_index = values->length(); 1971 } 1972 1973 if (argument->IsAssignment()) { 1974 classifier()->RecordPatternError( 1975 Scanner::Location(start_pos, scanner()->location().end_pos), 1976 MessageTemplate::kInvalidDestructuringTarget); 1977 } else { 1978 CheckDestructuringElement(argument, start_pos, 1979 scanner()->location().end_pos); 1980 } 1981 1982 if (peek() == Token::COMMA) { 1983 classifier()->RecordPatternError( 1984 Scanner::Location(start_pos, scanner()->location().end_pos), 1985 MessageTemplate::kElementAfterRest); 1986 } 1987 } else { 1988 int beg_pos = peek_position(); 1989 elem = ParseAssignmentExpression(true, CHECK_OK); 1990 CheckDestructuringElement(elem, beg_pos, scanner()->location().end_pos); 1991 } 1992 values->Add(elem, zone_); 1993 if (peek() != Token::RBRACK) { 1994 Expect(Token::COMMA, CHECK_OK); 1995 } 1996 } 1997 Expect(Token::RBRACK, CHECK_OK); 1998 1999 ExpressionT result = 2000 factory()->NewArrayLiteral(values, first_spread_index, pos); 2001 if (first_spread_index >= 0) { 2002 result = factory()->NewRewritableExpression(result); 2003 impl()->QueueNonPatternForRewriting(result, ok); 2004 if (!*ok) { 2005 // If the non-pattern rewriting mechanism is used in the future for 2006 // rewriting other things than spreads, this error message will have 2007 // to change. Also, this error message will never appear while pre- 2008 // parsing (this is OK, as it is an implementation limitation). 2009 ReportMessage(MessageTemplate::kTooManySpreads); 2010 return impl()->EmptyExpression(); 2011 } 2012 } 2013 return result; 2014 } 2015 2016 template <class Impl> 2017 bool ParserBase<Impl>::SetPropertyKindFromToken(Token::Value token, 2018 PropertyKind* kind) { 2019 // This returns true, setting the property kind, iff the given token is one 2020 // which must occur after a property name, indicating that the previous token 2021 // was in fact a name and not a modifier (like the "get" in "get x"). 2022 switch (token) { 2023 case Token::COLON: 2024 *kind = PropertyKind::kValueProperty; 2025 return true; 2026 case Token::COMMA: 2027 case Token::RBRACE: 2028 case Token::ASSIGN: 2029 *kind = PropertyKind::kShorthandProperty; 2030 return true; 2031 case Token::LPAREN: 2032 *kind = PropertyKind::kMethodProperty; 2033 return true; 2034 case Token::MUL: 2035 case Token::SEMICOLON: 2036 *kind = PropertyKind::kClassField; 2037 return true; 2038 default: 2039 break; 2040 } 2041 return false; 2042 } 2043 2044 template <class Impl> 2045 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( 2046 IdentifierT* name, PropertyKind* kind, bool* is_generator, bool* is_get, 2047 bool* is_set, bool* is_async, bool* is_computed_name, bool* ok) { 2048 DCHECK(*kind == PropertyKind::kNotSet); 2049 DCHECK(!*is_generator); 2050 DCHECK(!*is_get); 2051 DCHECK(!*is_set); 2052 DCHECK(!*is_async); 2053 DCHECK(!*is_computed_name); 2054 2055 *is_generator = Check(Token::MUL); 2056 if (*is_generator) { 2057 *kind = PropertyKind::kMethodProperty; 2058 } 2059 2060 Token::Value token = peek(); 2061 int pos = peek_position(); 2062 2063 if (!*is_generator && token == Token::ASYNC && 2064 !scanner()->HasAnyLineTerminatorAfterNext()) { 2065 Consume(Token::ASYNC); 2066 token = peek(); 2067 if (SetPropertyKindFromToken(token, kind)) { 2068 *name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'async' 2069 impl()->PushLiteralName(*name); 2070 return factory()->NewStringLiteral(*name, pos); 2071 } 2072 *kind = PropertyKind::kMethodProperty; 2073 *is_async = true; 2074 pos = peek_position(); 2075 } 2076 2077 if (token == Token::IDENTIFIER && !*is_generator && !*is_async) { 2078 // This is checking for 'get' and 'set' in particular. 2079 Consume(Token::IDENTIFIER); 2080 token = peek(); 2081 if (SetPropertyKindFromToken(token, kind) || 2082 !scanner()->IsGetOrSet(is_get, is_set)) { 2083 *name = impl()->GetSymbol(); 2084 impl()->PushLiteralName(*name); 2085 return factory()->NewStringLiteral(*name, pos); 2086 } 2087 *kind = PropertyKind::kAccessorProperty; 2088 pos = peek_position(); 2089 } 2090 2091 // For non computed property names we normalize the name a bit: 2092 // 2093 // "12" -> 12 2094 // 12.3 -> "12.3" 2095 // 12.30 -> "12.3" 2096 // identifier -> "identifier" 2097 // 2098 // This is important because we use the property name as a key in a hash 2099 // table when we compute constant properties. 2100 ExpressionT expression = impl()->EmptyExpression(); 2101 switch (token) { 2102 case Token::STRING: 2103 Consume(Token::STRING); 2104 *name = impl()->GetSymbol(); 2105 break; 2106 2107 case Token::SMI: 2108 Consume(Token::SMI); 2109 *name = impl()->GetNumberAsSymbol(); 2110 break; 2111 2112 case Token::NUMBER: 2113 Consume(Token::NUMBER); 2114 *name = impl()->GetNumberAsSymbol(); 2115 break; 2116 2117 case Token::LBRACK: { 2118 *name = impl()->EmptyIdentifier(); 2119 *is_computed_name = true; 2120 Consume(Token::LBRACK); 2121 ExpressionClassifier computed_name_classifier(this); 2122 expression = ParseAssignmentExpression(true, CHECK_OK); 2123 impl()->RewriteNonPattern(CHECK_OK); 2124 impl()->AccumulateFormalParameterContainmentErrors(); 2125 Expect(Token::RBRACK, CHECK_OK); 2126 break; 2127 } 2128 2129 case Token::ELLIPSIS: 2130 if (allow_harmony_object_rest_spread()) { 2131 *name = impl()->EmptyIdentifier(); 2132 Consume(Token::ELLIPSIS); 2133 expression = ParseAssignmentExpression(true, CHECK_OK); 2134 *kind = PropertyKind::kSpreadProperty; 2135 2136 if (expression->IsAssignment()) { 2137 classifier()->RecordPatternError( 2138 scanner()->location(), 2139 MessageTemplate::kInvalidDestructuringTarget); 2140 } else { 2141 CheckDestructuringElement(expression, pos, 2142 scanner()->location().end_pos); 2143 } 2144 2145 if (peek() != Token::RBRACE) { 2146 classifier()->RecordPatternError(scanner()->location(), 2147 MessageTemplate::kElementAfterRest); 2148 } 2149 return expression; 2150 } 2151 2152 default: 2153 *name = ParseIdentifierName(CHECK_OK); 2154 break; 2155 } 2156 2157 if (*kind == PropertyKind::kNotSet) { 2158 SetPropertyKindFromToken(peek(), kind); 2159 } 2160 2161 if (*is_computed_name) { 2162 return expression; 2163 } 2164 2165 impl()->PushLiteralName(*name); 2166 2167 uint32_t index; 2168 return impl()->IsArrayIndex(*name, &index) 2169 ? factory()->NewNumberLiteral(index, pos) 2170 : factory()->NewStringLiteral(*name, pos); 2171 } 2172 2173 template <typename Impl> 2174 typename ParserBase<Impl>::ClassLiteralPropertyT 2175 ParserBase<Impl>::ParseClassPropertyDefinition( 2176 ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name, 2177 bool* has_seen_constructor, ClassLiteralProperty::Kind* property_kind, 2178 bool* is_static, bool* has_name_static_property, bool* ok) { 2179 DCHECK_NOT_NULL(has_seen_constructor); 2180 DCHECK_NOT_NULL(has_name_static_property); 2181 bool is_get = false; 2182 bool is_set = false; 2183 bool is_generator = false; 2184 bool is_async = false; 2185 *is_static = false; 2186 *property_kind = ClassLiteralProperty::METHOD; 2187 PropertyKind kind = PropertyKind::kNotSet; 2188 2189 Token::Value name_token = peek(); 2190 2191 int function_token_position = scanner()->peek_location().beg_pos; 2192 IdentifierT name = impl()->EmptyIdentifier(); 2193 ExpressionT name_expression; 2194 if (name_token == Token::STATIC) { 2195 Consume(Token::STATIC); 2196 function_token_position = scanner()->peek_location().beg_pos; 2197 if (peek() == Token::LPAREN) { 2198 kind = PropertyKind::kMethodProperty; 2199 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' 2200 name_expression = factory()->NewStringLiteral(name, position()); 2201 } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON || 2202 peek() == Token::RBRACE) { 2203 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' 2204 name_expression = factory()->NewStringLiteral(name, position()); 2205 } else { 2206 *is_static = true; 2207 name_expression = ParsePropertyName( 2208 &name, &kind, &is_generator, &is_get, &is_set, &is_async, 2209 is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); 2210 } 2211 } else { 2212 name_expression = ParsePropertyName( 2213 &name, &kind, &is_generator, &is_get, &is_set, &is_async, 2214 is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); 2215 } 2216 2217 if (!*has_name_static_property && *is_static && impl()->IsName(name)) { 2218 *has_name_static_property = true; 2219 } 2220 2221 switch (kind) { 2222 case PropertyKind::kClassField: 2223 case PropertyKind::kNotSet: // This case is a name followed by a name or 2224 // other property. Here we have to assume 2225 // that's an uninitialized field followed by a 2226 // linebreak followed by a property, with ASI 2227 // adding the semicolon. If not, there will be 2228 // a syntax error after parsing the first name 2229 // as an uninitialized field. 2230 case PropertyKind::kShorthandProperty: 2231 case PropertyKind::kValueProperty: 2232 if (allow_harmony_class_fields()) { 2233 bool has_initializer = Check(Token::ASSIGN); 2234 ExpressionT function_literal = ParseClassFieldForInitializer( 2235 has_initializer, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); 2236 ExpectSemicolon(CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); 2237 *property_kind = ClassLiteralProperty::FIELD; 2238 return factory()->NewClassLiteralProperty( 2239 name_expression, function_literal, *property_kind, *is_static, 2240 *is_computed_name); 2241 } else { 2242 ReportUnexpectedToken(Next()); 2243 *ok = false; 2244 return impl()->EmptyClassLiteralProperty(); 2245 } 2246 2247 case PropertyKind::kMethodProperty: { 2248 DCHECK(!is_get && !is_set); 2249 2250 // MethodDefinition 2251 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' 2252 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' 2253 2254 if (!*is_computed_name) { 2255 checker->CheckClassMethodName( 2256 name_token, PropertyKind::kMethodProperty, is_generator, is_async, 2257 *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); 2258 } 2259 2260 FunctionKind kind = is_generator 2261 ? FunctionKind::kConciseGeneratorMethod 2262 : is_async ? FunctionKind::kAsyncConciseMethod 2263 : FunctionKind::kConciseMethod; 2264 2265 if (!*is_static && impl()->IsConstructor(name)) { 2266 *has_seen_constructor = true; 2267 kind = has_extends ? FunctionKind::kDerivedConstructor 2268 : FunctionKind::kBaseConstructor; 2269 } 2270 2271 ExpressionT value = impl()->ParseFunctionLiteral( 2272 name, scanner()->location(), kSkipFunctionNameCheck, kind, 2273 FLAG_harmony_function_tostring ? function_token_position 2274 : kNoSourcePosition, 2275 FunctionLiteral::kAccessorOrMethod, language_mode(), 2276 CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); 2277 2278 *property_kind = ClassLiteralProperty::METHOD; 2279 return factory()->NewClassLiteralProperty(name_expression, value, 2280 *property_kind, *is_static, 2281 *is_computed_name); 2282 } 2283 2284 case PropertyKind::kAccessorProperty: { 2285 DCHECK((is_get || is_set) && !is_generator && !is_async); 2286 2287 if (!*is_computed_name) { 2288 checker->CheckClassMethodName( 2289 name_token, PropertyKind::kAccessorProperty, false, false, 2290 *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); 2291 // Make sure the name expression is a string since we need a Name for 2292 // Runtime_DefineAccessorPropertyUnchecked and since we can determine 2293 // this statically we can skip the extra runtime check. 2294 name_expression = 2295 factory()->NewStringLiteral(name, name_expression->position()); 2296 } 2297 2298 FunctionKind kind = is_get ? FunctionKind::kGetterFunction 2299 : FunctionKind::kSetterFunction; 2300 2301 FunctionLiteralT value = impl()->ParseFunctionLiteral( 2302 name, scanner()->location(), kSkipFunctionNameCheck, kind, 2303 FLAG_harmony_function_tostring ? function_token_position 2304 : kNoSourcePosition, 2305 FunctionLiteral::kAccessorOrMethod, language_mode(), 2306 CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); 2307 2308 if (!*is_computed_name) { 2309 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); 2310 } 2311 2312 *property_kind = 2313 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER; 2314 return factory()->NewClassLiteralProperty(name_expression, value, 2315 *property_kind, *is_static, 2316 *is_computed_name); 2317 } 2318 case PropertyKind::kSpreadProperty: 2319 UNREACHABLE(); 2320 } 2321 UNREACHABLE(); 2322 return impl()->EmptyClassLiteralProperty(); 2323 } 2324 2325 template <typename Impl> 2326 typename ParserBase<Impl>::FunctionLiteralT 2327 ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer, 2328 bool* ok) { 2329 // Makes a concise method which evaluates and returns the initialized value 2330 // (or undefined if absent). 2331 FunctionKind kind = FunctionKind::kConciseMethod; 2332 DeclarationScope* initializer_scope = NewFunctionScope(kind); 2333 initializer_scope->set_start_position(scanner()->location().end_pos); 2334 FunctionState initializer_state(&function_state_, &scope_, initializer_scope); 2335 DCHECK_EQ(initializer_scope, scope()); 2336 scope()->SetLanguageMode(STRICT); 2337 ExpressionClassifier expression_classifier(this); 2338 ExpressionT value; 2339 if (has_initializer) { 2340 value = this->ParseAssignmentExpression( 2341 true, CHECK_OK_CUSTOM(EmptyFunctionLiteral)); 2342 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(EmptyFunctionLiteral)); 2343 } else { 2344 value = factory()->NewUndefinedLiteral(kNoSourcePosition); 2345 } 2346 initializer_scope->set_end_position(scanner()->location().end_pos); 2347 typename Types::StatementList body = impl()->NewStatementList(1); 2348 body->Add(factory()->NewReturnStatement(value, kNoSourcePosition), zone()); 2349 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( 2350 impl()->EmptyIdentifierString(), initializer_scope, body, 2351 initializer_state.expected_property_count(), 0, 0, 2352 FunctionLiteral::kNoDuplicateParameters, 2353 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_, 2354 initializer_scope->start_position(), true, GetNextFunctionLiteralId()); 2355 return function_literal; 2356 } 2357 2358 template <typename Impl> 2359 typename ParserBase<Impl>::ObjectLiteralPropertyT 2360 ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, 2361 bool* is_computed_name, 2362 bool* is_rest_property, 2363 bool* ok) { 2364 bool is_get = false; 2365 bool is_set = false; 2366 bool is_generator = false; 2367 bool is_async = false; 2368 PropertyKind kind = PropertyKind::kNotSet; 2369 2370 IdentifierT name = impl()->EmptyIdentifier(); 2371 Token::Value name_token = peek(); 2372 int next_beg_pos = scanner()->peek_location().beg_pos; 2373 int next_end_pos = scanner()->peek_location().end_pos; 2374 2375 ExpressionT name_expression = ParsePropertyName( 2376 &name, &kind, &is_generator, &is_get, &is_set, &is_async, 2377 is_computed_name, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2378 2379 switch (kind) { 2380 case PropertyKind::kSpreadProperty: 2381 DCHECK(allow_harmony_object_rest_spread()); 2382 DCHECK(!is_get && !is_set && !is_generator && !is_async && 2383 !*is_computed_name); 2384 DCHECK(name_token == Token::ELLIPSIS); 2385 2386 *is_computed_name = true; 2387 *is_rest_property = true; 2388 2389 return factory()->NewObjectLiteralProperty( 2390 impl()->GetLiteralTheHole(kNoSourcePosition), name_expression, 2391 ObjectLiteralProperty::SPREAD, true); 2392 2393 case PropertyKind::kValueProperty: { 2394 DCHECK(!is_get && !is_set && !is_generator && !is_async); 2395 2396 if (!*is_computed_name) { 2397 checker->CheckDuplicateProto(name_token); 2398 } 2399 Consume(Token::COLON); 2400 int beg_pos = peek_position(); 2401 ExpressionT value = ParseAssignmentExpression( 2402 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2403 CheckDestructuringElement(value, beg_pos, scanner()->location().end_pos); 2404 2405 ObjectLiteralPropertyT result = factory()->NewObjectLiteralProperty( 2406 name_expression, value, *is_computed_name); 2407 2408 if (!*is_computed_name) { 2409 impl()->SetFunctionNameFromPropertyName(result, name); 2410 } 2411 2412 return result; 2413 } 2414 2415 case PropertyKind::kShorthandProperty: { 2416 // PropertyDefinition 2417 // IdentifierReference 2418 // CoverInitializedName 2419 // 2420 // CoverInitializedName 2421 // IdentifierReference Initializer? 2422 DCHECK(!is_get && !is_set && !is_generator && !is_async); 2423 2424 if (!Token::IsIdentifier(name_token, language_mode(), 2425 this->is_generator(), 2426 parsing_module_ || is_async_function())) { 2427 ReportUnexpectedToken(Next()); 2428 *ok = false; 2429 return impl()->EmptyObjectLiteralProperty(); 2430 } 2431 2432 DCHECK(!*is_computed_name); 2433 2434 if (classifier()->duplicate_finder() != nullptr && 2435 scanner()->FindSymbol(classifier()->duplicate_finder())) { 2436 classifier()->RecordDuplicateFormalParameterError( 2437 scanner()->location()); 2438 } 2439 2440 if (impl()->IsEvalOrArguments(name) && is_strict(language_mode())) { 2441 classifier()->RecordBindingPatternError( 2442 scanner()->location(), MessageTemplate::kStrictEvalArguments); 2443 } 2444 2445 if (name_token == Token::LET) { 2446 classifier()->RecordLetPatternError( 2447 scanner()->location(), MessageTemplate::kLetInLexicalBinding); 2448 } 2449 if (name_token == Token::AWAIT) { 2450 DCHECK(!is_async_function()); 2451 classifier()->RecordAsyncArrowFormalParametersError( 2452 Scanner::Location(next_beg_pos, next_end_pos), 2453 MessageTemplate::kAwaitBindingIdentifier); 2454 } 2455 ExpressionT lhs = impl()->ExpressionFromIdentifier(name, next_beg_pos); 2456 CheckDestructuringElement(lhs, next_beg_pos, next_end_pos); 2457 2458 ExpressionT value; 2459 if (peek() == Token::ASSIGN) { 2460 Consume(Token::ASSIGN); 2461 ExpressionClassifier rhs_classifier(this); 2462 ExpressionT rhs = ParseAssignmentExpression( 2463 true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2464 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2465 impl()->AccumulateFormalParameterContainmentErrors(); 2466 value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, 2467 kNoSourcePosition); 2468 classifier()->RecordExpressionError( 2469 Scanner::Location(next_beg_pos, scanner()->location().end_pos), 2470 MessageTemplate::kInvalidCoverInitializedName); 2471 2472 impl()->SetFunctionNameFromIdentifierRef(rhs, lhs); 2473 } else { 2474 value = lhs; 2475 } 2476 2477 return factory()->NewObjectLiteralProperty( 2478 name_expression, value, ObjectLiteralProperty::COMPUTED, false); 2479 } 2480 2481 case PropertyKind::kMethodProperty: { 2482 DCHECK(!is_get && !is_set); 2483 2484 // MethodDefinition 2485 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' 2486 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' 2487 2488 classifier()->RecordPatternError( 2489 Scanner::Location(next_beg_pos, scanner()->location().end_pos), 2490 MessageTemplate::kInvalidDestructuringTarget); 2491 2492 FunctionKind kind = is_generator 2493 ? FunctionKind::kConciseGeneratorMethod 2494 : is_async ? FunctionKind::kAsyncConciseMethod 2495 : FunctionKind::kConciseMethod; 2496 2497 ExpressionT value = impl()->ParseFunctionLiteral( 2498 name, scanner()->location(), kSkipFunctionNameCheck, kind, 2499 FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition, 2500 FunctionLiteral::kAccessorOrMethod, language_mode(), 2501 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2502 2503 return factory()->NewObjectLiteralProperty( 2504 name_expression, value, ObjectLiteralProperty::COMPUTED, 2505 *is_computed_name); 2506 } 2507 2508 case PropertyKind::kAccessorProperty: { 2509 DCHECK((is_get || is_set) && !(is_set && is_get) && !is_generator && 2510 !is_async); 2511 2512 classifier()->RecordPatternError( 2513 Scanner::Location(next_beg_pos, scanner()->location().end_pos), 2514 MessageTemplate::kInvalidDestructuringTarget); 2515 2516 if (!*is_computed_name) { 2517 // Make sure the name expression is a string since we need a Name for 2518 // Runtime_DefineAccessorPropertyUnchecked and since we can determine 2519 // this statically we can skip the extra runtime check. 2520 name_expression = 2521 factory()->NewStringLiteral(name, name_expression->position()); 2522 } 2523 2524 FunctionKind kind = is_get ? FunctionKind::kGetterFunction 2525 : FunctionKind::kSetterFunction; 2526 2527 FunctionLiteralT value = impl()->ParseFunctionLiteral( 2528 name, scanner()->location(), kSkipFunctionNameCheck, kind, 2529 FLAG_harmony_function_tostring ? next_beg_pos : kNoSourcePosition, 2530 FunctionLiteral::kAccessorOrMethod, language_mode(), 2531 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 2532 2533 if (!*is_computed_name) { 2534 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); 2535 } 2536 2537 return factory()->NewObjectLiteralProperty( 2538 name_expression, value, is_get ? ObjectLiteralProperty::GETTER 2539 : ObjectLiteralProperty::SETTER, 2540 *is_computed_name); 2541 } 2542 2543 case PropertyKind::kClassField: 2544 case PropertyKind::kNotSet: 2545 ReportUnexpectedToken(Next()); 2546 *ok = false; 2547 return impl()->EmptyObjectLiteralProperty(); 2548 } 2549 UNREACHABLE(); 2550 return impl()->EmptyObjectLiteralProperty(); 2551 } 2552 2553 template <typename Impl> 2554 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( 2555 bool* ok) { 2556 // ObjectLiteral :: 2557 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' 2558 2559 int pos = peek_position(); 2560 typename Types::ObjectPropertyList properties = 2561 impl()->NewObjectPropertyList(4); 2562 int number_of_boilerplate_properties = 0; 2563 2564 bool has_computed_names = false; 2565 bool has_rest_property = false; 2566 ObjectLiteralChecker checker(this); 2567 2568 Expect(Token::LBRACE, CHECK_OK); 2569 2570 while (peek() != Token::RBRACE) { 2571 FuncNameInferrer::State fni_state(fni_); 2572 2573 bool is_computed_name = false; 2574 bool is_rest_property = false; 2575 ObjectLiteralPropertyT property = ParseObjectPropertyDefinition( 2576 &checker, &is_computed_name, &is_rest_property, CHECK_OK); 2577 2578 if (is_computed_name) { 2579 has_computed_names = true; 2580 } 2581 2582 if (is_rest_property) { 2583 has_rest_property = true; 2584 } 2585 2586 if (impl()->IsBoilerplateProperty(property) && !has_computed_names) { 2587 // Count CONSTANT or COMPUTED properties to maintain the enumeration 2588 // order. 2589 number_of_boilerplate_properties++; 2590 } 2591 2592 properties->Add(property, zone()); 2593 2594 if (peek() != Token::RBRACE) { 2595 // Need {} because of the CHECK_OK macro. 2596 Expect(Token::COMMA, CHECK_OK); 2597 } 2598 2599 if (fni_ != nullptr) fni_->Infer(); 2600 } 2601 Expect(Token::RBRACE, CHECK_OK); 2602 2603 // In pattern rewriter, we rewrite rest property to call out to a 2604 // runtime function passing all the other properties as arguments to 2605 // this runtime function. Here, we make sure that the number of 2606 // properties is less than number of arguments allowed for a runtime 2607 // call. 2608 if (has_rest_property && properties->length() > Code::kMaxArguments) { 2609 this->classifier()->RecordPatternError(Scanner::Location(pos, position()), 2610 MessageTemplate::kTooManyArguments); 2611 } 2612 2613 return factory()->NewObjectLiteral( 2614 properties, number_of_boilerplate_properties, pos, has_rest_property); 2615 } 2616 2617 template <typename Impl> 2618 typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments( 2619 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, bool* ok) { 2620 // Arguments :: 2621 // '(' (AssignmentExpression)*[','] ')' 2622 2623 Scanner::Location spread_arg = Scanner::Location::invalid(); 2624 ExpressionListT result = impl()->NewExpressionList(4); 2625 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 2626 bool done = (peek() == Token::RPAREN); 2627 while (!done) { 2628 int start_pos = peek_position(); 2629 bool is_spread = Check(Token::ELLIPSIS); 2630 int expr_pos = peek_position(); 2631 2632 ExpressionT argument = 2633 ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullExpressionList)); 2634 if (!maybe_arrow) { 2635 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); 2636 } 2637 if (is_spread) { 2638 if (!spread_arg.IsValid()) { 2639 spread_arg.beg_pos = start_pos; 2640 spread_arg.end_pos = peek_position(); 2641 } 2642 argument = factory()->NewSpread(argument, start_pos, expr_pos); 2643 } 2644 result->Add(argument, zone_); 2645 2646 if (result->length() > Code::kMaxArguments) { 2647 ReportMessage(MessageTemplate::kTooManyArguments); 2648 *ok = false; 2649 return impl()->NullExpressionList(); 2650 } 2651 done = (peek() != Token::COMMA); 2652 if (!done) { 2653 Next(); 2654 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) { 2655 // allow trailing comma 2656 done = true; 2657 } 2658 } 2659 } 2660 Scanner::Location location = scanner_->location(); 2661 if (Token::RPAREN != Next()) { 2662 impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); 2663 *ok = false; 2664 return impl()->NullExpressionList(); 2665 } 2666 *first_spread_arg_loc = spread_arg; 2667 2668 if (!maybe_arrow || peek() != Token::ARROW) { 2669 if (maybe_arrow) { 2670 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); 2671 } 2672 } 2673 2674 return result; 2675 } 2676 2677 // Precedence = 2 2678 template <typename Impl> 2679 typename ParserBase<Impl>::ExpressionT 2680 ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) { 2681 // AssignmentExpression :: 2682 // ConditionalExpression 2683 // ArrowFunction 2684 // YieldExpression 2685 // LeftHandSideExpression AssignmentOperator AssignmentExpression 2686 int lhs_beg_pos = peek_position(); 2687 2688 if (peek() == Token::YIELD && is_generator()) { 2689 return ParseYieldExpression(accept_IN, ok); 2690 } 2691 2692 FuncNameInferrer::State fni_state(fni_); 2693 Checkpoint checkpoint(this); 2694 ExpressionClassifier arrow_formals_classifier( 2695 this, classifier()->duplicate_finder()); 2696 2697 Scope::Snapshot scope_snapshot(scope()); 2698 int rewritable_length = 2699 function_state_->destructuring_assignments_to_rewrite().length(); 2700 2701 bool is_async = peek() == Token::ASYNC && 2702 !scanner()->HasAnyLineTerminatorAfterNext() && 2703 IsValidArrowFormalParametersStart(PeekAhead()); 2704 2705 bool parenthesized_formals = peek() == Token::LPAREN; 2706 if (!is_async && !parenthesized_formals) { 2707 ArrowFormalParametersUnexpectedToken(); 2708 } 2709 2710 // Parse a simple, faster sub-grammar (primary expression) if it's evident 2711 // that we have only a trivial expression to parse. 2712 ExpressionT expression; 2713 if (IsTrivialExpression()) { 2714 expression = ParsePrimaryExpression(&is_async, CHECK_OK); 2715 } else { 2716 expression = ParseConditionalExpression(accept_IN, CHECK_OK); 2717 } 2718 2719 if (is_async && impl()->IsIdentifier(expression) && peek_any_identifier() && 2720 PeekAhead() == Token::ARROW) { 2721 // async Identifier => AsyncConciseBody 2722 IdentifierT name = ParseAndClassifyIdentifier(CHECK_OK); 2723 expression = 2724 impl()->ExpressionFromIdentifier(name, position(), InferName::kNo); 2725 if (fni_) { 2726 // Remove `async` keyword from inferred name stack. 2727 fni_->RemoveAsyncKeywordFromEnd(); 2728 } 2729 } 2730 2731 if (peek() == Token::ARROW) { 2732 Scanner::Location arrow_loc = scanner()->peek_location(); 2733 ValidateArrowFormalParameters(expression, parenthesized_formals, is_async, 2734 CHECK_OK); 2735 // This reads strangely, but is correct: it checks whether any 2736 // sub-expression of the parameter list failed to be a valid formal 2737 // parameter initializer. Since YieldExpressions are banned anywhere 2738 // in an arrow parameter list, this is correct. 2739 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to 2740 // "YieldExpression", which is its only use. 2741 ValidateFormalParameterInitializer(ok); 2742 2743 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); 2744 DeclarationScope* scope = 2745 NewFunctionScope(is_async ? FunctionKind::kAsyncArrowFunction 2746 : FunctionKind::kArrowFunction); 2747 // Because the arrow's parameters were parsed in the outer scope, any 2748 // usage flags that might have been triggered there need to be copied 2749 // to the arrow scope. 2750 this->scope()->PropagateUsageFlagsToScope(scope); 2751 2752 scope_snapshot.Reparent(scope); 2753 function_state_->SetDestructuringAssignmentsScope(rewritable_length, scope); 2754 2755 FormalParametersT parameters(scope); 2756 if (!classifier()->is_simple_parameter_list()) { 2757 scope->SetHasNonSimpleParameters(); 2758 parameters.is_simple = false; 2759 } 2760 2761 checkpoint.Restore(¶meters.materialized_literals_count); 2762 2763 scope->set_start_position(lhs_beg_pos); 2764 Scanner::Location duplicate_loc = Scanner::Location::invalid(); 2765 impl()->DeclareArrowFunctionFormalParameters(¶meters, expression, loc, 2766 &duplicate_loc, CHECK_OK); 2767 if (duplicate_loc.IsValid()) { 2768 classifier()->RecordDuplicateFormalParameterError(duplicate_loc); 2769 } 2770 expression = ParseArrowFunctionLiteral(accept_IN, parameters, 2771 rewritable_length, CHECK_OK); 2772 impl()->Discard(); 2773 classifier()->RecordPatternError(arrow_loc, 2774 MessageTemplate::kUnexpectedToken, 2775 Token::String(Token::ARROW)); 2776 2777 if (fni_ != nullptr) fni_->Infer(); 2778 2779 return expression; 2780 } 2781 2782 // "expression" was not itself an arrow function parameter list, but it might 2783 // form part of one. Propagate speculative formal parameter error locations 2784 // (including those for binding patterns, since formal parameters can 2785 // themselves contain binding patterns). 2786 unsigned productions = ExpressionClassifier::AllProductions & 2787 ~ExpressionClassifier::ArrowFormalParametersProduction; 2788 2789 // Parenthesized identifiers and property references are allowed as part 2790 // of a larger assignment pattern, even though parenthesized patterns 2791 // themselves are not allowed, e.g., "[(x)] = []". Only accumulate 2792 // assignment pattern errors if the parsed expression is more complex. 2793 if (IsValidReferenceExpression(expression)) { 2794 productions &= ~ExpressionClassifier::AssignmentPatternProduction; 2795 } 2796 2797 const bool is_destructuring_assignment = 2798 IsValidPattern(expression) && peek() == Token::ASSIGN; 2799 if (is_destructuring_assignment) { 2800 // This is definitely not an expression so don't accumulate 2801 // expression-related errors. 2802 productions &= ~ExpressionClassifier::ExpressionProduction; 2803 } 2804 2805 if (!Token::IsAssignmentOp(peek())) { 2806 // Parsed conditional expression only (no assignment). 2807 // Pending non-pattern expressions must be merged. 2808 impl()->Accumulate(productions); 2809 return expression; 2810 } else { 2811 // Pending non-pattern expressions must be discarded. 2812 impl()->Accumulate(productions, false); 2813 } 2814 2815 if (is_destructuring_assignment) { 2816 ValidateAssignmentPattern(CHECK_OK); 2817 } else { 2818 expression = CheckAndRewriteReferenceExpression( 2819 expression, lhs_beg_pos, scanner()->location().end_pos, 2820 MessageTemplate::kInvalidLhsInAssignment, CHECK_OK); 2821 } 2822 2823 impl()->MarkExpressionAsAssigned(expression); 2824 2825 Token::Value op = Next(); // Get assignment operator. 2826 if (op != Token::ASSIGN) { 2827 classifier()->RecordPatternError(scanner()->location(), 2828 MessageTemplate::kUnexpectedToken, 2829 Token::String(op)); 2830 } 2831 int pos = position(); 2832 2833 ExpressionClassifier rhs_classifier(this); 2834 2835 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); 2836 impl()->RewriteNonPattern(CHECK_OK); 2837 impl()->AccumulateFormalParameterContainmentErrors(); 2838 2839 // TODO(1231235): We try to estimate the set of properties set by 2840 // constructors. We define a new property whenever there is an 2841 // assignment to a property of 'this'. We should probably only add 2842 // properties if we haven't seen them before. Otherwise we'll 2843 // probably overestimate the number of properties. 2844 if (op == Token::ASSIGN && impl()->IsThisProperty(expression)) { 2845 function_state_->AddProperty(); 2846 } 2847 2848 impl()->CheckAssigningFunctionLiteralToProperty(expression, right); 2849 2850 if (fni_ != NULL) { 2851 // Check if the right hand side is a call to avoid inferring a 2852 // name if we're dealing with "a = function(){...}();"-like 2853 // expression. 2854 if ((op == Token::INIT || op == Token::ASSIGN) && 2855 (!right->IsCall() && !right->IsCallNew())) { 2856 fni_->Infer(); 2857 } else { 2858 fni_->RemoveLastFunction(); 2859 } 2860 } 2861 2862 if (op == Token::ASSIGN) { 2863 impl()->SetFunctionNameFromIdentifierRef(right, expression); 2864 } 2865 2866 if (op == Token::ASSIGN_EXP) { 2867 DCHECK(!is_destructuring_assignment); 2868 return impl()->RewriteAssignExponentiation(expression, right, pos); 2869 } 2870 2871 ExpressionT result = factory()->NewAssignment(op, expression, right, pos); 2872 2873 if (is_destructuring_assignment) { 2874 result = factory()->NewRewritableExpression(result); 2875 impl()->QueueDestructuringAssignmentForRewriting(result); 2876 } 2877 2878 return result; 2879 } 2880 2881 template <typename Impl> 2882 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( 2883 bool accept_IN, bool* ok) { 2884 // YieldExpression :: 2885 // 'yield' ([no line terminator] '*'? AssignmentExpression)? 2886 int pos = peek_position(); 2887 classifier()->RecordPatternError( 2888 scanner()->peek_location(), MessageTemplate::kInvalidDestructuringTarget); 2889 classifier()->RecordFormalParameterInitializerError( 2890 scanner()->peek_location(), MessageTemplate::kYieldInParameter); 2891 Expect(Token::YIELD, CHECK_OK); 2892 ExpressionT generator_object = 2893 factory()->NewVariableProxy(function_state_->generator_object_variable()); 2894 // The following initialization is necessary. 2895 ExpressionT expression = impl()->EmptyExpression(); 2896 bool delegating = false; // yield* 2897 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { 2898 if (Check(Token::MUL)) delegating = true; 2899 switch (peek()) { 2900 case Token::EOS: 2901 case Token::SEMICOLON: 2902 case Token::RBRACE: 2903 case Token::RBRACK: 2904 case Token::RPAREN: 2905 case Token::COLON: 2906 case Token::COMMA: 2907 // The above set of tokens is the complete set of tokens that can appear 2908 // after an AssignmentExpression, and none of them can start an 2909 // AssignmentExpression. This allows us to avoid looking for an RHS for 2910 // a regular yield, given only one look-ahead token. 2911 if (!delegating) break; 2912 // Delegating yields require an RHS; fall through. 2913 default: 2914 expression = ParseAssignmentExpression(accept_IN, CHECK_OK); 2915 impl()->RewriteNonPattern(CHECK_OK); 2916 break; 2917 } 2918 } 2919 2920 if (delegating) { 2921 return impl()->RewriteYieldStar(generator_object, expression, pos); 2922 } 2923 2924 expression = impl()->BuildIteratorResult(expression, false); 2925 // Hackily disambiguate o from o.next and o [Symbol.iterator](). 2926 // TODO(verwaest): Come up with a better solution. 2927 ExpressionT yield = factory()->NewYield(generator_object, expression, pos, 2928 Yield::kOnExceptionThrow); 2929 return yield; 2930 } 2931 2932 // Precedence = 3 2933 template <typename Impl> 2934 typename ParserBase<Impl>::ExpressionT 2935 ParserBase<Impl>::ParseConditionalExpression(bool accept_IN, 2936 bool* ok) { 2937 // ConditionalExpression :: 2938 // LogicalOrExpression 2939 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 2940 2941 int pos = peek_position(); 2942 // We start using the binary expression parser for prec >= 4 only! 2943 ExpressionT expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); 2944 if (peek() != Token::CONDITIONAL) return expression; 2945 impl()->RewriteNonPattern(CHECK_OK); 2946 BindingPatternUnexpectedToken(); 2947 ArrowFormalParametersUnexpectedToken(); 2948 Consume(Token::CONDITIONAL); 2949 // In parsing the first assignment expression in conditional 2950 // expressions we always accept the 'in' keyword; see ECMA-262, 2951 // section 11.12, page 58. 2952 ExpressionT left = ParseAssignmentExpression(true, CHECK_OK); 2953 impl()->RewriteNonPattern(CHECK_OK); 2954 Expect(Token::COLON, CHECK_OK); 2955 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); 2956 impl()->RewriteNonPattern(CHECK_OK); 2957 return factory()->NewConditional(expression, left, right, pos); 2958 } 2959 2960 2961 // Precedence >= 4 2962 template <typename Impl> 2963 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression( 2964 int prec, bool accept_IN, bool* ok) { 2965 DCHECK(prec >= 4); 2966 ExpressionT x = ParseUnaryExpression(CHECK_OK); 2967 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 2968 // prec1 >= 4 2969 while (Precedence(peek(), accept_IN) == prec1) { 2970 impl()->RewriteNonPattern(CHECK_OK); 2971 BindingPatternUnexpectedToken(); 2972 ArrowFormalParametersUnexpectedToken(); 2973 Token::Value op = Next(); 2974 int pos = position(); 2975 2976 const bool is_right_associative = op == Token::EXP; 2977 const int next_prec = is_right_associative ? prec1 : prec1 + 1; 2978 ExpressionT y = ParseBinaryExpression(next_prec, accept_IN, CHECK_OK); 2979 impl()->RewriteNonPattern(CHECK_OK); 2980 2981 if (impl()->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos)) { 2982 continue; 2983 } 2984 2985 // For now we distinguish between comparisons and other binary 2986 // operations. (We could combine the two and get rid of this 2987 // code and AST node eventually.) 2988 if (Token::IsCompareOp(op)) { 2989 // We have a comparison. 2990 Token::Value cmp = op; 2991 switch (op) { 2992 case Token::NE: cmp = Token::EQ; break; 2993 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; 2994 default: break; 2995 } 2996 x = factory()->NewCompareOperation(cmp, x, y, pos); 2997 if (cmp != op) { 2998 // The comparison was negated - add a NOT. 2999 x = factory()->NewUnaryOperation(Token::NOT, x, pos); 3000 } 3001 } else if (op == Token::EXP) { 3002 x = impl()->RewriteExponentiation(x, y, pos); 3003 } else { 3004 // We have a "normal" binary operation. 3005 x = factory()->NewBinaryOperation(op, x, y, pos); 3006 } 3007 } 3008 } 3009 return x; 3010 } 3011 3012 template <typename Impl> 3013 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseUnaryExpression( 3014 bool* ok) { 3015 // UnaryExpression :: 3016 // PostfixExpression 3017 // 'delete' UnaryExpression 3018 // 'void' UnaryExpression 3019 // 'typeof' UnaryExpression 3020 // '++' UnaryExpression 3021 // '--' UnaryExpression 3022 // '+' UnaryExpression 3023 // '-' UnaryExpression 3024 // '~' UnaryExpression 3025 // '!' UnaryExpression 3026 // [+Await] AwaitExpression[?Yield] 3027 3028 Token::Value op = peek(); 3029 if (Token::IsUnaryOp(op)) { 3030 BindingPatternUnexpectedToken(); 3031 ArrowFormalParametersUnexpectedToken(); 3032 3033 op = Next(); 3034 int pos = position(); 3035 3036 // Assume "! function ..." indicates the function is likely to be called. 3037 if (op == Token::NOT && peek() == Token::FUNCTION) { 3038 function_state_->set_next_function_is_likely_called(); 3039 } 3040 3041 ExpressionT expression = ParseUnaryExpression(CHECK_OK); 3042 impl()->RewriteNonPattern(CHECK_OK); 3043 3044 if (op == Token::DELETE && is_strict(language_mode())) { 3045 if (impl()->IsIdentifier(expression)) { 3046 // "delete identifier" is a syntax error in strict mode. 3047 ReportMessage(MessageTemplate::kStrictDelete); 3048 *ok = false; 3049 return impl()->EmptyExpression(); 3050 } 3051 } 3052 3053 if (peek() == Token::EXP) { 3054 ReportUnexpectedToken(Next()); 3055 *ok = false; 3056 return impl()->EmptyExpression(); 3057 } 3058 3059 // Allow the parser's implementation to rewrite the expression. 3060 return impl()->BuildUnaryExpression(expression, op, pos); 3061 } else if (Token::IsCountOp(op)) { 3062 BindingPatternUnexpectedToken(); 3063 ArrowFormalParametersUnexpectedToken(); 3064 op = Next(); 3065 int beg_pos = peek_position(); 3066 ExpressionT expression = ParseUnaryExpression(CHECK_OK); 3067 expression = CheckAndRewriteReferenceExpression( 3068 expression, beg_pos, scanner()->location().end_pos, 3069 MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); 3070 impl()->MarkExpressionAsAssigned(expression); 3071 impl()->RewriteNonPattern(CHECK_OK); 3072 3073 return factory()->NewCountOperation(op, 3074 true /* prefix */, 3075 expression, 3076 position()); 3077 3078 } else if (is_async_function() && peek() == Token::AWAIT) { 3079 classifier()->RecordFormalParameterInitializerError( 3080 scanner()->peek_location(), 3081 MessageTemplate::kAwaitExpressionFormalParameter); 3082 3083 int await_pos = peek_position(); 3084 Consume(Token::AWAIT); 3085 3086 ExpressionT value = ParseUnaryExpression(CHECK_OK); 3087 3088 return impl()->RewriteAwaitExpression(value, await_pos); 3089 } else { 3090 return ParsePostfixExpression(ok); 3091 } 3092 } 3093 3094 template <typename Impl> 3095 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression( 3096 bool* ok) { 3097 // PostfixExpression :: 3098 // LeftHandSideExpression ('++' | '--')? 3099 3100 int lhs_beg_pos = peek_position(); 3101 ExpressionT expression = ParseLeftHandSideExpression(CHECK_OK); 3102 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 3103 Token::IsCountOp(peek())) { 3104 BindingPatternUnexpectedToken(); 3105 ArrowFormalParametersUnexpectedToken(); 3106 3107 expression = CheckAndRewriteReferenceExpression( 3108 expression, lhs_beg_pos, scanner()->location().end_pos, 3109 MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); 3110 impl()->MarkExpressionAsAssigned(expression); 3111 impl()->RewriteNonPattern(CHECK_OK); 3112 3113 Token::Value next = Next(); 3114 expression = 3115 factory()->NewCountOperation(next, 3116 false /* postfix */, 3117 expression, 3118 position()); 3119 } 3120 return expression; 3121 } 3122 3123 template <typename Impl> 3124 typename ParserBase<Impl>::ExpressionT 3125 ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) { 3126 // LeftHandSideExpression :: 3127 // (NewExpression | MemberExpression) ... 3128 3129 bool is_async = false; 3130 ExpressionT result = 3131 ParseMemberWithNewPrefixesExpression(&is_async, CHECK_OK); 3132 3133 while (true) { 3134 switch (peek()) { 3135 case Token::LBRACK: { 3136 impl()->RewriteNonPattern(CHECK_OK); 3137 BindingPatternUnexpectedToken(); 3138 ArrowFormalParametersUnexpectedToken(); 3139 Consume(Token::LBRACK); 3140 int pos = position(); 3141 ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK); 3142 impl()->RewriteNonPattern(CHECK_OK); 3143 result = factory()->NewProperty(result, index, pos); 3144 Expect(Token::RBRACK, CHECK_OK); 3145 break; 3146 } 3147 3148 case Token::LPAREN: { 3149 int pos; 3150 impl()->RewriteNonPattern(CHECK_OK); 3151 BindingPatternUnexpectedToken(); 3152 if (scanner()->current_token() == Token::IDENTIFIER || 3153 scanner()->current_token() == Token::SUPER || 3154 scanner()->current_token() == Token::ASYNC) { 3155 // For call of an identifier we want to report position of 3156 // the identifier as position of the call in the stack trace. 3157 pos = position(); 3158 } else { 3159 // For other kinds of calls we record position of the parenthesis as 3160 // position of the call. Note that this is extremely important for 3161 // expressions of the form function(){...}() for which call position 3162 // should not point to the closing brace otherwise it will intersect 3163 // with positions recorded for function literal and confuse debugger. 3164 pos = peek_position(); 3165 // Also the trailing parenthesis are a hint that the function will 3166 // be called immediately. If we happen to have parsed a preceding 3167 // function literal eagerly, we can also compile it eagerly. 3168 if (result->IsFunctionLiteral()) { 3169 result->AsFunctionLiteral()->SetShouldEagerCompile(); 3170 } 3171 } 3172 Scanner::Location spread_pos; 3173 ExpressionListT args; 3174 if (V8_UNLIKELY(is_async && impl()->IsIdentifier(result))) { 3175 ExpressionClassifier async_classifier(this); 3176 args = ParseArguments(&spread_pos, true, CHECK_OK); 3177 if (peek() == Token::ARROW) { 3178 if (fni_) { 3179 fni_->RemoveAsyncKeywordFromEnd(); 3180 } 3181 ValidateBindingPattern(CHECK_OK); 3182 ValidateFormalParameterInitializer(CHECK_OK); 3183 if (!classifier()->is_valid_async_arrow_formal_parameters()) { 3184 ReportClassifierError( 3185 classifier()->async_arrow_formal_parameters_error()); 3186 *ok = false; 3187 return impl()->EmptyExpression(); 3188 } 3189 if (args->length()) { 3190 // async ( Arguments ) => ... 3191 return impl()->ExpressionListToExpression(args); 3192 } 3193 // async () => ... 3194 return factory()->NewEmptyParentheses(pos); 3195 } else { 3196 impl()->AccumulateFormalParameterContainmentErrors(); 3197 } 3198 } else { 3199 args = ParseArguments(&spread_pos, false, CHECK_OK); 3200 } 3201 3202 ArrowFormalParametersUnexpectedToken(); 3203 3204 // Keep track of eval() calls since they disable all local variable 3205 // optimizations. 3206 // The calls that need special treatment are the 3207 // direct eval calls. These calls are all of the form eval(...), with 3208 // no explicit receiver. 3209 // These calls are marked as potentially direct eval calls. Whether 3210 // they are actually direct calls to eval is determined at run time. 3211 Call::PossiblyEval is_possibly_eval = 3212 CheckPossibleEvalCall(result, scope()); 3213 3214 bool is_super_call = result->IsSuperCallReference(); 3215 if (spread_pos.IsValid()) { 3216 result = impl()->SpreadCall(result, args, pos, is_possibly_eval); 3217 } else { 3218 result = factory()->NewCall(result, args, pos, is_possibly_eval); 3219 } 3220 3221 // Explicit calls to the super constructor using super() perform an 3222 // implicit binding assignment to the 'this' variable. 3223 if (is_super_call) { 3224 ExpressionT this_expr = impl()->ThisExpression(pos); 3225 result = 3226 factory()->NewAssignment(Token::INIT, this_expr, result, pos); 3227 } 3228 3229 if (fni_ != NULL) fni_->RemoveLastFunction(); 3230 break; 3231 } 3232 3233 case Token::PERIOD: { 3234 impl()->RewriteNonPattern(CHECK_OK); 3235 BindingPatternUnexpectedToken(); 3236 ArrowFormalParametersUnexpectedToken(); 3237 Consume(Token::PERIOD); 3238 int pos = position(); 3239 IdentifierT name = ParseIdentifierName(CHECK_OK); 3240 result = factory()->NewProperty( 3241 result, factory()->NewStringLiteral(name, pos), pos); 3242 impl()->PushLiteralName(name); 3243 break; 3244 } 3245 3246 case Token::TEMPLATE_SPAN: 3247 case Token::TEMPLATE_TAIL: { 3248 impl()->RewriteNonPattern(CHECK_OK); 3249 BindingPatternUnexpectedToken(); 3250 ArrowFormalParametersUnexpectedToken(); 3251 result = ParseTemplateLiteral(result, position(), true, CHECK_OK); 3252 break; 3253 } 3254 3255 default: 3256 return result; 3257 } 3258 } 3259 } 3260 3261 template <typename Impl> 3262 typename ParserBase<Impl>::ExpressionT 3263 ParserBase<Impl>::ParseMemberWithNewPrefixesExpression(bool* is_async, 3264 bool* ok) { 3265 // NewExpression :: 3266 // ('new')+ MemberExpression 3267 // 3268 // NewTarget :: 3269 // 'new' '.' 'target' 3270 3271 // The grammar for new expressions is pretty warped. We can have several 'new' 3272 // keywords following each other, and then a MemberExpression. When we see '(' 3273 // after the MemberExpression, it's associated with the rightmost unassociated 3274 // 'new' to create a NewExpression with arguments. However, a NewExpression 3275 // can also occur without arguments. 3276 3277 // Examples of new expression: 3278 // new foo.bar().baz means (new (foo.bar)()).baz 3279 // new foo()() means (new foo())() 3280 // new new foo()() means (new (new foo())()) 3281 // new new foo means new (new foo) 3282 // new new foo() means new (new foo()) 3283 // new new foo().bar().baz means (new (new foo()).bar()).baz 3284 3285 if (peek() == Token::NEW) { 3286 BindingPatternUnexpectedToken(); 3287 ArrowFormalParametersUnexpectedToken(); 3288 Consume(Token::NEW); 3289 int new_pos = position(); 3290 ExpressionT result; 3291 if (peek() == Token::SUPER) { 3292 const bool is_new = true; 3293 result = ParseSuperExpression(is_new, CHECK_OK); 3294 } else if (allow_harmony_dynamic_import() && peek() == Token::IMPORT) { 3295 impl()->ReportMessageAt(scanner()->peek_location(), 3296 MessageTemplate::kImportCallNotNewExpression); 3297 *ok = false; 3298 return impl()->EmptyExpression(); 3299 } else if (peek() == Token::PERIOD) { 3300 return ParseNewTargetExpression(CHECK_OK); 3301 } else { 3302 result = ParseMemberWithNewPrefixesExpression(is_async, CHECK_OK); 3303 } 3304 impl()->RewriteNonPattern(CHECK_OK); 3305 if (peek() == Token::LPAREN) { 3306 // NewExpression with arguments. 3307 Scanner::Location spread_pos; 3308 ExpressionListT args = ParseArguments(&spread_pos, CHECK_OK); 3309 3310 if (spread_pos.IsValid()) { 3311 result = impl()->SpreadCallNew(result, args, new_pos); 3312 } else { 3313 result = factory()->NewCallNew(result, args, new_pos); 3314 } 3315 // The expression can still continue with . or [ after the arguments. 3316 result = ParseMemberExpressionContinuation(result, is_async, CHECK_OK); 3317 return result; 3318 } 3319 // NewExpression without arguments. 3320 return factory()->NewCallNew(result, impl()->NewExpressionList(0), new_pos); 3321 } 3322 // No 'new' or 'super' keyword. 3323 return ParseMemberExpression(is_async, ok); 3324 } 3325 3326 template <typename Impl> 3327 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseMemberExpression( 3328 bool* is_async, bool* ok) { 3329 // MemberExpression :: 3330 // (PrimaryExpression | FunctionLiteral | ClassLiteral) 3331 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* 3332 // 3333 // CallExpression :: 3334 // (SuperCall | ImportCall) 3335 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* 3336 // 3337 // The '[' Expression ']' and '.' Identifier parts are parsed by 3338 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the 3339 // caller. 3340 3341 // Parse the initial primary or function expression. 3342 ExpressionT result; 3343 if (peek() == Token::FUNCTION) { 3344 BindingPatternUnexpectedToken(); 3345 ArrowFormalParametersUnexpectedToken(); 3346 3347 Consume(Token::FUNCTION); 3348 int function_token_position = position(); 3349 3350 if (allow_harmony_function_sent() && peek() == Token::PERIOD) { 3351 // function.sent 3352 int pos = position(); 3353 ExpectMetaProperty(CStrVector("sent"), "function.sent", pos, CHECK_OK); 3354 3355 if (!is_generator()) { 3356 // TODO(neis): allow escaping into closures? 3357 impl()->ReportMessageAt(scanner()->location(), 3358 MessageTemplate::kUnexpectedFunctionSent); 3359 *ok = false; 3360 return impl()->EmptyExpression(); 3361 } 3362 3363 return impl()->FunctionSentExpression(pos); 3364 } 3365 3366 FunctionKind function_kind = Check(Token::MUL) 3367 ? FunctionKind::kGeneratorFunction 3368 : FunctionKind::kNormalFunction; 3369 IdentifierT name = impl()->EmptyIdentifier(); 3370 bool is_strict_reserved_name = false; 3371 Scanner::Location function_name_location = Scanner::Location::invalid(); 3372 FunctionLiteral::FunctionType function_type = 3373 FunctionLiteral::kAnonymousExpression; 3374 if (impl()->ParsingDynamicFunctionDeclaration()) { 3375 // We don't want dynamic functions to actually declare their name 3376 // "anonymous". We just want that name in the toString(). 3377 Consume(Token::IDENTIFIER); 3378 DCHECK(scanner()->UnescapedLiteralMatches("anonymous", 9)); 3379 } else if (peek_any_identifier()) { 3380 name = ParseIdentifierOrStrictReservedWord( 3381 function_kind, &is_strict_reserved_name, CHECK_OK); 3382 function_name_location = scanner()->location(); 3383 function_type = FunctionLiteral::kNamedExpression; 3384 } 3385 result = impl()->ParseFunctionLiteral( 3386 name, function_name_location, 3387 is_strict_reserved_name ? kFunctionNameIsStrictReserved 3388 : kFunctionNameValidityUnknown, 3389 function_kind, function_token_position, function_type, language_mode(), 3390 CHECK_OK); 3391 } else if (peek() == Token::SUPER) { 3392 const bool is_new = false; 3393 result = ParseSuperExpression(is_new, CHECK_OK); 3394 } else if (allow_harmony_dynamic_import() && peek() == Token::IMPORT) { 3395 result = ParseDynamicImportExpression(CHECK_OK); 3396 } else { 3397 result = ParsePrimaryExpression(is_async, CHECK_OK); 3398 } 3399 3400 result = ParseMemberExpressionContinuation(result, is_async, CHECK_OK); 3401 return result; 3402 } 3403 3404 template <typename Impl> 3405 typename ParserBase<Impl>::ExpressionT 3406 ParserBase<Impl>::ParseDynamicImportExpression(bool* ok) { 3407 DCHECK(allow_harmony_dynamic_import()); 3408 Consume(Token::IMPORT); 3409 int pos = position(); 3410 Expect(Token::LPAREN, CHECK_OK); 3411 ExpressionT arg = ParseAssignmentExpression(true, CHECK_OK); 3412 Expect(Token::RPAREN, CHECK_OK); 3413 ZoneList<ExpressionT>* args = new (zone()) ZoneList<ExpressionT>(1, zone()); 3414 args->Add(arg, zone()); 3415 return factory()->NewCallRuntime(Runtime::kDynamicImportCall, args, pos); 3416 } 3417 3418 template <typename Impl> 3419 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseSuperExpression( 3420 bool is_new, bool* ok) { 3421 Expect(Token::SUPER, CHECK_OK); 3422 int pos = position(); 3423 3424 DeclarationScope* scope = GetReceiverScope(); 3425 FunctionKind kind = scope->function_kind(); 3426 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || 3427 IsClassConstructor(kind)) { 3428 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { 3429 scope->RecordSuperPropertyUsage(); 3430 return impl()->NewSuperPropertyReference(pos); 3431 } 3432 // new super() is never allowed. 3433 // super() is only allowed in derived constructor 3434 if (!is_new && peek() == Token::LPAREN && IsDerivedConstructor(kind)) { 3435 // TODO(rossberg): This might not be the correct FunctionState for the 3436 // method here. 3437 return impl()->NewSuperCallReference(pos); 3438 } 3439 } 3440 3441 impl()->ReportMessageAt(scanner()->location(), 3442 MessageTemplate::kUnexpectedSuper); 3443 *ok = false; 3444 return impl()->EmptyExpression(); 3445 } 3446 3447 template <typename Impl> 3448 void ParserBase<Impl>::ExpectMetaProperty(Vector<const char> property_name, 3449 const char* full_name, int pos, 3450 bool* ok) { 3451 Consume(Token::PERIOD); 3452 ExpectContextualKeyword(property_name, CHECK_OK_CUSTOM(Void)); 3453 if (scanner()->literal_contains_escapes()) { 3454 impl()->ReportMessageAt( 3455 Scanner::Location(pos, scanner()->location().end_pos), 3456 MessageTemplate::kInvalidEscapedMetaProperty, full_name); 3457 *ok = false; 3458 } 3459 } 3460 3461 template <typename Impl> 3462 typename ParserBase<Impl>::ExpressionT 3463 ParserBase<Impl>::ParseNewTargetExpression(bool* ok) { 3464 int pos = position(); 3465 ExpectMetaProperty(CStrVector("target"), "new.target", pos, CHECK_OK); 3466 3467 if (!GetReceiverScope()->is_function_scope()) { 3468 impl()->ReportMessageAt(scanner()->location(), 3469 MessageTemplate::kUnexpectedNewTarget); 3470 *ok = false; 3471 return impl()->EmptyExpression(); 3472 } 3473 3474 return impl()->NewTargetExpression(pos); 3475 } 3476 3477 template <typename Impl> 3478 typename ParserBase<Impl>::ExpressionT 3479 ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression, 3480 bool* is_async, bool* ok) { 3481 // Parses this part of MemberExpression: 3482 // ('[' Expression ']' | '.' Identifier | TemplateLiteral)* 3483 while (true) { 3484 switch (peek()) { 3485 case Token::LBRACK: { 3486 *is_async = false; 3487 impl()->RewriteNonPattern(CHECK_OK); 3488 BindingPatternUnexpectedToken(); 3489 ArrowFormalParametersUnexpectedToken(); 3490 3491 Consume(Token::LBRACK); 3492 int pos = position(); 3493 ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK); 3494 impl()->RewriteNonPattern(CHECK_OK); 3495 expression = factory()->NewProperty(expression, index, pos); 3496 impl()->PushPropertyName(index); 3497 Expect(Token::RBRACK, CHECK_OK); 3498 break; 3499 } 3500 case Token::PERIOD: { 3501 *is_async = false; 3502 impl()->RewriteNonPattern(CHECK_OK); 3503 BindingPatternUnexpectedToken(); 3504 ArrowFormalParametersUnexpectedToken(); 3505 3506 Consume(Token::PERIOD); 3507 int pos = position(); 3508 IdentifierT name = ParseIdentifierName(CHECK_OK); 3509 expression = factory()->NewProperty( 3510 expression, factory()->NewStringLiteral(name, pos), pos); 3511 impl()->PushLiteralName(name); 3512 break; 3513 } 3514 case Token::TEMPLATE_SPAN: 3515 case Token::TEMPLATE_TAIL: { 3516 *is_async = false; 3517 impl()->RewriteNonPattern(CHECK_OK); 3518 BindingPatternUnexpectedToken(); 3519 ArrowFormalParametersUnexpectedToken(); 3520 int pos; 3521 if (scanner()->current_token() == Token::IDENTIFIER) { 3522 pos = position(); 3523 } else { 3524 pos = peek_position(); 3525 if (expression->IsFunctionLiteral()) { 3526 // If the tag function looks like an IIFE, set_parenthesized() to 3527 // force eager compilation. 3528 expression->AsFunctionLiteral()->SetShouldEagerCompile(); 3529 } 3530 } 3531 expression = ParseTemplateLiteral(expression, pos, true, CHECK_OK); 3532 break; 3533 } 3534 case Token::ILLEGAL: { 3535 ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL); 3536 *ok = false; 3537 return impl()->EmptyExpression(); 3538 } 3539 default: 3540 return expression; 3541 } 3542 } 3543 DCHECK(false); 3544 return impl()->EmptyExpression(); 3545 } 3546 3547 template <typename Impl> 3548 void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters, 3549 bool* ok) { 3550 // FormalParameter[Yield,GeneratorParameter] : 3551 // BindingElement[?Yield, ?GeneratorParameter] 3552 bool is_rest = parameters->has_rest; 3553 3554 ExpressionT pattern = ParsePrimaryExpression(CHECK_OK_CUSTOM(Void)); 3555 ValidateBindingPattern(CHECK_OK_CUSTOM(Void)); 3556 3557 if (!impl()->IsIdentifier(pattern)) { 3558 parameters->is_simple = false; 3559 ValidateFormalParameterInitializer(CHECK_OK_CUSTOM(Void)); 3560 classifier()->RecordNonSimpleParameter(); 3561 } 3562 3563 ExpressionT initializer = impl()->EmptyExpression(); 3564 if (!is_rest && Check(Token::ASSIGN)) { 3565 ExpressionClassifier init_classifier(this); 3566 initializer = ParseAssignmentExpression(true, CHECK_OK_CUSTOM(Void)); 3567 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void)); 3568 ValidateFormalParameterInitializer(CHECK_OK_CUSTOM(Void)); 3569 parameters->is_simple = false; 3570 impl()->Discard(); 3571 classifier()->RecordNonSimpleParameter(); 3572 3573 impl()->SetFunctionNameFromIdentifierRef(initializer, pattern); 3574 } 3575 3576 impl()->AddFormalParameter(parameters, pattern, initializer, 3577 scanner()->location().end_pos, is_rest); 3578 } 3579 3580 template <typename Impl> 3581 void ParserBase<Impl>::ParseFormalParameterList(FormalParametersT* parameters, 3582 bool* ok) { 3583 // FormalParameters[Yield] : 3584 // [empty] 3585 // FunctionRestParameter[?Yield] 3586 // FormalParameterList[?Yield] 3587 // FormalParameterList[?Yield] , 3588 // FormalParameterList[?Yield] , FunctionRestParameter[?Yield] 3589 // 3590 // FormalParameterList[Yield] : 3591 // FormalParameter[?Yield] 3592 // FormalParameterList[?Yield] , FormalParameter[?Yield] 3593 3594 DCHECK_EQ(0, parameters->arity); 3595 3596 if (peek() != Token::RPAREN) { 3597 while (true) { 3598 if (parameters->arity > Code::kMaxArguments) { 3599 ReportMessage(MessageTemplate::kTooManyParameters); 3600 *ok = false; 3601 return; 3602 } 3603 parameters->has_rest = Check(Token::ELLIPSIS); 3604 ParseFormalParameter(parameters, CHECK_OK_CUSTOM(Void)); 3605 3606 if (parameters->has_rest) { 3607 parameters->is_simple = false; 3608 classifier()->RecordNonSimpleParameter(); 3609 if (peek() == Token::COMMA) { 3610 impl()->ReportMessageAt(scanner()->peek_location(), 3611 MessageTemplate::kParamAfterRest); 3612 *ok = false; 3613 return; 3614 } 3615 break; 3616 } 3617 if (!Check(Token::COMMA)) break; 3618 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) { 3619 // allow the trailing comma 3620 break; 3621 } 3622 } 3623 } 3624 3625 impl()->DeclareFormalParameters(parameters->scope, parameters->params); 3626 } 3627 3628 template <typename Impl> 3629 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseVariableDeclarations( 3630 VariableDeclarationContext var_context, 3631 DeclarationParsingResult* parsing_result, 3632 ZoneList<const AstRawString*>* names, bool* ok) { 3633 // VariableDeclarations :: 3634 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] 3635 // 3636 // ES6: 3637 // FIXME(marja, nikolaos): Add an up-to-date comment about ES6 variable 3638 // declaration syntax. 3639 3640 DCHECK_NOT_NULL(parsing_result); 3641 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL; 3642 parsing_result->descriptor.declaration_pos = peek_position(); 3643 parsing_result->descriptor.initialization_pos = peek_position(); 3644 3645 BlockT init_block = impl()->NullBlock(); 3646 if (var_context != kForStatement) { 3647 init_block = factory()->NewBlock( 3648 nullptr, 1, true, parsing_result->descriptor.declaration_pos); 3649 } 3650 3651 switch (peek()) { 3652 case Token::VAR: 3653 parsing_result->descriptor.mode = VAR; 3654 Consume(Token::VAR); 3655 break; 3656 case Token::CONST: 3657 Consume(Token::CONST); 3658 DCHECK(var_context != kStatement); 3659 parsing_result->descriptor.mode = CONST; 3660 break; 3661 case Token::LET: 3662 Consume(Token::LET); 3663 DCHECK(var_context != kStatement); 3664 parsing_result->descriptor.mode = LET; 3665 break; 3666 default: 3667 UNREACHABLE(); // by current callers 3668 break; 3669 } 3670 3671 parsing_result->descriptor.scope = scope(); 3672 3673 int bindings_start = peek_position(); 3674 do { 3675 // Parse binding pattern. 3676 FuncNameInferrer::State fni_state(fni_); 3677 3678 ExpressionT pattern = impl()->EmptyExpression(); 3679 int decl_pos = peek_position(); 3680 { 3681 ExpressionClassifier pattern_classifier(this); 3682 pattern = ParsePrimaryExpression(CHECK_OK_CUSTOM(NullBlock)); 3683 3684 ValidateBindingPattern(CHECK_OK_CUSTOM(NullBlock)); 3685 if (IsLexicalVariableMode(parsing_result->descriptor.mode)) { 3686 ValidateLetPattern(CHECK_OK_CUSTOM(NullBlock)); 3687 } 3688 } 3689 3690 Scanner::Location variable_loc = scanner()->location(); 3691 bool single_name = impl()->IsIdentifier(pattern); 3692 3693 if (single_name) { 3694 impl()->PushVariableName(impl()->AsIdentifier(pattern)); 3695 } 3696 3697 ExpressionT value = impl()->EmptyExpression(); 3698 int initializer_position = kNoSourcePosition; 3699 if (Check(Token::ASSIGN)) { 3700 ExpressionClassifier classifier(this); 3701 value = ParseAssignmentExpression(var_context != kForStatement, 3702 CHECK_OK_CUSTOM(NullBlock)); 3703 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullBlock)); 3704 variable_loc.end_pos = scanner()->location().end_pos; 3705 3706 if (!parsing_result->first_initializer_loc.IsValid()) { 3707 parsing_result->first_initializer_loc = variable_loc; 3708 } 3709 3710 // Don't infer if it is "a = function(){...}();"-like expression. 3711 if (single_name && fni_ != nullptr) { 3712 if (!value->IsCall() && !value->IsCallNew()) { 3713 fni_->Infer(); 3714 } else { 3715 fni_->RemoveLastFunction(); 3716 } 3717 } 3718 3719 impl()->SetFunctionNameFromIdentifierRef(value, pattern); 3720 3721 // End position of the initializer is after the assignment expression. 3722 initializer_position = scanner()->location().end_pos; 3723 } else { 3724 if (var_context != kForStatement || !PeekInOrOf()) { 3725 // ES6 'const' and binding patterns require initializers. 3726 if (parsing_result->descriptor.mode == CONST || 3727 !impl()->IsIdentifier(pattern)) { 3728 impl()->ReportMessageAt( 3729 Scanner::Location(decl_pos, scanner()->location().end_pos), 3730 MessageTemplate::kDeclarationMissingInitializer, 3731 !impl()->IsIdentifier(pattern) ? "destructuring" : "const"); 3732 *ok = false; 3733 return impl()->NullBlock(); 3734 } 3735 // 'let x' initializes 'x' to undefined. 3736 if (parsing_result->descriptor.mode == LET) { 3737 value = impl()->GetLiteralUndefined(position()); 3738 } 3739 } 3740 3741 // End position of the initializer is after the variable. 3742 initializer_position = position(); 3743 } 3744 3745 typename DeclarationParsingResult::Declaration decl( 3746 pattern, initializer_position, value); 3747 if (var_context == kForStatement) { 3748 // Save the declaration for further handling in ParseForStatement. 3749 parsing_result->declarations.Add(decl); 3750 } else { 3751 // Immediately declare the variable otherwise. This avoids O(N^2) 3752 // behavior (where N is the number of variables in a single 3753 // declaration) in the PatternRewriter having to do with removing 3754 // and adding VariableProxies to the Scope (see bug 4699). 3755 impl()->DeclareAndInitializeVariables(init_block, 3756 &parsing_result->descriptor, &decl, 3757 names, CHECK_OK_CUSTOM(NullBlock)); 3758 } 3759 } while (Check(Token::COMMA)); 3760 3761 parsing_result->bindings_loc = 3762 Scanner::Location(bindings_start, scanner()->location().end_pos); 3763 3764 DCHECK(*ok); 3765 return init_block; 3766 } 3767 3768 template <typename Impl> 3769 typename ParserBase<Impl>::StatementT 3770 ParserBase<Impl>::ParseFunctionDeclaration(bool* ok) { 3771 Consume(Token::FUNCTION); 3772 int pos = position(); 3773 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; 3774 if (Check(Token::MUL)) { 3775 impl()->ReportMessageAt(scanner()->location(), 3776 MessageTemplate::kGeneratorInLegacyContext); 3777 *ok = false; 3778 return impl()->NullStatement(); 3779 } 3780 return ParseHoistableDeclaration(pos, flags, nullptr, false, ok); 3781 } 3782 3783 template <typename Impl> 3784 typename ParserBase<Impl>::StatementT 3785 ParserBase<Impl>::ParseHoistableDeclaration( 3786 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { 3787 Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement)); 3788 int pos = position(); 3789 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; 3790 if (Check(Token::MUL)) { 3791 flags |= ParseFunctionFlags::kIsGenerator; 3792 } 3793 return ParseHoistableDeclaration(pos, flags, names, default_export, ok); 3794 } 3795 3796 template <typename Impl> 3797 typename ParserBase<Impl>::StatementT 3798 ParserBase<Impl>::ParseHoistableDeclaration( 3799 int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names, 3800 bool default_export, bool* ok) { 3801 // FunctionDeclaration :: 3802 // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}' 3803 // 'function' '(' FormalParameters ')' '{' FunctionBody '}' 3804 // GeneratorDeclaration :: 3805 // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}' 3806 // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}' 3807 // 3808 // The anonymous forms are allowed iff [default_export] is true. 3809 // 3810 // 'function' and '*' (if present) have been consumed by the caller. 3811 3812 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator; 3813 const bool is_async = flags & ParseFunctionFlags::kIsAsync; 3814 DCHECK(!is_generator || !is_async); 3815 3816 IdentifierT name; 3817 FunctionNameValidity name_validity; 3818 IdentifierT variable_name; 3819 if (default_export && peek() == Token::LPAREN) { 3820 impl()->GetDefaultStrings(&name, &variable_name); 3821 name_validity = kSkipFunctionNameCheck; 3822 } else { 3823 bool is_strict_reserved; 3824 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, 3825 CHECK_OK_CUSTOM(NullStatement)); 3826 name_validity = is_strict_reserved ? kFunctionNameIsStrictReserved 3827 : kFunctionNameValidityUnknown; 3828 variable_name = name; 3829 } 3830 3831 FuncNameInferrer::State fni_state(fni_); 3832 impl()->PushEnclosingName(name); 3833 FunctionLiteralT function = impl()->ParseFunctionLiteral( 3834 name, scanner()->location(), name_validity, 3835 is_generator ? FunctionKind::kGeneratorFunction 3836 : is_async ? FunctionKind::kAsyncFunction 3837 : FunctionKind::kNormalFunction, 3838 pos, FunctionLiteral::kDeclaration, language_mode(), 3839 CHECK_OK_CUSTOM(NullStatement)); 3840 3841 // In ES6, a function behaves as a lexical binding, except in 3842 // a script scope, or the initial scope of eval or another function. 3843 VariableMode mode = 3844 (!scope()->is_declaration_scope() || scope()->is_module_scope()) ? LET 3845 : VAR; 3846 // Async functions don't undergo sloppy mode block scoped hoisting, and don't 3847 // allow duplicates in a block. Both are represented by the 3848 // sloppy_block_function_map. Don't add them to the map for async functions. 3849 // Generators are also supposed to be prohibited; currently doing this behind 3850 // a flag and UseCounting violations to assess web compatibility. 3851 bool is_sloppy_block_function = 3852 is_sloppy(language_mode()) && !scope()->is_declaration_scope() && 3853 !is_async && !(allow_harmony_restrictive_generators() && is_generator); 3854 3855 return impl()->DeclareFunction(variable_name, function, mode, pos, 3856 is_sloppy_block_function, names, ok); 3857 } 3858 3859 template <typename Impl> 3860 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseClassDeclaration( 3861 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { 3862 // ClassDeclaration :: 3863 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' 3864 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}' 3865 // 3866 // The anonymous form is allowed iff [default_export] is true. 3867 // 3868 // 'class' is expected to be consumed by the caller. 3869 // 3870 // A ClassDeclaration 3871 // 3872 // class C { ... } 3873 // 3874 // has the same semantics as: 3875 // 3876 // let C = class C { ... }; 3877 // 3878 // so rewrite it as such. 3879 3880 int class_token_pos = position(); 3881 IdentifierT name = impl()->EmptyIdentifier(); 3882 bool is_strict_reserved = false; 3883 IdentifierT variable_name = impl()->EmptyIdentifier(); 3884 if (default_export && (peek() == Token::EXTENDS || peek() == Token::LBRACE)) { 3885 impl()->GetDefaultStrings(&name, &variable_name); 3886 } else { 3887 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, 3888 CHECK_OK_CUSTOM(NullStatement)); 3889 variable_name = name; 3890 } 3891 3892 ExpressionClassifier no_classifier(this); 3893 ExpressionT value = 3894 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, 3895 class_token_pos, CHECK_OK_CUSTOM(NullStatement)); 3896 int end_pos = position(); 3897 return impl()->DeclareClass(variable_name, value, names, class_token_pos, 3898 end_pos, ok); 3899 } 3900 3901 // Language extension which is only enabled for source files loaded 3902 // through the API's extension mechanism. A native function 3903 // declaration is resolved by looking up the function through a 3904 // callback provided by the extension. 3905 template <typename Impl> 3906 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseNativeDeclaration( 3907 bool* ok) { 3908 int pos = peek_position(); 3909 Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement)); 3910 // Allow "eval" or "arguments" for backward compatibility. 3911 IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers, 3912 CHECK_OK_CUSTOM(NullStatement)); 3913 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullStatement)); 3914 if (peek() != Token::RPAREN) { 3915 do { 3916 ParseIdentifier(kAllowRestrictedIdentifiers, 3917 CHECK_OK_CUSTOM(NullStatement)); 3918 } while (Check(Token::COMMA)); 3919 } 3920 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullStatement)); 3921 Expect(Token::SEMICOLON, CHECK_OK_CUSTOM(NullStatement)); 3922 return impl()->DeclareNative(name, pos, ok); 3923 } 3924 3925 template <typename Impl> 3926 typename ParserBase<Impl>::StatementT 3927 ParserBase<Impl>::ParseAsyncFunctionDeclaration( 3928 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { 3929 // AsyncFunctionDeclaration :: 3930 // async [no LineTerminator here] function BindingIdentifier[Await] 3931 // ( FormalParameters[Await] ) { AsyncFunctionBody } 3932 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); 3933 int pos = position(); 3934 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 3935 *ok = false; 3936 impl()->ReportUnexpectedToken(scanner()->current_token()); 3937 return impl()->NullStatement(); 3938 } 3939 Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement)); 3940 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; 3941 return ParseHoistableDeclaration(pos, flags, names, default_export, ok); 3942 } 3943 3944 template <typename Impl> 3945 void ParserBase<Impl>::ParseFunctionBody( 3946 typename ParserBase<Impl>::StatementListT result, IdentifierT function_name, 3947 int pos, const FormalParametersT& parameters, FunctionKind kind, 3948 FunctionLiteral::FunctionType function_type, bool* ok) { 3949 static const int kFunctionNameAssignmentIndex = 0; 3950 if (function_type == FunctionLiteral::kNamedExpression) { 3951 DCHECK(!impl()->IsEmptyIdentifier(function_name)); 3952 // If we have a named function expression, we add a local variable 3953 // declaration to the body of the function with the name of the 3954 // function and let it refer to the function itself (closure). 3955 // Not having parsed the function body, the language mode may still change, 3956 // so we reserve a spot and create the actual const assignment later. 3957 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length()); 3958 result->Add(impl()->NullStatement(), zone()); 3959 } 3960 3961 DeclarationScope* function_scope = scope()->AsDeclarationScope(); 3962 DeclarationScope* inner_scope = function_scope; 3963 BlockT inner_block = impl()->NullBlock(); 3964 3965 StatementListT body = result; 3966 if (!parameters.is_simple) { 3967 inner_scope = NewVarblockScope(); 3968 inner_scope->set_start_position(scanner()->location().beg_pos); 3969 inner_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); 3970 inner_block->set_scope(inner_scope); 3971 body = inner_block->statements(); 3972 } 3973 3974 { 3975 BlockState block_state(&scope_, inner_scope); 3976 3977 if (IsGeneratorFunction(kind)) { 3978 impl()->ParseAndRewriteGeneratorFunctionBody(pos, kind, body, ok); 3979 } else if (IsAsyncFunction(kind)) { 3980 const bool accept_IN = true; 3981 ParseAsyncFunctionBody(inner_scope, body, kind, FunctionBodyType::kNormal, 3982 accept_IN, pos, CHECK_OK_VOID); 3983 } else { 3984 ParseStatementList(body, Token::RBRACE, CHECK_OK_VOID); 3985 } 3986 3987 if (IsDerivedConstructor(kind)) { 3988 body->Add(factory()->NewReturnStatement(impl()->ThisExpression(), 3989 kNoSourcePosition), 3990 zone()); 3991 } 3992 } 3993 3994 Expect(Token::RBRACE, CHECK_OK_VOID); 3995 scope()->set_end_position(scanner()->location().end_pos); 3996 3997 if (!parameters.is_simple) { 3998 DCHECK_NOT_NULL(inner_scope); 3999 DCHECK_EQ(function_scope, scope()); 4000 DCHECK_EQ(function_scope, inner_scope->outer_scope()); 4001 impl()->SetLanguageMode(function_scope, inner_scope->language_mode()); 4002 BlockT init_block = 4003 impl()->BuildParameterInitializationBlock(parameters, CHECK_OK_VOID); 4004 4005 if (is_sloppy(inner_scope->language_mode())) { 4006 impl()->InsertSloppyBlockFunctionVarBindings(inner_scope); 4007 } 4008 4009 // TODO(littledan): Merge the two rejection blocks into one 4010 if (IsAsyncFunction(kind)) { 4011 init_block = impl()->BuildRejectPromiseOnException(init_block); 4012 } 4013 4014 inner_scope->set_end_position(scanner()->location().end_pos); 4015 if (inner_scope->FinalizeBlockScope() != nullptr) { 4016 impl()->CheckConflictingVarDeclarations(inner_scope, CHECK_OK_VOID); 4017 impl()->InsertShadowingVarBindingInitializers(inner_block); 4018 } else { 4019 inner_block->set_scope(nullptr); 4020 } 4021 inner_scope = nullptr; 4022 4023 result->Add(init_block, zone()); 4024 result->Add(inner_block, zone()); 4025 } else { 4026 DCHECK_EQ(inner_scope, function_scope); 4027 if (is_sloppy(function_scope->language_mode())) { 4028 impl()->InsertSloppyBlockFunctionVarBindings(function_scope); 4029 } 4030 } 4031 4032 if (!IsArrowFunction(kind)) { 4033 // Declare arguments after parsing the function since lexical 'arguments' 4034 // masks the arguments object. Declare arguments before declaring the 4035 // function var since the arguments object masks 'function arguments'. 4036 function_scope->DeclareArguments(ast_value_factory()); 4037 } 4038 4039 impl()->CreateFunctionNameAssignment(function_name, pos, function_type, 4040 function_scope, result, 4041 kFunctionNameAssignmentIndex); 4042 impl()->MarkCollectedTailCallExpressions(); 4043 } 4044 4045 template <typename Impl> 4046 void ParserBase<Impl>::CheckArityRestrictions(int param_count, 4047 FunctionKind function_kind, 4048 bool has_rest, 4049 int formals_start_pos, 4050 int formals_end_pos, bool* ok) { 4051 if (IsGetterFunction(function_kind)) { 4052 if (param_count != 0) { 4053 impl()->ReportMessageAt( 4054 Scanner::Location(formals_start_pos, formals_end_pos), 4055 MessageTemplate::kBadGetterArity); 4056 *ok = false; 4057 } 4058 } else if (IsSetterFunction(function_kind)) { 4059 if (param_count != 1) { 4060 impl()->ReportMessageAt( 4061 Scanner::Location(formals_start_pos, formals_end_pos), 4062 MessageTemplate::kBadSetterArity); 4063 *ok = false; 4064 } 4065 if (has_rest) { 4066 impl()->ReportMessageAt( 4067 Scanner::Location(formals_start_pos, formals_end_pos), 4068 MessageTemplate::kBadSetterRestParameter); 4069 *ok = false; 4070 } 4071 } 4072 } 4073 4074 template <typename Impl> 4075 bool ParserBase<Impl>::IsNextLetKeyword() { 4076 DCHECK(peek() == Token::LET); 4077 Token::Value next_next = PeekAhead(); 4078 switch (next_next) { 4079 case Token::LBRACE: 4080 case Token::LBRACK: 4081 case Token::IDENTIFIER: 4082 case Token::STATIC: 4083 case Token::LET: // `let let;` is disallowed by static semantics, but the 4084 // token must be first interpreted as a keyword in order 4085 // for those semantics to apply. This ensures that ASI is 4086 // not honored when a LineTerminator separates the 4087 // tokens. 4088 case Token::YIELD: 4089 case Token::AWAIT: 4090 case Token::ASYNC: 4091 return true; 4092 case Token::FUTURE_STRICT_RESERVED_WORD: 4093 return is_sloppy(language_mode()); 4094 default: 4095 return false; 4096 } 4097 } 4098 4099 template <typename Impl> 4100 bool ParserBase<Impl>::IsTrivialExpression() { 4101 Token::Value peek_token = peek(); 4102 if (peek_token == Token::SMI || peek_token == Token::NUMBER || 4103 peek_token == Token::NULL_LITERAL || peek_token == Token::TRUE_LITERAL || 4104 peek_token == Token::FALSE_LITERAL || peek_token == Token::STRING || 4105 peek_token == Token::IDENTIFIER || peek_token == Token::THIS) { 4106 // PeekAhead() is expensive & may not always be called, so we only call it 4107 // after checking peek(). 4108 Token::Value peek_ahead = PeekAhead(); 4109 if (peek_ahead == Token::COMMA || peek_ahead == Token::RPAREN || 4110 peek_ahead == Token::SEMICOLON || peek_ahead == Token::RBRACK) { 4111 return true; 4112 } 4113 } 4114 return false; 4115 } 4116 4117 template <typename Impl> 4118 typename ParserBase<Impl>::ExpressionT 4119 ParserBase<Impl>::ParseArrowFunctionLiteral( 4120 bool accept_IN, const FormalParametersT& formal_parameters, 4121 int rewritable_length, bool* ok) { 4122 const RuntimeCallStats::CounterId counters[2][2] = { 4123 {&RuntimeCallStats::ParseBackgroundArrowFunctionLiteral, 4124 &RuntimeCallStats::ParseArrowFunctionLiteral}, 4125 {&RuntimeCallStats::PreParseBackgroundArrowFunctionLiteral, 4126 &RuntimeCallStats::PreParseArrowFunctionLiteral}}; 4127 RuntimeCallTimerScope runtime_timer( 4128 runtime_call_stats_, 4129 counters[Impl::IsPreParser()][parsing_on_main_thread_]); 4130 4131 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { 4132 // ASI inserts `;` after arrow parameters if a line terminator is found. 4133 // `=> ...` is never a valid expression, so report as syntax error. 4134 // If next token is not `=>`, it's a syntax error anyways. 4135 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); 4136 *ok = false; 4137 return impl()->EmptyExpression(); 4138 } 4139 4140 StatementListT body = impl()->NullStatementList(); 4141 int expected_property_count = -1; 4142 int function_literal_id = GetNextFunctionLiteralId(); 4143 4144 FunctionKind kind = formal_parameters.scope->function_kind(); 4145 FunctionLiteral::EagerCompileHint eager_compile_hint = 4146 default_eager_compile_hint_; 4147 bool can_preparse = impl()->parse_lazily() && 4148 eager_compile_hint == FunctionLiteral::kShouldLazyCompile; 4149 // TODO(marja): consider lazy-parsing inner arrow functions too. is_this 4150 // handling in Scope::ResolveVariable needs to change. 4151 bool is_lazy_top_level_function = 4152 can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables(); 4153 bool should_be_used_once_hint = false; 4154 bool has_braces = true; 4155 { 4156 FunctionState function_state(&function_state_, &scope_, 4157 formal_parameters.scope); 4158 4159 Expect(Token::ARROW, CHECK_OK); 4160 4161 if (peek() == Token::LBRACE) { 4162 // Multiple statement body 4163 DCHECK_EQ(scope(), formal_parameters.scope); 4164 if (is_lazy_top_level_function) { 4165 // FIXME(marja): Arrow function parameters will be parsed even if the 4166 // body is preparsed; move relevant parts of parameter handling to 4167 // simulate consistent parameter handling. 4168 Scanner::BookmarkScope bookmark(scanner()); 4169 bookmark.Set(); 4170 // For arrow functions, we don't need to retrieve data about function 4171 // parameters. 4172 int dummy_num_parameters = -1; 4173 int dummy_function_length = -1; 4174 bool dummy_has_duplicate_parameters = false; 4175 DCHECK((kind & FunctionKind::kArrowFunction) != 0); 4176 LazyParsingResult result = impl()->SkipFunction( 4177 kind, formal_parameters.scope, &dummy_num_parameters, 4178 &dummy_function_length, &dummy_has_duplicate_parameters, 4179 &expected_property_count, false, true, CHECK_OK); 4180 formal_parameters.scope->ResetAfterPreparsing( 4181 ast_value_factory_, result == kLazyParsingAborted); 4182 4183 if (result == kLazyParsingAborted) { 4184 bookmark.Apply(); 4185 // Trigger eager (re-)parsing, just below this block. 4186 is_lazy_top_level_function = false; 4187 4188 // This is probably an initialization function. Inform the compiler it 4189 // should also eager-compile this function, and that we expect it to 4190 // be used once. 4191 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 4192 should_be_used_once_hint = true; 4193 } 4194 } 4195 if (!is_lazy_top_level_function) { 4196 Consume(Token::LBRACE); 4197 body = impl()->NewStatementList(8); 4198 impl()->ParseFunctionBody(body, impl()->EmptyIdentifier(), 4199 kNoSourcePosition, formal_parameters, kind, 4200 FunctionLiteral::kAnonymousExpression, 4201 CHECK_OK); 4202 expected_property_count = function_state.expected_property_count(); 4203 } 4204 } else { 4205 // Single-expression body 4206 has_braces = false; 4207 int pos = position(); 4208 DCHECK(ReturnExprContext::kInsideValidBlock == 4209 function_state_->return_expr_context()); 4210 ReturnExprScope allow_tail_calls( 4211 function_state_, ReturnExprContext::kInsideValidReturnStatement); 4212 body = impl()->NewStatementList(1); 4213 impl()->AddParameterInitializationBlock( 4214 formal_parameters, body, kind == kAsyncArrowFunction, CHECK_OK); 4215 ExpressionClassifier classifier(this); 4216 if (kind == kAsyncArrowFunction) { 4217 ParseAsyncFunctionBody(scope(), body, kAsyncArrowFunction, 4218 FunctionBodyType::kSingleExpression, accept_IN, 4219 pos, CHECK_OK); 4220 impl()->RewriteNonPattern(CHECK_OK); 4221 } else { 4222 ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK); 4223 impl()->RewriteNonPattern(CHECK_OK); 4224 body->Add(BuildReturnStatement(expression, expression->position()), 4225 zone()); 4226 if (allow_tailcalls() && !is_sloppy(language_mode())) { 4227 // ES6 14.6.1 Static Semantics: IsInTailPosition 4228 impl()->MarkTailPosition(expression); 4229 } 4230 } 4231 expected_property_count = function_state.expected_property_count(); 4232 impl()->MarkCollectedTailCallExpressions(); 4233 } 4234 4235 formal_parameters.scope->set_end_position(scanner()->location().end_pos); 4236 4237 // Arrow function formal parameters are parsed as StrictFormalParameterList, 4238 // which is not the same as "parameters of a strict function"; it only means 4239 // that duplicates are not allowed. Of course, the arrow function may 4240 // itself be strict as well. 4241 const bool allow_duplicate_parameters = false; 4242 ValidateFormalParameters(language_mode(), allow_duplicate_parameters, 4243 CHECK_OK); 4244 4245 // Validate strict mode. 4246 if (is_strict(language_mode())) { 4247 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), 4248 scanner()->location().end_pos, CHECK_OK); 4249 } 4250 impl()->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); 4251 4252 if (is_lazy_top_level_function) { 4253 FunctionState* parent_state = function_state.outer(); 4254 DCHECK_NOT_NULL(parent_state); 4255 DCHECK_GE(parent_state->destructuring_assignments_to_rewrite().length(), 4256 rewritable_length); 4257 parent_state->RewindDestructuringAssignments(rewritable_length); 4258 } 4259 4260 impl()->RewriteDestructuringAssignments(); 4261 } 4262 4263 if (FLAG_trace_preparse) { 4264 Scope* scope = formal_parameters.scope; 4265 PrintF(" [%s]: %i-%i (arrow function)\n", 4266 is_lazy_top_level_function ? "Preparse no-resolution" : "Full parse", 4267 scope->start_position(), scope->end_position()); 4268 } 4269 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( 4270 impl()->EmptyIdentifierString(), formal_parameters.scope, body, 4271 expected_property_count, formal_parameters.num_parameters(), 4272 formal_parameters.function_length, 4273 FunctionLiteral::kNoDuplicateParameters, 4274 FunctionLiteral::kAnonymousExpression, eager_compile_hint, 4275 formal_parameters.scope->start_position(), has_braces, 4276 function_literal_id); 4277 4278 function_literal->set_function_token_position( 4279 formal_parameters.scope->start_position()); 4280 if (should_be_used_once_hint) { 4281 function_literal->set_should_be_used_once_hint(); 4282 } 4283 4284 impl()->AddFunctionForNameInference(function_literal); 4285 4286 return function_literal; 4287 } 4288 4289 template <typename Impl> 4290 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral( 4291 IdentifierT name, Scanner::Location class_name_location, 4292 bool name_is_strict_reserved, int class_token_pos, bool* ok) { 4293 // All parts of a ClassDeclaration and ClassExpression are strict code. 4294 if (name_is_strict_reserved) { 4295 impl()->ReportMessageAt(class_name_location, 4296 MessageTemplate::kUnexpectedStrictReserved); 4297 *ok = false; 4298 return impl()->EmptyExpression(); 4299 } 4300 if (impl()->IsEvalOrArguments(name)) { 4301 impl()->ReportMessageAt(class_name_location, 4302 MessageTemplate::kStrictEvalArguments); 4303 *ok = false; 4304 return impl()->EmptyExpression(); 4305 } 4306 4307 BlockState block_state(zone(), &scope_); 4308 RaiseLanguageMode(STRICT); 4309 4310 ClassInfo class_info(this); 4311 impl()->DeclareClassVariable(name, &class_info, class_token_pos, CHECK_OK); 4312 4313 scope()->set_start_position(scanner()->location().end_pos); 4314 if (Check(Token::EXTENDS)) { 4315 ExpressionClassifier extends_classifier(this); 4316 class_info.extends = ParseLeftHandSideExpression(CHECK_OK); 4317 impl()->RewriteNonPattern(CHECK_OK); 4318 impl()->AccumulateFormalParameterContainmentErrors(); 4319 } 4320 4321 ClassLiteralChecker checker(this); 4322 4323 Expect(Token::LBRACE, CHECK_OK); 4324 4325 const bool has_extends = !impl()->IsEmptyExpression(class_info.extends); 4326 while (peek() != Token::RBRACE) { 4327 if (Check(Token::SEMICOLON)) continue; 4328 FuncNameInferrer::State fni_state(fni_); 4329 bool is_computed_name = false; // Classes do not care about computed 4330 // property names here. 4331 bool is_static; 4332 ClassLiteralProperty::Kind property_kind; 4333 ExpressionClassifier property_classifier(this); 4334 // If we haven't seen the constructor yet, it potentially is the next 4335 // property. 4336 bool is_constructor = !class_info.has_seen_constructor; 4337 ClassLiteralPropertyT property = ParseClassPropertyDefinition( 4338 &checker, has_extends, &is_computed_name, 4339 &class_info.has_seen_constructor, &property_kind, &is_static, 4340 &class_info.has_name_static_property, CHECK_OK); 4341 if (!class_info.has_static_computed_names && is_static && 4342 is_computed_name) { 4343 class_info.has_static_computed_names = true; 4344 } 4345 is_constructor &= class_info.has_seen_constructor; 4346 impl()->RewriteNonPattern(CHECK_OK); 4347 impl()->AccumulateFormalParameterContainmentErrors(); 4348 4349 impl()->DeclareClassProperty(name, property, property_kind, is_static, 4350 is_constructor, &class_info, CHECK_OK); 4351 impl()->InferFunctionName(); 4352 } 4353 4354 Expect(Token::RBRACE, CHECK_OK); 4355 return impl()->RewriteClassLiteral(name, &class_info, class_token_pos, ok); 4356 } 4357 4358 template <typename Impl> 4359 void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope, StatementListT body, 4360 FunctionKind kind, 4361 FunctionBodyType body_type, 4362 bool accept_IN, int pos, 4363 bool* ok) { 4364 impl()->PrepareAsyncFunctionBody(body, kind, pos); 4365 4366 BlockT block = factory()->NewBlock(nullptr, 8, true, kNoSourcePosition); 4367 4368 ExpressionT return_value = impl()->EmptyExpression(); 4369 if (body_type == FunctionBodyType::kNormal) { 4370 ParseStatementList(block->statements(), Token::RBRACE, 4371 CHECK_OK_CUSTOM(Void)); 4372 return_value = factory()->NewUndefinedLiteral(kNoSourcePosition); 4373 } else { 4374 return_value = ParseAssignmentExpression(accept_IN, CHECK_OK_CUSTOM(Void)); 4375 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void)); 4376 } 4377 4378 impl()->RewriteAsyncFunctionBody(body, block, return_value, 4379 CHECK_OK_CUSTOM(Void)); 4380 scope->set_end_position(scanner()->location().end_pos); 4381 } 4382 4383 template <typename Impl> 4384 typename ParserBase<Impl>::ExpressionT 4385 ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) { 4386 // AsyncFunctionLiteral :: 4387 // async [no LineTerminator here] function ( FormalParameters[Await] ) 4388 // { AsyncFunctionBody } 4389 // 4390 // async [no LineTerminator here] function BindingIdentifier[Await] 4391 // ( FormalParameters[Await] ) { AsyncFunctionBody } 4392 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); 4393 int pos = position(); 4394 Expect(Token::FUNCTION, CHECK_OK); 4395 bool is_strict_reserved = false; 4396 IdentifierT name = impl()->EmptyIdentifier(); 4397 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression; 4398 4399 if (impl()->ParsingDynamicFunctionDeclaration()) { 4400 // We don't want dynamic functions to actually declare their name 4401 // "anonymous". We just want that name in the toString(). 4402 Consume(Token::IDENTIFIER); 4403 DCHECK(scanner()->UnescapedLiteralMatches("anonymous", 9)); 4404 } else if (peek_any_identifier()) { 4405 type = FunctionLiteral::kNamedExpression; 4406 name = ParseIdentifierOrStrictReservedWord(FunctionKind::kAsyncFunction, 4407 &is_strict_reserved, CHECK_OK); 4408 } 4409 return impl()->ParseFunctionLiteral( 4410 name, scanner()->location(), 4411 is_strict_reserved ? kFunctionNameIsStrictReserved 4412 : kFunctionNameValidityUnknown, 4413 FunctionKind::kAsyncFunction, pos, type, language_mode(), CHECK_OK); 4414 } 4415 4416 template <typename Impl> 4417 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseTemplateLiteral( 4418 ExpressionT tag, int start, bool tagged, bool* ok) { 4419 // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal 4420 // text followed by a substitution expression), finalized by a single 4421 // TEMPLATE_TAIL. 4422 // 4423 // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or 4424 // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or 4425 // NoSubstitutionTemplate. 4426 // 4427 // When parsing a TemplateLiteral, we must have scanned either an initial 4428 // TEMPLATE_SPAN, or a TEMPLATE_TAIL. 4429 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL); 4430 4431 bool forbid_illegal_escapes = !allow_harmony_template_escapes() || !tagged; 4432 4433 // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate. 4434 // In this case we may simply consume the token and build a template with a 4435 // single TEMPLATE_SPAN and no expressions. 4436 if (peek() == Token::TEMPLATE_TAIL) { 4437 Consume(Token::TEMPLATE_TAIL); 4438 int pos = position(); 4439 typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos); 4440 bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK); 4441 impl()->AddTemplateSpan(&ts, is_valid, true); 4442 return impl()->CloseTemplateLiteral(&ts, start, tag); 4443 } 4444 4445 Consume(Token::TEMPLATE_SPAN); 4446 int pos = position(); 4447 typename Impl::TemplateLiteralState ts = impl()->OpenTemplateLiteral(pos); 4448 bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK); 4449 impl()->AddTemplateSpan(&ts, is_valid, false); 4450 Token::Value next; 4451 4452 // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression, 4453 // and repeat if the following token is a TEMPLATE_SPAN as well (in this 4454 // case, representing a TemplateMiddle). 4455 4456 do { 4457 next = peek(); 4458 if (next == Token::EOS) { 4459 impl()->ReportMessageAt(Scanner::Location(start, peek_position()), 4460 MessageTemplate::kUnterminatedTemplate); 4461 *ok = false; 4462 return impl()->EmptyExpression(); 4463 } else if (next == Token::ILLEGAL) { 4464 impl()->ReportMessageAt( 4465 Scanner::Location(position() + 1, peek_position()), 4466 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); 4467 *ok = false; 4468 return impl()->EmptyExpression(); 4469 } 4470 4471 int expr_pos = peek_position(); 4472 ExpressionT expression = ParseExpressionCoverGrammar(true, CHECK_OK); 4473 impl()->RewriteNonPattern(CHECK_OK); 4474 impl()->AddTemplateExpression(&ts, expression); 4475 4476 if (peek() != Token::RBRACE) { 4477 impl()->ReportMessageAt(Scanner::Location(expr_pos, peek_position()), 4478 MessageTemplate::kUnterminatedTemplateExpr); 4479 *ok = false; 4480 return impl()->EmptyExpression(); 4481 } 4482 4483 // If we didn't die parsing that expression, our next token should be a 4484 // TEMPLATE_SPAN or TEMPLATE_TAIL. 4485 next = scanner()->ScanTemplateContinuation(); 4486 Next(); 4487 pos = position(); 4488 4489 if (next == Token::EOS) { 4490 impl()->ReportMessageAt(Scanner::Location(start, pos), 4491 MessageTemplate::kUnterminatedTemplate); 4492 *ok = false; 4493 return impl()->EmptyExpression(); 4494 } else if (next == Token::ILLEGAL) { 4495 impl()->ReportMessageAt( 4496 Scanner::Location(position() + 1, peek_position()), 4497 MessageTemplate::kUnexpectedToken, "ILLEGAL", kSyntaxError); 4498 *ok = false; 4499 return impl()->EmptyExpression(); 4500 } 4501 4502 bool is_valid = CheckTemplateEscapes(forbid_illegal_escapes, CHECK_OK); 4503 impl()->AddTemplateSpan(&ts, is_valid, next == Token::TEMPLATE_TAIL); 4504 } while (next == Token::TEMPLATE_SPAN); 4505 4506 DCHECK_EQ(next, Token::TEMPLATE_TAIL); 4507 // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral. 4508 return impl()->CloseTemplateLiteral(&ts, start, tag); 4509 } 4510 4511 template <typename Impl> 4512 typename ParserBase<Impl>::ExpressionT 4513 ParserBase<Impl>::CheckAndRewriteReferenceExpression( 4514 ExpressionT expression, int beg_pos, int end_pos, 4515 MessageTemplate::Template message, bool* ok) { 4516 return CheckAndRewriteReferenceExpression(expression, beg_pos, end_pos, 4517 message, kReferenceError, ok); 4518 } 4519 4520 template <typename Impl> 4521 typename ParserBase<Impl>::ExpressionT 4522 ParserBase<Impl>::CheckAndRewriteReferenceExpression( 4523 ExpressionT expression, int beg_pos, int end_pos, 4524 MessageTemplate::Template message, ParseErrorType type, bool* ok) { 4525 if (impl()->IsIdentifier(expression) && is_strict(language_mode()) && 4526 impl()->IsEvalOrArguments(impl()->AsIdentifier(expression))) { 4527 ReportMessageAt(Scanner::Location(beg_pos, end_pos), 4528 MessageTemplate::kStrictEvalArguments, kSyntaxError); 4529 *ok = false; 4530 return impl()->EmptyExpression(); 4531 } 4532 if (expression->IsValidReferenceExpression()) { 4533 return expression; 4534 } 4535 if (expression->IsCall()) { 4536 // If it is a call, make it a runtime error for legacy web compatibility. 4537 // Bug: https://bugs.chromium.org/p/v8/issues/detail?id=4480 4538 // Rewrite `expr' to `expr[throw ReferenceError]'. 4539 impl()->CountUsage( 4540 is_strict(language_mode()) 4541 ? v8::Isolate::kAssigmentExpressionLHSIsCallInStrict 4542 : v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy); 4543 ExpressionT error = impl()->NewThrowReferenceError(message, beg_pos); 4544 return factory()->NewProperty(expression, error, beg_pos); 4545 } 4546 ReportMessageAt(Scanner::Location(beg_pos, end_pos), message, type); 4547 *ok = false; 4548 return impl()->EmptyExpression(); 4549 } 4550 4551 template <typename Impl> 4552 bool ParserBase<Impl>::IsValidReferenceExpression(ExpressionT expression) { 4553 return IsAssignableIdentifier(expression) || expression->IsProperty(); 4554 } 4555 4556 template <typename Impl> 4557 void ParserBase<Impl>::CheckDestructuringElement(ExpressionT expression, 4558 int begin, int end) { 4559 if (!IsValidPattern(expression) && !expression->IsAssignment() && 4560 !IsValidReferenceExpression(expression)) { 4561 classifier()->RecordAssignmentPatternError( 4562 Scanner::Location(begin, end), 4563 MessageTemplate::kInvalidDestructuringTarget); 4564 } 4565 } 4566 4567 template <typename Impl> 4568 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseV8Intrinsic( 4569 bool* ok) { 4570 // CallRuntime :: 4571 // '%' Identifier Arguments 4572 4573 int pos = peek_position(); 4574 Expect(Token::MOD, CHECK_OK); 4575 // Allow "eval" or "arguments" for backward compatibility. 4576 IdentifierT name = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 4577 Scanner::Location spread_pos; 4578 ExpressionClassifier classifier(this); 4579 ExpressionListT args = ParseArguments(&spread_pos, CHECK_OK); 4580 4581 DCHECK(!spread_pos.IsValid()); 4582 4583 return impl()->NewV8Intrinsic(name, args, pos, ok); 4584 } 4585 4586 template <typename Impl> 4587 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseDoExpression( 4588 bool* ok) { 4589 // AssignmentExpression :: 4590 // do '{' StatementList '}' 4591 4592 int pos = peek_position(); 4593 Expect(Token::DO, CHECK_OK); 4594 BlockT block = ParseBlock(nullptr, CHECK_OK); 4595 return impl()->RewriteDoExpression(block, pos, ok); 4596 } 4597 4598 // Redefinition of CHECK_OK for parsing statements. 4599 #undef CHECK_OK 4600 #define CHECK_OK CHECK_OK_CUSTOM(NullStatement) 4601 4602 template <typename Impl> 4603 typename ParserBase<Impl>::LazyParsingResult 4604 ParserBase<Impl>::ParseStatementList(StatementListT body, int end_token, 4605 bool may_abort, bool* ok) { 4606 // StatementList :: 4607 // (StatementListItem)* <end_token> 4608 4609 // Allocate a target stack to use for this set of source 4610 // elements. This way, all scripts and functions get their own 4611 // target stack thus avoiding illegal breaks and continues across 4612 // functions. 4613 typename Types::TargetScope target_scope(this); 4614 int count_statements = 0; 4615 4616 DCHECK(!impl()->IsNullStatementList(body)); 4617 bool directive_prologue = true; // Parsing directive prologue. 4618 4619 while (peek() != end_token) { 4620 if (directive_prologue && peek() != Token::STRING) { 4621 directive_prologue = false; 4622 } 4623 4624 bool starts_with_identifier = peek() == Token::IDENTIFIER; 4625 Scanner::Location token_loc = scanner()->peek_location(); 4626 StatementT stat = 4627 ParseStatementListItem(CHECK_OK_CUSTOM(Return, kLazyParsingComplete)); 4628 4629 if (impl()->IsNullStatement(stat) || impl()->IsEmptyStatement(stat)) { 4630 directive_prologue = false; // End of directive prologue. 4631 continue; 4632 } 4633 4634 if (directive_prologue) { 4635 // The length of the token is used to distinguish between strings literals 4636 // that evaluate equal to directives but contain either escape sequences 4637 // (e.g., "use \x73trict") or line continuations (e.g., "use \(newline) 4638 // strict"). 4639 if (impl()->IsUseStrictDirective(stat) && 4640 token_loc.end_pos - token_loc.beg_pos == sizeof("use strict") + 1) { 4641 // Directive "use strict" (ES5 14.1). 4642 RaiseLanguageMode(STRICT); 4643 if (!scope()->HasSimpleParameters()) { 4644 // TC39 deemed "use strict" directives to be an error when occurring 4645 // in the body of a function with non-simple parameter list, on 4646 // 29/7/2015. https://goo.gl/ueA7Ln 4647 impl()->ReportMessageAt( 4648 token_loc, MessageTemplate::kIllegalLanguageModeDirective, 4649 "use strict"); 4650 *ok = false; 4651 return kLazyParsingComplete; 4652 } 4653 } else if (impl()->IsUseAsmDirective(stat) && 4654 token_loc.end_pos - token_loc.beg_pos == 4655 sizeof("use asm") + 1) { 4656 // Directive "use asm". 4657 impl()->SetAsmModule(); 4658 } else if (impl()->IsStringLiteral(stat)) { 4659 // Possibly an unknown directive. 4660 // Should not change mode, but will increment usage counters 4661 // as appropriate. Ditto usages below. 4662 RaiseLanguageMode(SLOPPY); 4663 } else { 4664 // End of the directive prologue. 4665 directive_prologue = false; 4666 RaiseLanguageMode(SLOPPY); 4667 } 4668 } else { 4669 RaiseLanguageMode(SLOPPY); 4670 } 4671 4672 // If we're allowed to abort, we will do so when we see a "long and 4673 // trivial" function. Our current definition of "long and trivial" is: 4674 // - over kLazyParseTrialLimit statements 4675 // - all starting with an identifier (i.e., no if, for, while, etc.) 4676 if (may_abort) { 4677 if (!starts_with_identifier) { 4678 may_abort = false; 4679 } else if (++count_statements > kLazyParseTrialLimit) { 4680 return kLazyParsingAborted; 4681 } 4682 } 4683 4684 body->Add(stat, zone()); 4685 } 4686 return kLazyParsingComplete; 4687 } 4688 4689 template <typename Impl> 4690 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatementListItem( 4691 bool* ok) { 4692 // ECMA 262 6th Edition 4693 // StatementListItem[Yield, Return] : 4694 // Statement[?Yield, ?Return] 4695 // Declaration[?Yield] 4696 // 4697 // Declaration[Yield] : 4698 // HoistableDeclaration[?Yield] 4699 // ClassDeclaration[?Yield] 4700 // LexicalDeclaration[In, ?Yield] 4701 // 4702 // HoistableDeclaration[Yield, Default] : 4703 // FunctionDeclaration[?Yield, ?Default] 4704 // GeneratorDeclaration[?Yield, ?Default] 4705 // 4706 // LexicalDeclaration[In, Yield] : 4707 // LetOrConst BindingList[?In, ?Yield] ; 4708 4709 switch (peek()) { 4710 case Token::FUNCTION: 4711 return ParseHoistableDeclaration(nullptr, false, ok); 4712 case Token::CLASS: 4713 Consume(Token::CLASS); 4714 return ParseClassDeclaration(nullptr, false, ok); 4715 case Token::VAR: 4716 case Token::CONST: 4717 return ParseVariableStatement(kStatementListItem, nullptr, ok); 4718 case Token::LET: 4719 if (IsNextLetKeyword()) { 4720 return ParseVariableStatement(kStatementListItem, nullptr, ok); 4721 } 4722 break; 4723 case Token::ASYNC: 4724 if (PeekAhead() == Token::FUNCTION && 4725 !scanner()->HasAnyLineTerminatorAfterNext()) { 4726 Consume(Token::ASYNC); 4727 return ParseAsyncFunctionDeclaration(nullptr, false, ok); 4728 } 4729 /* falls through */ 4730 default: 4731 break; 4732 } 4733 return ParseStatement(nullptr, kAllowLabelledFunctionStatement, ok); 4734 } 4735 4736 template <typename Impl> 4737 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement( 4738 ZoneList<const AstRawString*>* labels, 4739 AllowLabelledFunctionStatement allow_function, bool* ok) { 4740 // Statement :: 4741 // Block 4742 // VariableStatement 4743 // EmptyStatement 4744 // ExpressionStatement 4745 // IfStatement 4746 // IterationStatement 4747 // ContinueStatement 4748 // BreakStatement 4749 // ReturnStatement 4750 // WithStatement 4751 // LabelledStatement 4752 // SwitchStatement 4753 // ThrowStatement 4754 // TryStatement 4755 // DebuggerStatement 4756 4757 // Note: Since labels can only be used by 'break' and 'continue' 4758 // statements, which themselves are only valid within blocks, 4759 // iterations or 'switch' statements (i.e., BreakableStatements), 4760 // labels can be simply ignored in all other cases; except for 4761 // trivial labeled break statements 'label: break label' which is 4762 // parsed into an empty statement. 4763 switch (peek()) { 4764 case Token::LBRACE: 4765 return ParseBlock(labels, ok); 4766 case Token::SEMICOLON: 4767 Next(); 4768 return factory()->NewEmptyStatement(kNoSourcePosition); 4769 case Token::IF: 4770 return ParseIfStatement(labels, ok); 4771 case Token::DO: 4772 return ParseDoWhileStatement(labels, ok); 4773 case Token::WHILE: 4774 return ParseWhileStatement(labels, ok); 4775 case Token::FOR: 4776 if (V8_UNLIKELY(allow_harmony_async_iteration() && is_async_function() && 4777 PeekAhead() == Token::AWAIT)) { 4778 return ParseForAwaitStatement(labels, ok); 4779 } 4780 return ParseForStatement(labels, ok); 4781 case Token::CONTINUE: 4782 case Token::BREAK: 4783 case Token::RETURN: 4784 case Token::THROW: 4785 case Token::TRY: { 4786 // These statements must have their labels preserved in an enclosing 4787 // block, as the corresponding AST nodes do not currently store their 4788 // labels. 4789 // TODO(nikolaos, marja): Consider adding the labels to the AST nodes. 4790 if (labels == nullptr) { 4791 return ParseStatementAsUnlabelled(labels, ok); 4792 } else { 4793 BlockT result = 4794 factory()->NewBlock(labels, 1, false, kNoSourcePosition); 4795 typename Types::Target target(this, result); 4796 StatementT statement = ParseStatementAsUnlabelled(labels, CHECK_OK); 4797 result->statements()->Add(statement, zone()); 4798 return result; 4799 } 4800 } 4801 case Token::WITH: 4802 return ParseWithStatement(labels, ok); 4803 case Token::SWITCH: 4804 return ParseSwitchStatement(labels, ok); 4805 case Token::FUNCTION: 4806 // FunctionDeclaration only allowed as a StatementListItem, not in 4807 // an arbitrary Statement position. Exceptions such as 4808 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses 4809 // are handled by calling ParseScopedStatement rather than 4810 // ParseStatement directly. 4811 impl()->ReportMessageAt(scanner()->peek_location(), 4812 is_strict(language_mode()) 4813 ? MessageTemplate::kStrictFunction 4814 : MessageTemplate::kSloppyFunction); 4815 *ok = false; 4816 return impl()->NullStatement(); 4817 case Token::DEBUGGER: 4818 return ParseDebuggerStatement(ok); 4819 case Token::VAR: 4820 return ParseVariableStatement(kStatement, nullptr, ok); 4821 default: 4822 return ParseExpressionOrLabelledStatement(labels, allow_function, ok); 4823 } 4824 } 4825 4826 // This method parses a subset of statements (break, continue, return, throw, 4827 // try) which are to be grouped because they all require their labeles to be 4828 // preserved in an enclosing block. 4829 template <typename Impl> 4830 typename ParserBase<Impl>::StatementT 4831 ParserBase<Impl>::ParseStatementAsUnlabelled( 4832 ZoneList<const AstRawString*>* labels, bool* ok) { 4833 switch (peek()) { 4834 case Token::CONTINUE: 4835 return ParseContinueStatement(ok); 4836 case Token::BREAK: 4837 return ParseBreakStatement(labels, ok); 4838 case Token::RETURN: 4839 return ParseReturnStatement(ok); 4840 case Token::THROW: 4841 return ParseThrowStatement(ok); 4842 case Token::TRY: 4843 return ParseTryStatement(ok); 4844 default: 4845 UNREACHABLE(); 4846 return impl()->NullStatement(); 4847 } 4848 } 4849 4850 template <typename Impl> 4851 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseBlock( 4852 ZoneList<const AstRawString*>* labels, bool* ok) { 4853 // Block :: 4854 // '{' StatementList '}' 4855 4856 // Construct block expecting 16 statements. 4857 BlockT body = factory()->NewBlock(labels, 16, false, kNoSourcePosition); 4858 4859 // Parse the statements and collect escaping labels. 4860 Expect(Token::LBRACE, CHECK_OK_CUSTOM(NullBlock)); 4861 { 4862 BlockState block_state(zone(), &scope_); 4863 scope()->set_start_position(scanner()->location().beg_pos); 4864 typename Types::Target target(this, body); 4865 4866 while (peek() != Token::RBRACE) { 4867 StatementT stat = ParseStatementListItem(CHECK_OK_CUSTOM(NullBlock)); 4868 if (!impl()->IsNullStatement(stat) && !impl()->IsEmptyStatement(stat)) { 4869 body->statements()->Add(stat, zone()); 4870 } 4871 } 4872 4873 Expect(Token::RBRACE, CHECK_OK_CUSTOM(NullBlock)); 4874 scope()->set_end_position(scanner()->location().end_pos); 4875 body->set_scope(scope()->FinalizeBlockScope()); 4876 } 4877 return body; 4878 } 4879 4880 template <typename Impl> 4881 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseScopedStatement( 4882 ZoneList<const AstRawString*>* labels, bool* ok) { 4883 if (is_strict(language_mode()) || peek() != Token::FUNCTION) { 4884 return ParseStatement(labels, ok); 4885 } else { 4886 // Make a block around the statement for a lexical binding 4887 // is introduced by a FunctionDeclaration. 4888 BlockState block_state(zone(), &scope_); 4889 scope()->set_start_position(scanner()->location().beg_pos); 4890 BlockT block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); 4891 StatementT body = ParseFunctionDeclaration(CHECK_OK); 4892 block->statements()->Add(body, zone()); 4893 scope()->set_end_position(scanner()->location().end_pos); 4894 block->set_scope(scope()->FinalizeBlockScope()); 4895 return block; 4896 } 4897 } 4898 4899 template <typename Impl> 4900 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseVariableStatement( 4901 VariableDeclarationContext var_context, 4902 ZoneList<const AstRawString*>* names, bool* ok) { 4903 // VariableStatement :: 4904 // VariableDeclarations ';' 4905 4906 // The scope of a var declared variable anywhere inside a function 4907 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 4908 // transform a source-level var declaration into a (Function) Scope 4909 // declaration, and rewrite the source-level initialization into an assignment 4910 // statement. We use a block to collect multiple assignments. 4911 // 4912 // We mark the block as initializer block because we don't want the 4913 // rewriter to add a '.result' assignment to such a block (to get compliant 4914 // behavior for code such as print(eval('var x = 7')), and for cosmetic 4915 // reasons when pretty-printing. Also, unless an assignment (initialization) 4916 // is inside an initializer block, it is ignored. 4917 4918 DeclarationParsingResult parsing_result; 4919 StatementT result = 4920 ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK); 4921 ExpectSemicolon(CHECK_OK); 4922 return result; 4923 } 4924 4925 template <typename Impl> 4926 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDebuggerStatement( 4927 bool* ok) { 4928 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 4929 // contexts this is used as a statement which invokes the debugger as i a 4930 // break point is present. 4931 // DebuggerStatement :: 4932 // 'debugger' ';' 4933 4934 int pos = peek_position(); 4935 Expect(Token::DEBUGGER, CHECK_OK); 4936 ExpectSemicolon(CHECK_OK); 4937 return factory()->NewDebuggerStatement(pos); 4938 } 4939 4940 template <typename Impl> 4941 typename ParserBase<Impl>::StatementT 4942 ParserBase<Impl>::ParseExpressionOrLabelledStatement( 4943 ZoneList<const AstRawString*>* labels, 4944 AllowLabelledFunctionStatement allow_function, bool* ok) { 4945 // ExpressionStatement | LabelledStatement :: 4946 // Expression ';' 4947 // Identifier ':' Statement 4948 // 4949 // ExpressionStatement[Yield] : 4950 // [lookahead notin {{, function, class, let [}] Expression[In, ?Yield] ; 4951 4952 int pos = peek_position(); 4953 4954 switch (peek()) { 4955 case Token::FUNCTION: 4956 case Token::LBRACE: 4957 UNREACHABLE(); // Always handled by the callers. 4958 case Token::CLASS: 4959 ReportUnexpectedToken(Next()); 4960 *ok = false; 4961 return impl()->NullStatement(); 4962 case Token::LET: { 4963 Token::Value next_next = PeekAhead(); 4964 // "let" followed by either "[", "{" or an identifier means a lexical 4965 // declaration, which should not appear here. 4966 if (next_next != Token::LBRACK && next_next != Token::LBRACE && 4967 next_next != Token::IDENTIFIER) { 4968 break; 4969 } 4970 impl()->ReportMessageAt(scanner()->peek_location(), 4971 MessageTemplate::kUnexpectedLexicalDeclaration); 4972 *ok = false; 4973 return impl()->NullStatement(); 4974 } 4975 default: 4976 break; 4977 } 4978 4979 bool starts_with_identifier = peek_any_identifier(); 4980 ExpressionT expr = ParseExpression(true, CHECK_OK); 4981 if (peek() == Token::COLON && starts_with_identifier && 4982 impl()->IsIdentifier(expr)) { 4983 // The whole expression was a single identifier, and not, e.g., 4984 // something starting with an identifier or a parenthesized identifier. 4985 labels = impl()->DeclareLabel(labels, impl()->AsIdentifierExpression(expr), 4986 CHECK_OK); 4987 Consume(Token::COLON); 4988 // ES#sec-labelled-function-declarations Labelled Function Declarations 4989 if (peek() == Token::FUNCTION && is_sloppy(language_mode()) && 4990 allow_function == kAllowLabelledFunctionStatement) { 4991 return ParseFunctionDeclaration(ok); 4992 } 4993 return ParseStatement(labels, ok); 4994 } 4995 4996 // If we have an extension, we allow a native function declaration. 4997 // A native function declaration starts with "native function" with 4998 // no line-terminator between the two words. 4999 if (extension_ != nullptr && peek() == Token::FUNCTION && 5000 !scanner()->HasAnyLineTerminatorBeforeNext() && impl()->IsNative(expr) && 5001 !scanner()->literal_contains_escapes()) { 5002 return ParseNativeDeclaration(ok); 5003 } 5004 5005 // Parsed expression statement, followed by semicolon. 5006 ExpectSemicolon(CHECK_OK); 5007 return factory()->NewExpressionStatement(expr, pos); 5008 } 5009 5010 template <typename Impl> 5011 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseIfStatement( 5012 ZoneList<const AstRawString*>* labels, bool* ok) { 5013 // IfStatement :: 5014 // 'if' '(' Expression ')' Statement ('else' Statement)? 5015 5016 int pos = peek_position(); 5017 Expect(Token::IF, CHECK_OK); 5018 Expect(Token::LPAREN, CHECK_OK); 5019 ExpressionT condition = ParseExpression(true, CHECK_OK); 5020 Expect(Token::RPAREN, CHECK_OK); 5021 StatementT then_statement = ParseScopedStatement(labels, CHECK_OK); 5022 StatementT else_statement = impl()->NullStatement(); 5023 if (Check(Token::ELSE)) { 5024 else_statement = ParseScopedStatement(labels, CHECK_OK); 5025 } else { 5026 else_statement = factory()->NewEmptyStatement(kNoSourcePosition); 5027 } 5028 return factory()->NewIfStatement(condition, then_statement, else_statement, 5029 pos); 5030 } 5031 5032 template <typename Impl> 5033 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseContinueStatement( 5034 bool* ok) { 5035 // ContinueStatement :: 5036 // 'continue' Identifier? ';' 5037 5038 int pos = peek_position(); 5039 Expect(Token::CONTINUE, CHECK_OK); 5040 IdentifierT label = impl()->EmptyIdentifier(); 5041 Token::Value tok = peek(); 5042 if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON && 5043 tok != Token::RBRACE && tok != Token::EOS) { 5044 // ECMA allows "eval" or "arguments" as labels even in strict mode. 5045 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 5046 } 5047 typename Types::IterationStatement target = 5048 impl()->LookupContinueTarget(label, CHECK_OK); 5049 if (impl()->IsNullStatement(target)) { 5050 // Illegal continue statement. 5051 MessageTemplate::Template message = MessageTemplate::kIllegalContinue; 5052 if (!impl()->IsEmptyIdentifier(label)) { 5053 message = MessageTemplate::kUnknownLabel; 5054 } 5055 ReportMessage(message, label); 5056 *ok = false; 5057 return impl()->NullStatement(); 5058 } 5059 ExpectSemicolon(CHECK_OK); 5060 return factory()->NewContinueStatement(target, pos); 5061 } 5062 5063 template <typename Impl> 5064 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement( 5065 ZoneList<const AstRawString*>* labels, bool* ok) { 5066 // BreakStatement :: 5067 // 'break' Identifier? ';' 5068 5069 int pos = peek_position(); 5070 Expect(Token::BREAK, CHECK_OK); 5071 IdentifierT label = impl()->EmptyIdentifier(); 5072 Token::Value tok = peek(); 5073 if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON && 5074 tok != Token::RBRACE && tok != Token::EOS) { 5075 // ECMA allows "eval" or "arguments" as labels even in strict mode. 5076 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 5077 } 5078 // Parse labeled break statements that target themselves into 5079 // empty statements, e.g. 'l1: l2: l3: break l2;' 5080 if (!impl()->IsEmptyIdentifier(label) && 5081 impl()->ContainsLabel(labels, label)) { 5082 ExpectSemicolon(CHECK_OK); 5083 return factory()->NewEmptyStatement(pos); 5084 } 5085 typename Types::BreakableStatement target = 5086 impl()->LookupBreakTarget(label, CHECK_OK); 5087 if (impl()->IsNullStatement(target)) { 5088 // Illegal break statement. 5089 MessageTemplate::Template message = MessageTemplate::kIllegalBreak; 5090 if (!impl()->IsEmptyIdentifier(label)) { 5091 message = MessageTemplate::kUnknownLabel; 5092 } 5093 ReportMessage(message, label); 5094 *ok = false; 5095 return impl()->NullStatement(); 5096 } 5097 ExpectSemicolon(CHECK_OK); 5098 return factory()->NewBreakStatement(target, pos); 5099 } 5100 5101 template <typename Impl> 5102 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseReturnStatement( 5103 bool* ok) { 5104 // ReturnStatement :: 5105 // 'return' [no line terminator] Expression? ';' 5106 5107 // Consume the return token. It is necessary to do that before 5108 // reporting any errors on it, because of the way errors are 5109 // reported (underlining). 5110 Expect(Token::RETURN, CHECK_OK); 5111 Scanner::Location loc = scanner()->location(); 5112 5113 switch (GetDeclarationScope()->scope_type()) { 5114 case SCRIPT_SCOPE: 5115 case EVAL_SCOPE: 5116 case MODULE_SCOPE: 5117 impl()->ReportMessageAt(loc, MessageTemplate::kIllegalReturn); 5118 *ok = false; 5119 return impl()->NullStatement(); 5120 default: 5121 break; 5122 } 5123 5124 Token::Value tok = peek(); 5125 ExpressionT return_value = impl()->EmptyExpression(); 5126 if (scanner()->HasAnyLineTerminatorBeforeNext() || tok == Token::SEMICOLON || 5127 tok == Token::RBRACE || tok == Token::EOS) { 5128 if (IsDerivedConstructor(function_state_->kind())) { 5129 return_value = impl()->ThisExpression(loc.beg_pos); 5130 } else { 5131 return_value = impl()->GetLiteralUndefined(position()); 5132 } 5133 } else { 5134 if (IsDerivedConstructor(function_state_->kind())) { 5135 // Because of the return code rewriting that happens in case of a subclass 5136 // constructor we don't want to accept tail calls, therefore we don't set 5137 // ReturnExprScope to kInsideValidReturnStatement here. 5138 return_value = ParseExpression(true, CHECK_OK); 5139 } else { 5140 ReturnExprScope maybe_allow_tail_calls( 5141 function_state_, ReturnExprContext::kInsideValidReturnStatement); 5142 return_value = ParseExpression(true, CHECK_OK); 5143 5144 if (allow_tailcalls() && !is_sloppy(language_mode()) && !is_resumable()) { 5145 // ES6 14.6.1 Static Semantics: IsInTailPosition 5146 function_state_->AddImplicitTailCallExpression(return_value); 5147 } 5148 } 5149 } 5150 ExpectSemicolon(CHECK_OK); 5151 return_value = impl()->RewriteReturn(return_value, loc.beg_pos); 5152 return BuildReturnStatement(return_value, loc.beg_pos); 5153 } 5154 5155 template <typename Impl> 5156 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWithStatement( 5157 ZoneList<const AstRawString*>* labels, bool* ok) { 5158 // WithStatement :: 5159 // 'with' '(' Expression ')' Statement 5160 5161 Expect(Token::WITH, CHECK_OK); 5162 int pos = position(); 5163 5164 if (is_strict(language_mode())) { 5165 ReportMessage(MessageTemplate::kStrictWith); 5166 *ok = false; 5167 return impl()->NullStatement(); 5168 } 5169 5170 Expect(Token::LPAREN, CHECK_OK); 5171 ExpressionT expr = ParseExpression(true, CHECK_OK); 5172 Expect(Token::RPAREN, CHECK_OK); 5173 5174 Scope* with_scope = NewScope(WITH_SCOPE); 5175 StatementT body = impl()->NullStatement(); 5176 { 5177 BlockState block_state(&scope_, with_scope); 5178 with_scope->set_start_position(scanner()->peek_location().beg_pos); 5179 body = ParseStatement(labels, CHECK_OK); 5180 with_scope->set_end_position(scanner()->location().end_pos); 5181 } 5182 return factory()->NewWithStatement(with_scope, expr, body, pos); 5183 } 5184 5185 template <typename Impl> 5186 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseDoWhileStatement( 5187 ZoneList<const AstRawString*>* labels, bool* ok) { 5188 // DoStatement :: 5189 // 'do' Statement 'while' '(' Expression ')' ';' 5190 5191 auto loop = factory()->NewDoWhileStatement(labels, peek_position()); 5192 typename Types::Target target(this, loop); 5193 5194 Expect(Token::DO, CHECK_OK); 5195 StatementT body = ParseStatement(nullptr, CHECK_OK); 5196 Expect(Token::WHILE, CHECK_OK); 5197 Expect(Token::LPAREN, CHECK_OK); 5198 5199 ExpressionT cond = ParseExpression(true, CHECK_OK); 5200 Expect(Token::RPAREN, CHECK_OK); 5201 5202 // Allow do-statements to be terminated with and without 5203 // semi-colons. This allows code such as 'do;while(0)return' to 5204 // parse, which would not be the case if we had used the 5205 // ExpectSemicolon() functionality here. 5206 Check(Token::SEMICOLON); 5207 5208 loop->Initialize(cond, body); 5209 return loop; 5210 } 5211 5212 template <typename Impl> 5213 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseWhileStatement( 5214 ZoneList<const AstRawString*>* labels, bool* ok) { 5215 // WhileStatement :: 5216 // 'while' '(' Expression ')' Statement 5217 5218 auto loop = factory()->NewWhileStatement(labels, peek_position()); 5219 typename Types::Target target(this, loop); 5220 5221 Expect(Token::WHILE, CHECK_OK); 5222 Expect(Token::LPAREN, CHECK_OK); 5223 ExpressionT cond = ParseExpression(true, CHECK_OK); 5224 Expect(Token::RPAREN, CHECK_OK); 5225 StatementT body = ParseStatement(nullptr, CHECK_OK); 5226 5227 loop->Initialize(cond, body); 5228 return loop; 5229 } 5230 5231 template <typename Impl> 5232 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseThrowStatement( 5233 bool* ok) { 5234 // ThrowStatement :: 5235 // 'throw' Expression ';' 5236 5237 Expect(Token::THROW, CHECK_OK); 5238 int pos = position(); 5239 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 5240 ReportMessage(MessageTemplate::kNewlineAfterThrow); 5241 *ok = false; 5242 return impl()->NullStatement(); 5243 } 5244 ExpressionT exception = ParseExpression(true, CHECK_OK); 5245 ExpectSemicolon(CHECK_OK); 5246 5247 return impl()->NewThrowStatement(exception, pos); 5248 } 5249 5250 template <typename Impl> 5251 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseSwitchStatement( 5252 ZoneList<const AstRawString*>* labels, bool* ok) { 5253 // SwitchStatement :: 5254 // 'switch' '(' Expression ')' '{' CaseClause* '}' 5255 // CaseClause :: 5256 // 'case' Expression ':' StatementList 5257 // 'default' ':' StatementList 5258 5259 int switch_pos = peek_position(); 5260 5261 Expect(Token::SWITCH, CHECK_OK); 5262 Expect(Token::LPAREN, CHECK_OK); 5263 ExpressionT tag = ParseExpression(true, CHECK_OK); 5264 Expect(Token::RPAREN, CHECK_OK); 5265 5266 auto switch_statement = factory()->NewSwitchStatement(labels, switch_pos); 5267 5268 { 5269 BlockState cases_block_state(zone(), &scope_); 5270 scope()->set_start_position(switch_pos); 5271 scope()->SetNonlinear(); 5272 typename Types::Target target(this, switch_statement); 5273 5274 bool default_seen = false; 5275 auto cases = impl()->NewCaseClauseList(4); 5276 Expect(Token::LBRACE, CHECK_OK); 5277 while (peek() != Token::RBRACE) { 5278 // An empty label indicates the default case. 5279 ExpressionT label = impl()->EmptyExpression(); 5280 if (Check(Token::CASE)) { 5281 label = ParseExpression(true, CHECK_OK); 5282 } else { 5283 Expect(Token::DEFAULT, CHECK_OK); 5284 if (default_seen) { 5285 ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch); 5286 *ok = false; 5287 return impl()->NullStatement(); 5288 } 5289 default_seen = true; 5290 } 5291 Expect(Token::COLON, CHECK_OK); 5292 int clause_pos = position(); 5293 StatementListT statements = impl()->NewStatementList(5); 5294 while (peek() != Token::CASE && peek() != Token::DEFAULT && 5295 peek() != Token::RBRACE) { 5296 StatementT stat = ParseStatementListItem(CHECK_OK); 5297 statements->Add(stat, zone()); 5298 } 5299 auto clause = factory()->NewCaseClause(label, statements, clause_pos); 5300 cases->Add(clause, zone()); 5301 } 5302 Expect(Token::RBRACE, CHECK_OK); 5303 5304 scope()->set_end_position(scanner()->location().end_pos); 5305 return impl()->RewriteSwitchStatement(tag, switch_statement, cases, 5306 scope()->FinalizeBlockScope()); 5307 } 5308 } 5309 5310 template <typename Impl> 5311 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseTryStatement( 5312 bool* ok) { 5313 // TryStatement :: 5314 // 'try' Block Catch 5315 // 'try' Block Finally 5316 // 'try' Block Catch Finally 5317 // 5318 // Catch :: 5319 // 'catch' '(' Identifier ')' Block 5320 // 5321 // Finally :: 5322 // 'finally' Block 5323 5324 Expect(Token::TRY, CHECK_OK); 5325 int pos = position(); 5326 5327 BlockT try_block = impl()->NullBlock(); 5328 { 5329 ReturnExprScope no_tail_calls(function_state_, 5330 ReturnExprContext::kInsideTryBlock); 5331 try_block = ParseBlock(nullptr, CHECK_OK); 5332 } 5333 5334 CatchInfo catch_info(this); 5335 5336 if (peek() != Token::CATCH && peek() != Token::FINALLY) { 5337 ReportMessage(MessageTemplate::kNoCatchOrFinally); 5338 *ok = false; 5339 return impl()->NullStatement(); 5340 } 5341 5342 BlockT catch_block = impl()->NullBlock(); 5343 if (Check(Token::CATCH)) { 5344 Expect(Token::LPAREN, CHECK_OK); 5345 catch_info.scope = NewScope(CATCH_SCOPE); 5346 catch_info.scope->set_start_position(scanner()->location().beg_pos); 5347 5348 { 5349 CollectExpressionsInTailPositionToListScope 5350 collect_tail_call_expressions_scope( 5351 function_state_, &catch_info.tail_call_expressions); 5352 BlockState catch_block_state(&scope_, catch_info.scope); 5353 5354 catch_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition); 5355 5356 // Create a block scope to hold any lexical declarations created 5357 // as part of destructuring the catch parameter. 5358 { 5359 BlockState catch_variable_block_state(zone(), &scope_); 5360 scope()->set_start_position(scanner()->location().beg_pos); 5361 typename Types::Target target(this, catch_block); 5362 5363 // This does not simply call ParsePrimaryExpression to avoid 5364 // ExpressionFromIdentifier from being called in the first 5365 // branch, which would introduce an unresolved symbol and mess 5366 // with arrow function names. 5367 if (peek_any_identifier()) { 5368 catch_info.name = 5369 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK); 5370 } else { 5371 ExpressionClassifier pattern_classifier(this); 5372 catch_info.pattern = ParsePrimaryExpression(CHECK_OK); 5373 ValidateBindingPattern(CHECK_OK); 5374 } 5375 5376 Expect(Token::RPAREN, CHECK_OK); 5377 impl()->RewriteCatchPattern(&catch_info, CHECK_OK); 5378 if (!impl()->IsNullStatement(catch_info.init_block)) { 5379 catch_block->statements()->Add(catch_info.init_block, zone()); 5380 } 5381 5382 catch_info.inner_block = ParseBlock(nullptr, CHECK_OK); 5383 catch_block->statements()->Add(catch_info.inner_block, zone()); 5384 impl()->ValidateCatchBlock(catch_info, CHECK_OK); 5385 scope()->set_end_position(scanner()->location().end_pos); 5386 catch_block->set_scope(scope()->FinalizeBlockScope()); 5387 } 5388 } 5389 5390 catch_info.scope->set_end_position(scanner()->location().end_pos); 5391 } 5392 5393 BlockT finally_block = impl()->NullBlock(); 5394 DCHECK(peek() == Token::FINALLY || !impl()->IsNullStatement(catch_block)); 5395 if (Check(Token::FINALLY)) { 5396 finally_block = ParseBlock(nullptr, CHECK_OK); 5397 } 5398 5399 return impl()->RewriteTryStatement(try_block, catch_block, finally_block, 5400 catch_info, pos); 5401 } 5402 5403 template <typename Impl> 5404 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement( 5405 ZoneList<const AstRawString*>* labels, bool* ok) { 5406 int stmt_pos = peek_position(); 5407 ForInfo for_info(this); 5408 bool bound_names_are_lexical = false; 5409 5410 // Create an in-between scope for let-bound iteration variables. 5411 BlockState for_state(zone(), &scope_); 5412 Expect(Token::FOR, CHECK_OK); 5413 Expect(Token::LPAREN, CHECK_OK); 5414 scope()->set_start_position(scanner()->location().beg_pos); 5415 scope()->set_is_hidden(); 5416 5417 StatementT init = impl()->NullStatement(); 5418 5419 if (peek() == Token::VAR || peek() == Token::CONST || 5420 (peek() == Token::LET && IsNextLetKeyword())) { 5421 // The initializer contains declarations. 5422 ParseVariableDeclarations(kForStatement, &for_info.parsing_result, nullptr, 5423 CHECK_OK); 5424 bound_names_are_lexical = 5425 IsLexicalVariableMode(for_info.parsing_result.descriptor.mode); 5426 for_info.position = scanner()->location().beg_pos; 5427 5428 if (CheckInOrOf(&for_info.mode)) { 5429 return ParseForEachStatementWithDeclarations(stmt_pos, &for_info, labels, 5430 ok); 5431 } 5432 5433 // One or more declaration not followed by in/of. 5434 init = impl()->BuildInitializationBlock( 5435 &for_info.parsing_result, 5436 bound_names_are_lexical ? &for_info.bound_names : nullptr, CHECK_OK); 5437 } else if (peek() != Token::SEMICOLON) { 5438 // The initializer does not contain declarations. 5439 int lhs_beg_pos = peek_position(); 5440 ExpressionClassifier classifier(this); 5441 ExpressionT expression = ParseExpressionCoverGrammar(false, CHECK_OK); 5442 int lhs_end_pos = scanner()->location().end_pos; 5443 5444 bool is_for_each = CheckInOrOf(&for_info.mode); 5445 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() || 5446 expression->IsObjectLiteral()); 5447 5448 if (is_destructuring) { 5449 ValidateAssignmentPattern(CHECK_OK); 5450 } else { 5451 impl()->RewriteNonPattern(CHECK_OK); 5452 } 5453 5454 if (is_for_each) { 5455 return ParseForEachStatementWithoutDeclarations(stmt_pos, expression, 5456 lhs_beg_pos, lhs_end_pos, 5457 &for_info, labels, ok); 5458 } 5459 // Initializer is just an expression. 5460 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); 5461 } 5462 5463 // Standard 'for' loop, we have parsed the initializer at this point. 5464 return ParseStandardForLoop(stmt_pos, init, bound_names_are_lexical, 5465 &for_info, &for_state, labels, ok); 5466 } 5467 5468 template <typename Impl> 5469 typename ParserBase<Impl>::StatementT 5470 ParserBase<Impl>::ParseForEachStatementWithDeclarations( 5471 int stmt_pos, ForInfo* for_info, ZoneList<const AstRawString*>* labels, 5472 bool* ok) { 5473 // Just one declaration followed by in/of. 5474 if (for_info->parsing_result.declarations.length() != 1) { 5475 impl()->ReportMessageAt(for_info->parsing_result.bindings_loc, 5476 MessageTemplate::kForInOfLoopMultiBindings, 5477 ForEachStatement::VisitModeString(for_info->mode)); 5478 *ok = false; 5479 return impl()->NullStatement(); 5480 } 5481 if (for_info->parsing_result.first_initializer_loc.IsValid() && 5482 (is_strict(language_mode()) || 5483 for_info->mode == ForEachStatement::ITERATE || 5484 IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) || 5485 !impl()->IsIdentifier( 5486 for_info->parsing_result.declarations[0].pattern))) { 5487 impl()->ReportMessageAt(for_info->parsing_result.first_initializer_loc, 5488 MessageTemplate::kForInOfLoopInitializer, 5489 ForEachStatement::VisitModeString(for_info->mode)); 5490 *ok = false; 5491 return impl()->NullStatement(); 5492 } 5493 5494 BlockT init_block = impl()->RewriteForVarInLegacy(*for_info); 5495 5496 auto loop = factory()->NewForEachStatement(for_info->mode, labels, stmt_pos); 5497 typename Types::Target target(this, loop); 5498 5499 int each_keyword_pos = scanner()->location().beg_pos; 5500 5501 ExpressionT enumerable = impl()->EmptyExpression(); 5502 if (for_info->mode == ForEachStatement::ITERATE) { 5503 ExpressionClassifier classifier(this); 5504 enumerable = ParseAssignmentExpression(true, CHECK_OK); 5505 impl()->RewriteNonPattern(CHECK_OK); 5506 } else { 5507 enumerable = ParseExpression(true, CHECK_OK); 5508 } 5509 5510 Expect(Token::RPAREN, CHECK_OK); 5511 5512 StatementT final_loop = impl()->NullStatement(); 5513 { 5514 ReturnExprScope no_tail_calls(function_state_, 5515 ReturnExprContext::kInsideForInOfBody); 5516 BlockState block_state(zone(), &scope_); 5517 scope()->set_start_position(scanner()->location().beg_pos); 5518 5519 StatementT body = ParseStatement(nullptr, CHECK_OK); 5520 5521 BlockT body_block = impl()->NullBlock(); 5522 ExpressionT each_variable = impl()->EmptyExpression(); 5523 impl()->DesugarBindingInForEachStatement(for_info, &body_block, 5524 &each_variable, CHECK_OK); 5525 body_block->statements()->Add(body, zone()); 5526 final_loop = impl()->InitializeForEachStatement( 5527 loop, each_variable, enumerable, body_block, each_keyword_pos); 5528 5529 scope()->set_end_position(scanner()->location().end_pos); 5530 body_block->set_scope(scope()->FinalizeBlockScope()); 5531 } 5532 5533 init_block = impl()->CreateForEachStatementTDZ(init_block, *for_info, ok); 5534 5535 scope()->set_end_position(scanner()->location().end_pos); 5536 Scope* for_scope = scope()->FinalizeBlockScope(); 5537 // Parsed for-in loop w/ variable declarations. 5538 if (!impl()->IsNullStatement(init_block)) { 5539 init_block->statements()->Add(final_loop, zone()); 5540 init_block->set_scope(for_scope); 5541 return init_block; 5542 } 5543 5544 DCHECK_NULL(for_scope); 5545 return final_loop; 5546 } 5547 5548 template <typename Impl> 5549 typename ParserBase<Impl>::StatementT 5550 ParserBase<Impl>::ParseForEachStatementWithoutDeclarations( 5551 int stmt_pos, ExpressionT expression, int lhs_beg_pos, int lhs_end_pos, 5552 ForInfo* for_info, ZoneList<const AstRawString*>* labels, bool* ok) { 5553 // Initializer is reference followed by in/of. 5554 if (!expression->IsArrayLiteral() && !expression->IsObjectLiteral()) { 5555 expression = impl()->CheckAndRewriteReferenceExpression( 5556 expression, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor, 5557 kSyntaxError, CHECK_OK); 5558 } 5559 5560 auto loop = factory()->NewForEachStatement(for_info->mode, labels, stmt_pos); 5561 typename Types::Target target(this, loop); 5562 5563 int each_keyword_pos = scanner()->location().beg_pos; 5564 5565 ExpressionT enumerable = impl()->EmptyExpression(); 5566 if (for_info->mode == ForEachStatement::ITERATE) { 5567 ExpressionClassifier classifier(this); 5568 enumerable = ParseAssignmentExpression(true, CHECK_OK); 5569 impl()->RewriteNonPattern(CHECK_OK); 5570 } else { 5571 enumerable = ParseExpression(true, CHECK_OK); 5572 } 5573 5574 Expect(Token::RPAREN, CHECK_OK); 5575 Scope* for_scope = scope(); 5576 5577 { 5578 ReturnExprScope no_tail_calls(function_state_, 5579 ReturnExprContext::kInsideForInOfBody); 5580 BlockState block_state(zone(), &scope_); 5581 scope()->set_start_position(scanner()->location().beg_pos); 5582 5583 StatementT body = ParseStatement(nullptr, CHECK_OK); 5584 scope()->set_end_position(scanner()->location().end_pos); 5585 StatementT final_loop = impl()->InitializeForEachStatement( 5586 loop, expression, enumerable, body, each_keyword_pos); 5587 5588 for_scope = for_scope->FinalizeBlockScope(); 5589 USE(for_scope); 5590 DCHECK_NULL(for_scope); 5591 Scope* block_scope = scope()->FinalizeBlockScope(); 5592 USE(block_scope); 5593 DCHECK_NULL(block_scope); 5594 return final_loop; 5595 } 5596 } 5597 5598 template <typename Impl> 5599 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStandardForLoop( 5600 int stmt_pos, StatementT init, bool bound_names_are_lexical, 5601 ForInfo* for_info, BlockState* for_state, 5602 ZoneList<const AstRawString*>* labels, bool* ok) { 5603 auto loop = factory()->NewForStatement(labels, stmt_pos); 5604 typename Types::Target target(this, loop); 5605 5606 Expect(Token::SEMICOLON, CHECK_OK); 5607 5608 ExpressionT cond = impl()->EmptyExpression(); 5609 StatementT next = impl()->NullStatement(); 5610 StatementT body = impl()->NullStatement(); 5611 5612 // If there are let bindings, then condition and the next statement of the 5613 // for loop must be parsed in a new scope. 5614 Scope* inner_scope = scope(); 5615 if (bound_names_are_lexical && for_info->bound_names.length() > 0) { 5616 inner_scope = NewScopeWithParent(inner_scope, BLOCK_SCOPE); 5617 inner_scope->set_start_position(scanner()->location().beg_pos); 5618 } 5619 { 5620 BlockState block_state(&scope_, inner_scope); 5621 5622 if (peek() != Token::SEMICOLON) { 5623 cond = ParseExpression(true, CHECK_OK); 5624 } 5625 Expect(Token::SEMICOLON, CHECK_OK); 5626 5627 if (peek() != Token::RPAREN) { 5628 ExpressionT exp = ParseExpression(true, CHECK_OK); 5629 next = factory()->NewExpressionStatement(exp, exp->position()); 5630 } 5631 Expect(Token::RPAREN, CHECK_OK); 5632 5633 body = ParseStatement(nullptr, CHECK_OK); 5634 } 5635 5636 if (bound_names_are_lexical && for_info->bound_names.length() > 0) { 5637 auto result = impl()->DesugarLexicalBindingsInForStatement( 5638 loop, init, cond, next, body, inner_scope, *for_info, CHECK_OK); 5639 scope()->set_end_position(scanner()->location().end_pos); 5640 inner_scope->set_end_position(scanner()->location().end_pos); 5641 return result; 5642 } 5643 5644 scope()->set_end_position(scanner()->location().end_pos); 5645 Scope* for_scope = scope()->FinalizeBlockScope(); 5646 if (for_scope != nullptr) { 5647 // Rewrite a for statement of the form 5648 // for (const x = i; c; n) b 5649 // 5650 // into 5651 // 5652 // { 5653 // const x = i; 5654 // for (; c; n) b 5655 // } 5656 // 5657 // or, desugar 5658 // for (; c; n) b 5659 // into 5660 // { 5661 // for (; c; n) b 5662 // } 5663 // just in case b introduces a lexical binding some other way, e.g., if b 5664 // is a FunctionDeclaration. 5665 BlockT block = factory()->NewBlock(nullptr, 2, false, kNoSourcePosition); 5666 if (!impl()->IsNullStatement(init)) { 5667 block->statements()->Add(init, zone()); 5668 } 5669 block->statements()->Add(loop, zone()); 5670 block->set_scope(for_scope); 5671 loop->Initialize(init, cond, next, body); 5672 return block; 5673 } 5674 5675 loop->Initialize(init, cond, next, body); 5676 return loop; 5677 } 5678 5679 template <typename Impl> 5680 void ParserBase<Impl>::MarkLoopVariableAsAssigned(Scope* scope, Variable* var) { 5681 if (!IsLexicalVariableMode(var->mode()) && !scope->is_function_scope()) { 5682 var->set_maybe_assigned(); 5683 } 5684 } 5685 5686 template <typename Impl> 5687 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement( 5688 ZoneList<const AstRawString*>* labels, bool* ok) { 5689 // for await '(' ForDeclaration of AssignmentExpression ')' 5690 DCHECK(is_async_function()); 5691 DCHECK(allow_harmony_async_iteration()); 5692 5693 int stmt_pos = peek_position(); 5694 5695 ForInfo for_info(this); 5696 for_info.mode = ForEachStatement::ITERATE; 5697 5698 // Create an in-between scope for let-bound iteration variables. 5699 BlockState for_state(zone(), &scope_); 5700 Expect(Token::FOR, CHECK_OK); 5701 Expect(Token::AWAIT, CHECK_OK); 5702 Expect(Token::LPAREN, CHECK_OK); 5703 scope()->set_start_position(scanner()->location().beg_pos); 5704 scope()->set_is_hidden(); 5705 5706 auto loop = factory()->NewForOfStatement(labels, stmt_pos); 5707 typename Types::Target target(this, loop); 5708 5709 ExpressionT each_variable = impl()->EmptyExpression(); 5710 5711 bool has_declarations = false; 5712 5713 if (peek() == Token::VAR || peek() == Token::CONST || 5714 (peek() == Token::LET && IsNextLetKeyword())) { 5715 // The initializer contains declarations 5716 // 'for' 'await' '(' ForDeclaration 'of' AssignmentExpression ')' 5717 // Statement 5718 // 'for' 'await' '(' 'var' ForBinding 'of' AssignmentExpression ')' 5719 // Statement 5720 has_declarations = true; 5721 ParseVariableDeclarations(kForStatement, &for_info.parsing_result, nullptr, 5722 CHECK_OK); 5723 for_info.position = scanner()->location().beg_pos; 5724 5725 // Only a single declaration is allowed in for-await-of loops 5726 if (for_info.parsing_result.declarations.length() != 1) { 5727 impl()->ReportMessageAt(for_info.parsing_result.bindings_loc, 5728 MessageTemplate::kForInOfLoopMultiBindings, 5729 "for-await-of"); 5730 *ok = false; 5731 return impl()->NullStatement(); 5732 } 5733 5734 // for-await-of's declarations do not permit initializers. 5735 if (for_info.parsing_result.first_initializer_loc.IsValid()) { 5736 impl()->ReportMessageAt(for_info.parsing_result.first_initializer_loc, 5737 MessageTemplate::kForInOfLoopInitializer, 5738 "for-await-of"); 5739 *ok = false; 5740 return impl()->NullStatement(); 5741 } 5742 } else { 5743 // The initializer does not contain declarations. 5744 // 'for' 'await' '(' LeftHandSideExpression 'of' AssignmentExpression ')' 5745 // Statement 5746 int lhs_beg_pos = peek_position(); 5747 ExpressionClassifier classifier(this); 5748 ExpressionT lhs = each_variable = ParseLeftHandSideExpression(CHECK_OK); 5749 int lhs_end_pos = scanner()->location().end_pos; 5750 5751 if (lhs->IsArrayLiteral() || lhs->IsObjectLiteral()) { 5752 ValidateAssignmentPattern(CHECK_OK); 5753 } else { 5754 impl()->RewriteNonPattern(CHECK_OK); 5755 each_variable = impl()->CheckAndRewriteReferenceExpression( 5756 lhs, lhs_beg_pos, lhs_end_pos, MessageTemplate::kInvalidLhsInFor, 5757 kSyntaxError, CHECK_OK); 5758 } 5759 } 5760 5761 ExpectContextualKeyword(CStrVector("of"), CHECK_OK); 5762 int each_keyword_pos = scanner()->location().beg_pos; 5763 5764 const bool kAllowIn = true; 5765 ExpressionT iterable = impl()->EmptyExpression(); 5766 5767 { 5768 ExpressionClassifier classifier(this); 5769 iterable = ParseAssignmentExpression(kAllowIn, CHECK_OK); 5770 impl()->RewriteNonPattern(CHECK_OK); 5771 } 5772 5773 Expect(Token::RPAREN, CHECK_OK); 5774 5775 StatementT final_loop = impl()->NullStatement(); 5776 Scope* for_scope = scope(); 5777 { 5778 ReturnExprScope no_tail_calls(function_state_, 5779 ReturnExprContext::kInsideForInOfBody); 5780 BlockState block_state(zone(), &scope_); 5781 scope()->set_start_position(scanner()->location().beg_pos); 5782 5783 StatementT body = ParseStatement(nullptr, CHECK_OK); 5784 scope()->set_end_position(scanner()->location().end_pos); 5785 5786 if (has_declarations) { 5787 BlockT body_block = impl()->NullBlock(); 5788 impl()->DesugarBindingInForEachStatement(&for_info, &body_block, 5789 &each_variable, CHECK_OK); 5790 body_block->statements()->Add(body, zone()); 5791 body_block->set_scope(scope()->FinalizeBlockScope()); 5792 5793 const bool finalize = true; 5794 final_loop = impl()->InitializeForOfStatement( 5795 loop, each_variable, iterable, body_block, finalize, 5796 IteratorType::kAsync, each_keyword_pos); 5797 } else { 5798 const bool finalize = true; 5799 final_loop = impl()->InitializeForOfStatement( 5800 loop, each_variable, iterable, body, finalize, IteratorType::kAsync, 5801 each_keyword_pos); 5802 5803 for_scope = for_scope->FinalizeBlockScope(); 5804 DCHECK_NULL(for_scope); 5805 USE(for_scope); 5806 Scope* block_scope = scope()->FinalizeBlockScope(); 5807 DCHECK_NULL(block_scope); 5808 USE(block_scope); 5809 return final_loop; 5810 } 5811 } 5812 5813 DCHECK(has_declarations); 5814 BlockT init_block = 5815 impl()->CreateForEachStatementTDZ(impl()->NullBlock(), for_info, ok); 5816 5817 for_scope->set_end_position(scanner()->location().end_pos); 5818 for_scope = for_scope->FinalizeBlockScope(); 5819 // Parsed for-in loop w/ variable declarations. 5820 if (!impl()->IsNullStatement(init_block)) { 5821 init_block->statements()->Add(final_loop, zone()); 5822 init_block->set_scope(for_scope); 5823 return init_block; 5824 } 5825 DCHECK_NULL(for_scope); 5826 return final_loop; 5827 } 5828 5829 template <typename Impl> 5830 void ParserBase<Impl>::ObjectLiteralChecker::CheckDuplicateProto( 5831 Token::Value property) { 5832 if (property == Token::SMI || property == Token::NUMBER) return; 5833 5834 if (IsProto()) { 5835 if (has_seen_proto_) { 5836 this->parser()->classifier()->RecordExpressionError( 5837 this->scanner()->location(), MessageTemplate::kDuplicateProto); 5838 return; 5839 } 5840 has_seen_proto_ = true; 5841 } 5842 } 5843 5844 template <typename Impl> 5845 void ParserBase<Impl>::ClassLiteralChecker::CheckClassMethodName( 5846 Token::Value property, PropertyKind type, bool is_generator, bool is_async, 5847 bool is_static, bool* ok) { 5848 DCHECK(type == PropertyKind::kMethodProperty || 5849 type == PropertyKind::kAccessorProperty); 5850 5851 if (property == Token::SMI || property == Token::NUMBER) return; 5852 5853 if (is_static) { 5854 if (IsPrototype()) { 5855 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); 5856 *ok = false; 5857 return; 5858 } 5859 } else if (IsConstructor()) { 5860 if (is_generator || is_async || type == PropertyKind::kAccessorProperty) { 5861 MessageTemplate::Template msg = 5862 is_generator ? MessageTemplate::kConstructorIsGenerator 5863 : is_async ? MessageTemplate::kConstructorIsAsync 5864 : MessageTemplate::kConstructorIsAccessor; 5865 this->parser()->ReportMessage(msg); 5866 *ok = false; 5867 return; 5868 } 5869 if (has_seen_constructor_) { 5870 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor); 5871 *ok = false; 5872 return; 5873 } 5874 has_seen_constructor_ = true; 5875 return; 5876 } 5877 } 5878 5879 #undef CHECK_OK 5880 #undef CHECK_OK_CUSTOM 5881 #undef CHECK_OK_VOID 5882 5883 } // namespace internal 5884 } // namespace v8 5885 5886 #endif // V8_PARSING_PARSER_BASE_H 5887