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_PREPARSER_H_ 6 #define V8_PARSING_PREPARSER_H_ 7 8 #include "src/ast/ast.h" 9 #include "src/ast/scopes.h" 10 #include "src/parsing/parser-base.h" 11 #include "src/parsing/preparser-logger.h" 12 #include "src/pending-compilation-error-handler.h" 13 #include "src/zone/zone-containers.h" 14 15 namespace v8 { 16 namespace internal { 17 18 // Whereas the Parser generates AST during the recursive descent, 19 // the PreParser doesn't create a tree. Instead, it passes around minimal 20 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain 21 // just enough data for the upper layer functions. PreParserFactory is 22 // responsible for creating these dummy objects. It provides a similar kind of 23 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is 24 // used. 25 26 class ProducedPreParsedScopeData; 27 28 class PreParserIdentifier { 29 public: 30 PreParserIdentifier() : type_(kUnknownIdentifier) {} 31 static PreParserIdentifier Default() { 32 return PreParserIdentifier(kUnknownIdentifier); 33 } 34 static PreParserIdentifier Null() { 35 return PreParserIdentifier(kNullIdentifier); 36 } 37 static PreParserIdentifier Eval() { 38 return PreParserIdentifier(kEvalIdentifier); 39 } 40 static PreParserIdentifier Arguments() { 41 return PreParserIdentifier(kArgumentsIdentifier); 42 } 43 static PreParserIdentifier Constructor() { 44 return PreParserIdentifier(kConstructorIdentifier); 45 } 46 static PreParserIdentifier Await() { 47 return PreParserIdentifier(kAwaitIdentifier); 48 } 49 static PreParserIdentifier Async() { 50 return PreParserIdentifier(kAsyncIdentifier); 51 } 52 static PreParserIdentifier Name() { 53 return PreParserIdentifier(kNameIdentifier); 54 } 55 static PreParserIdentifier PrivateName() { 56 return PreParserIdentifier(kPrivateNameIdentifier); 57 } 58 bool IsNull() const { return type_ == kNullIdentifier; } 59 bool IsEval() const { return type_ == kEvalIdentifier; } 60 bool IsArguments() const { return type_ == kArgumentsIdentifier; } 61 bool IsEvalOrArguments() const { return IsEval() || IsArguments(); } 62 bool IsConstructor() const { return type_ == kConstructorIdentifier; } 63 bool IsAwait() const { return type_ == kAwaitIdentifier; } 64 bool IsName() const { return type_ == kNameIdentifier; } 65 bool IsPrivateName() const { return type_ == kPrivateNameIdentifier; } 66 67 private: 68 enum Type : uint8_t { 69 kNullIdentifier, 70 kUnknownIdentifier, 71 kEvalIdentifier, 72 kArgumentsIdentifier, 73 kConstructorIdentifier, 74 kAwaitIdentifier, 75 kAsyncIdentifier, 76 kNameIdentifier, 77 kPrivateNameIdentifier 78 }; 79 80 explicit PreParserIdentifier(Type type) : string_(nullptr), type_(type) {} 81 // Only non-nullptr when PreParser.track_unresolved_variables_ is true. 82 const AstRawString* string_; 83 84 Type type_; 85 friend class PreParserExpression; 86 friend class PreParser; 87 friend class PreParserFactory; 88 }; 89 90 91 class PreParserExpression { 92 public: 93 PreParserExpression() 94 : code_(TypeField::encode(kNull)), variables_(nullptr) {} 95 96 static PreParserExpression Null() { return PreParserExpression(); } 97 98 static PreParserExpression Default( 99 ZonePtrList<VariableProxy>* variables = nullptr) { 100 return PreParserExpression(TypeField::encode(kExpression), variables); 101 } 102 103 static PreParserExpression Spread(const PreParserExpression& expression) { 104 return PreParserExpression(TypeField::encode(kSpreadExpression), 105 expression.variables_); 106 } 107 108 static PreParserExpression FromIdentifier(const PreParserIdentifier& id, 109 VariableProxy* variable, 110 Zone* zone) { 111 PreParserExpression expression(TypeField::encode(kIdentifierExpression) | 112 IdentifierTypeField::encode(id.type_)); 113 expression.AddVariable(variable, zone); 114 return expression; 115 } 116 117 static PreParserExpression BinaryOperation(const PreParserExpression& left, 118 Token::Value op, 119 const PreParserExpression& right, 120 Zone* zone) { 121 if (op == Token::COMMA) { 122 // Possibly an arrow function parameter list. 123 if (left.variables_ == nullptr) { 124 return PreParserExpression(TypeField::encode(kExpression), 125 right.variables_); 126 } 127 if (right.variables_ != nullptr) { 128 for (auto variable : *right.variables_) { 129 left.variables_->Add(variable, zone); 130 } 131 } 132 return PreParserExpression(TypeField::encode(kExpression), 133 left.variables_); 134 } 135 return PreParserExpression(TypeField::encode(kExpression)); 136 } 137 138 static PreParserExpression Assignment(ZonePtrList<VariableProxy>* variables) { 139 return PreParserExpression(TypeField::encode(kExpression) | 140 ExpressionTypeField::encode(kAssignment), 141 variables); 142 } 143 144 static PreParserExpression NewTargetExpression() { 145 return PreParserExpression::Default(); 146 } 147 148 static PreParserExpression ObjectLiteral( 149 ZonePtrList<VariableProxy>* variables) { 150 return PreParserExpression(TypeField::encode(kObjectLiteralExpression), 151 variables); 152 } 153 154 static PreParserExpression ArrayLiteral( 155 ZonePtrList<VariableProxy>* variables) { 156 return PreParserExpression(TypeField::encode(kArrayLiteralExpression), 157 variables); 158 } 159 160 static PreParserExpression StringLiteral() { 161 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); 162 } 163 164 static PreParserExpression UseStrictStringLiteral() { 165 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | 166 IsUseStrictField::encode(true)); 167 } 168 169 static PreParserExpression UseAsmStringLiteral() { 170 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | 171 IsUseAsmField::encode(true)); 172 } 173 174 static PreParserExpression This(ZonePtrList<VariableProxy>* variables) { 175 return PreParserExpression(TypeField::encode(kExpression) | 176 ExpressionTypeField::encode(kThisExpression), 177 variables); 178 } 179 180 static PreParserExpression ThisPropertyWithPrivateFieldKey() { 181 return PreParserExpression(TypeField::encode(kExpression) | 182 ExpressionTypeField::encode( 183 kThisPropertyExpressionWithPrivateFieldKey)); 184 } 185 186 static PreParserExpression ThisProperty() { 187 return PreParserExpression( 188 TypeField::encode(kExpression) | 189 ExpressionTypeField::encode(kThisPropertyExpression)); 190 } 191 192 static PreParserExpression Property() { 193 return PreParserExpression( 194 TypeField::encode(kExpression) | 195 ExpressionTypeField::encode(kPropertyExpression)); 196 } 197 198 static PreParserExpression PropertyWithPrivateFieldKey() { 199 return PreParserExpression( 200 TypeField::encode(kExpression) | 201 ExpressionTypeField::encode(kPropertyExpressionWithPrivateFieldKey)); 202 } 203 204 static PreParserExpression Call() { 205 return PreParserExpression(TypeField::encode(kExpression) | 206 ExpressionTypeField::encode(kCallExpression)); 207 } 208 209 static PreParserExpression CallEval() { 210 return PreParserExpression( 211 TypeField::encode(kExpression) | 212 ExpressionTypeField::encode(kCallEvalExpression)); 213 } 214 215 static PreParserExpression CallTaggedTemplate() { 216 return PreParserExpression( 217 TypeField::encode(kExpression) | 218 ExpressionTypeField::encode(kCallTaggedTemplateExpression)); 219 } 220 221 bool is_tagged_template() const { 222 DCHECK(IsCall()); 223 return ExpressionTypeField::decode(code_) == kCallTaggedTemplateExpression; 224 } 225 226 static PreParserExpression SuperCallReference() { 227 return PreParserExpression( 228 TypeField::encode(kExpression) | 229 ExpressionTypeField::encode(kSuperCallReference)); 230 } 231 232 bool IsNull() const { return TypeField::decode(code_) == kNull; } 233 234 bool IsIdentifier() const { 235 return TypeField::decode(code_) == kIdentifierExpression; 236 } 237 238 PreParserIdentifier AsIdentifier() const { 239 DCHECK(IsIdentifier()); 240 return PreParserIdentifier(IdentifierTypeField::decode(code_)); 241 } 242 243 bool IsAssignment() const { 244 return TypeField::decode(code_) == kExpression && 245 ExpressionTypeField::decode(code_) == kAssignment; 246 } 247 248 bool IsObjectLiteral() const { 249 return TypeField::decode(code_) == kObjectLiteralExpression; 250 } 251 252 bool IsArrayLiteral() const { 253 return TypeField::decode(code_) == kArrayLiteralExpression; 254 } 255 256 bool IsStringLiteral() const { 257 return TypeField::decode(code_) == kStringLiteralExpression; 258 } 259 260 bool IsUseStrictLiteral() const { 261 return TypeField::decode(code_) == kStringLiteralExpression && 262 IsUseStrictField::decode(code_); 263 } 264 265 bool IsUseAsmLiteral() const { 266 return TypeField::decode(code_) == kStringLiteralExpression && 267 IsUseAsmField::decode(code_); 268 } 269 270 bool IsThis() const { 271 return TypeField::decode(code_) == kExpression && 272 ExpressionTypeField::decode(code_) == kThisExpression; 273 } 274 275 bool IsThisProperty() const { 276 return TypeField::decode(code_) == kExpression && 277 (ExpressionTypeField::decode(code_) == kThisPropertyExpression || 278 ExpressionTypeField::decode(code_) == 279 kThisPropertyExpressionWithPrivateFieldKey); 280 } 281 282 bool IsProperty() const { 283 return TypeField::decode(code_) == kExpression && 284 (ExpressionTypeField::decode(code_) == kPropertyExpression || 285 ExpressionTypeField::decode(code_) == kThisPropertyExpression || 286 ExpressionTypeField::decode(code_) == 287 kPropertyExpressionWithPrivateFieldKey || 288 ExpressionTypeField::decode(code_) == 289 kThisPropertyExpressionWithPrivateFieldKey); 290 } 291 292 bool IsPropertyWithPrivateFieldKey() const { 293 return TypeField::decode(code_) == kExpression && 294 (ExpressionTypeField::decode(code_) == 295 kPropertyExpressionWithPrivateFieldKey || 296 ExpressionTypeField::decode(code_) == 297 kThisPropertyExpressionWithPrivateFieldKey); 298 } 299 300 bool IsCall() const { 301 return TypeField::decode(code_) == kExpression && 302 (ExpressionTypeField::decode(code_) == kCallExpression || 303 ExpressionTypeField::decode(code_) == kCallEvalExpression || 304 ExpressionTypeField::decode(code_) == 305 kCallTaggedTemplateExpression); 306 } 307 PreParserExpression* AsCall() { 308 if (IsCall()) return this; 309 return nullptr; 310 } 311 312 bool IsSuperCallReference() const { 313 return TypeField::decode(code_) == kExpression && 314 ExpressionTypeField::decode(code_) == kSuperCallReference; 315 } 316 317 bool IsValidReferenceExpression() const { 318 return IsIdentifier() || IsProperty(); 319 } 320 321 // At the moment PreParser doesn't track these expression types. 322 bool IsFunctionLiteral() const { return false; } 323 bool IsCallNew() const { return false; } 324 325 bool IsSpread() const { 326 return TypeField::decode(code_) == kSpreadExpression; 327 } 328 329 PreParserExpression AsFunctionLiteral() { return *this; } 330 331 // Dummy implementation for making expression->somefunc() work in both Parser 332 // and PreParser. 333 PreParserExpression* operator->() { return this; } 334 335 void set_is_private_field() { 336 if (variables_ != nullptr) { 337 DCHECK(IsIdentifier()); 338 DCHECK(AsIdentifier().IsPrivateName()); 339 DCHECK_EQ(1, variables_->length()); 340 variables_->first()->set_is_private_field(); 341 } 342 } 343 344 // More dummy implementations of things PreParser doesn't need to track: 345 void SetShouldEagerCompile() {} 346 void mark_as_iife() {} 347 348 int position() const { return kNoSourcePosition; } 349 void set_function_token_position(int position) {} 350 void set_scope(Scope* scope) {} 351 void set_suspend_count(int suspend_count) {} 352 353 private: 354 enum Type { 355 kNull, 356 kExpression, 357 kIdentifierExpression, 358 kStringLiteralExpression, 359 kSpreadExpression, 360 kObjectLiteralExpression, 361 kArrayLiteralExpression 362 }; 363 364 enum ExpressionType { 365 kThisExpression, 366 kThisPropertyExpression, 367 kThisPropertyExpressionWithPrivateFieldKey, 368 kPropertyExpression, 369 kPropertyExpressionWithPrivateFieldKey, 370 kCallExpression, 371 kCallEvalExpression, 372 kCallTaggedTemplateExpression, 373 kSuperCallReference, 374 kAssignment 375 }; 376 377 explicit PreParserExpression(uint32_t expression_code, 378 ZonePtrList<VariableProxy>* variables = nullptr) 379 : code_(expression_code), variables_(variables) {} 380 381 void AddVariable(VariableProxy* variable, Zone* zone) { 382 if (variable == nullptr) { 383 return; 384 } 385 if (variables_ == nullptr) { 386 variables_ = new (zone) ZonePtrList<VariableProxy>(1, zone); 387 } 388 variables_->Add(variable, zone); 389 } 390 391 // The first three bits are for the Type. 392 typedef BitField<Type, 0, 3> TypeField; 393 394 // The high order bit applies only to nodes which would inherit from the 395 // Expression ASTNode --- This is by necessity, due to the fact that 396 // Expression nodes may be represented as multiple Types, not exclusively 397 // through kExpression. 398 // TODO(caitp, adamk): clean up PreParserExpression bitfields. 399 typedef BitField<bool, 31, 1> ParenthesizedField; 400 401 // The rest of the bits are interpreted depending on the value 402 // of the Type field, so they can share the storage. 403 typedef BitField<ExpressionType, TypeField::kNext, 4> ExpressionTypeField; 404 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField; 405 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseAsmField; 406 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 8> 407 IdentifierTypeField; 408 typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField; 409 410 uint32_t code_; 411 // If the PreParser is used in the variable tracking mode, PreParserExpression 412 // accumulates variables in that expression. 413 ZonePtrList<VariableProxy>* variables_; 414 415 friend class PreParser; 416 friend class PreParserFactory; 417 template <typename T> 418 friend class PreParserList; 419 }; 420 421 422 // The pre-parser doesn't need to build lists of expressions, identifiers, or 423 // the like. If the PreParser is used in variable tracking mode, it needs to 424 // build lists of variables though. 425 template <typename T> 426 class PreParserList { 427 public: 428 // These functions make list->Add(some_expression) work (and do nothing). 429 PreParserList() : length_(0), variables_(nullptr) {} 430 PreParserList* operator->() { return this; } 431 void Add(const T& element, Zone* zone); 432 int length() const { return length_; } 433 static PreParserList Null() { return PreParserList(-1); } 434 bool IsNull() const { return length_ == -1; } 435 void Set(int index, const T& element) {} 436 437 private: 438 explicit PreParserList(int n) : length_(n), variables_(nullptr) {} 439 int length_; 440 ZonePtrList<VariableProxy>* variables_; 441 442 friend class PreParser; 443 friend class PreParserFactory; 444 }; 445 446 template <> 447 inline void PreParserList<PreParserExpression>::Add( 448 const PreParserExpression& expression, Zone* zone) { 449 if (expression.variables_ != nullptr) { 450 DCHECK(FLAG_lazy_inner_functions); 451 DCHECK_NOT_NULL(zone); 452 if (variables_ == nullptr) { 453 variables_ = new (zone) ZonePtrList<VariableProxy>(1, zone); 454 } 455 for (auto identifier : (*expression.variables_)) { 456 variables_->Add(identifier, zone); 457 } 458 } 459 ++length_; 460 } 461 462 template <typename T> 463 void PreParserList<T>::Add(const T& element, Zone* zone) { 464 ++length_; 465 } 466 467 typedef PreParserList<PreParserExpression> PreParserExpressionList; 468 469 class PreParserStatement; 470 typedef PreParserList<PreParserStatement> PreParserStatementList; 471 472 class PreParserStatement { 473 public: 474 static PreParserStatement Default() { 475 return PreParserStatement(kUnknownStatement); 476 } 477 478 static PreParserStatement Null() { 479 return PreParserStatement(kNullStatement); 480 } 481 482 static PreParserStatement Empty() { 483 return PreParserStatement(kEmptyStatement); 484 } 485 486 static PreParserStatement Jump() { 487 return PreParserStatement(kJumpStatement); 488 } 489 490 // Creates expression statement from expression. 491 // Preserves being an unparenthesized string literal, possibly 492 // "use strict". 493 static PreParserStatement ExpressionStatement( 494 const PreParserExpression& expression) { 495 if (expression.IsUseStrictLiteral()) { 496 return PreParserStatement(kUseStrictExpressionStatement); 497 } 498 if (expression.IsUseAsmLiteral()) { 499 return PreParserStatement(kUseAsmExpressionStatement); 500 } 501 if (expression.IsStringLiteral()) { 502 return PreParserStatement(kStringLiteralExpressionStatement); 503 } 504 return Default(); 505 } 506 507 bool IsStringLiteral() { 508 return code_ == kStringLiteralExpressionStatement || IsUseStrictLiteral() || 509 IsUseAsmLiteral(); 510 } 511 512 bool IsUseStrictLiteral() { 513 return code_ == kUseStrictExpressionStatement; 514 } 515 516 bool IsUseAsmLiteral() { return code_ == kUseAsmExpressionStatement; } 517 518 bool IsJumpStatement() { 519 return code_ == kJumpStatement; 520 } 521 522 bool IsNull() { return code_ == kNullStatement; } 523 524 bool IsEmptyStatement() { 525 DCHECK(!IsNull()); 526 return code_ == kEmptyStatement; 527 } 528 529 // Dummy implementation for making statement->somefunc() work in both Parser 530 // and PreParser. 531 PreParserStatement* operator->() { return this; } 532 533 // TODO(adamk): These should return something even lighter-weight than 534 // PreParserStatementList. 535 PreParserStatementList statements() { return PreParserStatementList(); } 536 PreParserStatementList cases() { return PreParserStatementList(); } 537 538 void set_scope(Scope* scope) {} 539 void Initialize(const PreParserExpression& cond, PreParserStatement body, 540 const SourceRange& body_range = {}) {} 541 void Initialize(PreParserStatement init, const PreParserExpression& cond, 542 PreParserStatement next, PreParserStatement body, 543 const SourceRange& body_range = {}) {} 544 545 private: 546 enum Type { 547 kNullStatement, 548 kEmptyStatement, 549 kUnknownStatement, 550 kJumpStatement, 551 kStringLiteralExpressionStatement, 552 kUseStrictExpressionStatement, 553 kUseAsmExpressionStatement, 554 }; 555 556 explicit PreParserStatement(Type code) : code_(code) {} 557 Type code_; 558 }; 559 560 561 class PreParserFactory { 562 public: 563 explicit PreParserFactory(AstValueFactory* ast_value_factory, Zone* zone) 564 : ast_node_factory_(ast_value_factory, zone), zone_(zone) {} 565 566 void set_zone(Zone* zone) { 567 ast_node_factory_.set_zone(zone); 568 zone_ = zone; 569 } 570 571 AstNodeFactory* ast_node_factory() { return &ast_node_factory_; } 572 573 PreParserExpression NewStringLiteral(const PreParserIdentifier& identifier, 574 int pos) { 575 // This is needed for object literal property names. Property names are 576 // normalized to string literals during object literal parsing. 577 PreParserExpression expression = PreParserExpression::Default(); 578 if (identifier.string_ != nullptr) { 579 DCHECK(FLAG_lazy_inner_functions); 580 VariableProxy* variable = ast_node_factory_.NewVariableProxy( 581 identifier.string_, NORMAL_VARIABLE); 582 expression.AddVariable(variable, zone_); 583 } 584 return expression; 585 } 586 PreParserExpression NewNumberLiteral(double number, 587 int pos) { 588 return PreParserExpression::Default(); 589 } 590 PreParserExpression NewUndefinedLiteral(int pos) { 591 return PreParserExpression::Default(); 592 } 593 PreParserExpression NewTheHoleLiteral() { 594 return PreParserExpression::Default(); 595 } 596 PreParserExpression NewRegExpLiteral(const PreParserIdentifier& js_pattern, 597 int js_flags, int pos) { 598 return PreParserExpression::Default(); 599 } 600 PreParserExpression NewArrayLiteral(const PreParserExpressionList& values, 601 int first_spread_index, int pos) { 602 return PreParserExpression::ArrayLiteral(values.variables_); 603 } 604 PreParserExpression NewClassLiteralProperty(const PreParserExpression& key, 605 const PreParserExpression& value, 606 ClassLiteralProperty::Kind kind, 607 bool is_static, 608 bool is_computed_name) { 609 return PreParserExpression::Default(); 610 } 611 PreParserExpression NewObjectLiteralProperty(const PreParserExpression& key, 612 const PreParserExpression& value, 613 ObjectLiteralProperty::Kind kind, 614 bool is_computed_name) { 615 return PreParserExpression::Default(value.variables_); 616 } 617 PreParserExpression NewObjectLiteralProperty(const PreParserExpression& key, 618 const PreParserExpression& value, 619 bool is_computed_name) { 620 return PreParserExpression::Default(value.variables_); 621 } 622 PreParserExpression NewObjectLiteral( 623 const PreParserExpressionList& properties, int boilerplate_properties, 624 int pos, bool has_rest_property) { 625 return PreParserExpression::ObjectLiteral(properties.variables_); 626 } 627 PreParserExpression NewVariableProxy(void* variable) { 628 return PreParserExpression::Default(); 629 } 630 631 PreParserExpression NewProperty(const PreParserExpression& obj, 632 const PreParserExpression& key, int pos) { 633 if (key.IsIdentifier() && key.AsIdentifier().IsPrivateName()) { 634 if (obj.IsThis()) { 635 return PreParserExpression::ThisPropertyWithPrivateFieldKey(); 636 } 637 return PreParserExpression::PropertyWithPrivateFieldKey(); 638 } 639 640 if (obj.IsThis()) { 641 return PreParserExpression::ThisProperty(); 642 } 643 return PreParserExpression::Property(); 644 } 645 PreParserExpression NewUnaryOperation(Token::Value op, 646 const PreParserExpression& expression, 647 int pos) { 648 return PreParserExpression::Default(); 649 } 650 PreParserExpression NewBinaryOperation(Token::Value op, 651 const PreParserExpression& left, 652 const PreParserExpression& right, 653 int pos) { 654 return PreParserExpression::BinaryOperation(left, op, right, zone_); 655 } 656 PreParserExpression NewCompareOperation(Token::Value op, 657 const PreParserExpression& left, 658 const PreParserExpression& right, 659 int pos) { 660 return PreParserExpression::Default(); 661 } 662 PreParserExpression NewRewritableExpression( 663 const PreParserExpression& expression, Scope* scope) { 664 return expression; 665 } 666 PreParserExpression NewAssignment(Token::Value op, 667 const PreParserExpression& left, 668 const PreParserExpression& right, int pos) { 669 // Identifiers need to be tracked since this might be a parameter with a 670 // default value inside an arrow function parameter list. 671 return PreParserExpression::Assignment(left.variables_); 672 } 673 PreParserExpression NewYield(const PreParserExpression& expression, int pos, 674 Suspend::OnAbruptResume on_abrupt_resume) { 675 return PreParserExpression::Default(); 676 } 677 PreParserExpression NewAwait(const PreParserExpression& expression, int pos) { 678 return PreParserExpression::Default(); 679 } 680 PreParserExpression NewYieldStar(const PreParserExpression& iterable, 681 int pos) { 682 return PreParserExpression::Default(); 683 } 684 PreParserExpression NewConditional(const PreParserExpression& condition, 685 const PreParserExpression& then_expression, 686 const PreParserExpression& else_expression, 687 int pos) { 688 return PreParserExpression::Default(); 689 } 690 PreParserExpression NewCountOperation(Token::Value op, bool is_prefix, 691 const PreParserExpression& expression, 692 int pos) { 693 return PreParserExpression::Default(); 694 } 695 PreParserExpression NewCall( 696 PreParserExpression expression, const PreParserExpressionList& arguments, 697 int pos, Call::PossiblyEval possibly_eval = Call::NOT_EVAL) { 698 if (possibly_eval == Call::IS_POSSIBLY_EVAL) { 699 DCHECK(expression.IsIdentifier() && expression.AsIdentifier().IsEval()); 700 return PreParserExpression::CallEval(); 701 } 702 return PreParserExpression::Call(); 703 } 704 PreParserExpression NewTaggedTemplate( 705 PreParserExpression expression, const PreParserExpressionList& arguments, 706 int pos) { 707 return PreParserExpression::CallTaggedTemplate(); 708 } 709 PreParserExpression NewCallNew(const PreParserExpression& expression, 710 const PreParserExpressionList& arguments, 711 int pos) { 712 return PreParserExpression::Default(); 713 } 714 PreParserStatement NewReturnStatement( 715 const PreParserExpression& expression, int pos, 716 int continuation_pos = kNoSourcePosition) { 717 return PreParserStatement::Jump(); 718 } 719 PreParserStatement NewAsyncReturnStatement( 720 const PreParserExpression& expression, int pos, 721 int continuation_pos = kNoSourcePosition) { 722 return PreParserStatement::Jump(); 723 } 724 PreParserExpression NewFunctionLiteral( 725 const PreParserIdentifier& name, Scope* scope, 726 PreParserStatementList body, int expected_property_count, 727 int parameter_count, int function_length, 728 FunctionLiteral::ParameterFlag has_duplicate_parameters, 729 FunctionLiteral::FunctionType function_type, 730 FunctionLiteral::EagerCompileHint eager_compile_hint, int position, 731 bool has_braces, int function_literal_id, 732 ProducedPreParsedScopeData* produced_preparsed_scope_data = nullptr) { 733 DCHECK_NULL(produced_preparsed_scope_data); 734 return PreParserExpression::Default(); 735 } 736 737 PreParserExpression NewSpread(const PreParserExpression& expression, int pos, 738 int expr_pos) { 739 return PreParserExpression::Spread(expression); 740 } 741 742 PreParserExpression NewEmptyParentheses(int pos) { 743 return PreParserExpression::Default(); 744 } 745 746 PreParserStatement NewEmptyStatement(int pos) { 747 return PreParserStatement::Default(); 748 } 749 750 PreParserStatement NewBlock( 751 int capacity, bool ignore_completion_value, 752 ZonePtrList<const AstRawString>* labels = nullptr) { 753 return PreParserStatement::Default(); 754 } 755 756 PreParserStatement NewDebuggerStatement(int pos) { 757 return PreParserStatement::Default(); 758 } 759 760 PreParserStatement NewExpressionStatement(const PreParserExpression& expr, 761 int pos) { 762 return PreParserStatement::ExpressionStatement(expr); 763 } 764 765 PreParserStatement NewIfStatement(const PreParserExpression& condition, 766 PreParserStatement then_statement, 767 PreParserStatement else_statement, int pos, 768 SourceRange then_range = {}, 769 SourceRange else_range = {}) { 770 // This must return a jump statement iff both clauses are jump statements. 771 return else_statement.IsJumpStatement() ? then_statement : else_statement; 772 } 773 774 PreParserStatement NewBreakStatement( 775 PreParserStatement target, int pos, 776 int continuation_pos = kNoSourcePosition) { 777 return PreParserStatement::Jump(); 778 } 779 780 PreParserStatement NewContinueStatement( 781 PreParserStatement target, int pos, 782 int continuation_pos = kNoSourcePosition) { 783 return PreParserStatement::Jump(); 784 } 785 786 PreParserStatement NewWithStatement(Scope* scope, 787 const PreParserExpression& expression, 788 PreParserStatement statement, int pos) { 789 return PreParserStatement::Default(); 790 } 791 792 PreParserStatement NewDoWhileStatement( 793 ZonePtrList<const AstRawString>* labels, 794 ZonePtrList<const AstRawString>* own_labels, int pos) { 795 return PreParserStatement::Default(); 796 } 797 798 PreParserStatement NewWhileStatement( 799 ZonePtrList<const AstRawString>* labels, 800 ZonePtrList<const AstRawString>* own_labels, int pos) { 801 return PreParserStatement::Default(); 802 } 803 804 PreParserStatement NewSwitchStatement(ZonePtrList<const AstRawString>* labels, 805 const PreParserExpression& tag, 806 int pos) { 807 return PreParserStatement::Default(); 808 } 809 810 PreParserStatement NewCaseClause(const PreParserExpression& label, 811 PreParserStatementList statements) { 812 return PreParserStatement::Default(); 813 } 814 815 PreParserStatement NewForStatement( 816 ZonePtrList<const AstRawString>* labels, 817 ZonePtrList<const AstRawString>* own_labels, int pos) { 818 return PreParserStatement::Default(); 819 } 820 821 PreParserStatement NewForEachStatement( 822 ForEachStatement::VisitMode visit_mode, 823 ZonePtrList<const AstRawString>* labels, 824 ZonePtrList<const AstRawString>* own_labels, int pos) { 825 return PreParserStatement::Default(); 826 } 827 828 PreParserStatement NewForOfStatement( 829 ZonePtrList<const AstRawString>* labels, 830 ZonePtrList<const AstRawString>* own_labels, int pos) { 831 return PreParserStatement::Default(); 832 } 833 834 PreParserExpression NewCallRuntime( 835 Runtime::FunctionId id, ZoneChunkList<PreParserExpression>* arguments, 836 int pos) { 837 return PreParserExpression::Default(); 838 } 839 840 PreParserExpression NewImportCallExpression(const PreParserExpression& args, 841 int pos) { 842 return PreParserExpression::Default(); 843 } 844 845 private: 846 // For creating VariableProxy objects (if 847 // PreParser::track_unresolved_variables_ is used). 848 AstNodeFactory ast_node_factory_; 849 Zone* zone_; 850 }; 851 852 853 struct PreParserFormalParameters : FormalParametersBase { 854 struct Parameter : public ZoneObject { 855 Parameter(ZonePtrList<VariableProxy>* variables, bool is_rest) 856 : variables_(variables), is_rest(is_rest) {} 857 Parameter** next() { return &next_parameter; } 858 Parameter* const* next() const { return &next_parameter; } 859 860 ZonePtrList<VariableProxy>* variables_; 861 Parameter* next_parameter = nullptr; 862 bool is_rest : 1; 863 }; 864 explicit PreParserFormalParameters(DeclarationScope* scope) 865 : FormalParametersBase(scope) {} 866 867 ThreadedList<Parameter> params; 868 }; 869 870 871 class PreParser; 872 873 class PreParserTarget { 874 public: 875 PreParserTarget(ParserBase<PreParser>* preparser, 876 PreParserStatement statement) {} 877 }; 878 879 class PreParserTargetScope { 880 public: 881 explicit PreParserTargetScope(ParserBase<PreParser>* preparser) {} 882 }; 883 884 template <> 885 struct ParserTypes<PreParser> { 886 typedef ParserBase<PreParser> Base; 887 typedef PreParser Impl; 888 889 // Return types for traversing functions. 890 typedef PreParserIdentifier Identifier; 891 typedef PreParserExpression Expression; 892 typedef PreParserExpression FunctionLiteral; 893 typedef PreParserExpression ObjectLiteralProperty; 894 typedef PreParserExpression ClassLiteralProperty; 895 typedef PreParserExpression Suspend; 896 typedef PreParserExpression RewritableExpression; 897 typedef PreParserExpressionList ExpressionList; 898 typedef PreParserExpressionList ObjectPropertyList; 899 typedef PreParserExpressionList ClassPropertyList; 900 typedef PreParserFormalParameters FormalParameters; 901 typedef PreParserStatement Statement; 902 typedef PreParserStatementList StatementList; 903 typedef PreParserStatement Block; 904 typedef PreParserStatement BreakableStatement; 905 typedef PreParserStatement IterationStatement; 906 typedef PreParserStatement ForStatement; 907 908 // For constructing objects returned by the traversing functions. 909 typedef PreParserFactory Factory; 910 911 typedef PreParserTarget Target; 912 typedef PreParserTargetScope TargetScope; 913 }; 914 915 916 // Preparsing checks a JavaScript program and emits preparse-data that helps 917 // a later parsing to be faster. 918 // See preparse-data-format.h for the data format. 919 920 // The PreParser checks that the syntax follows the grammar for JavaScript, 921 // and collects some information about the program along the way. 922 // The grammar check is only performed in order to understand the program 923 // sufficiently to deduce some information about it, that can be used 924 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 925 // rather it is to speed up properly written and correct programs. 926 // That means that contextual checks (like a label being declared where 927 // it is used) are generally omitted. 928 class PreParser : public ParserBase<PreParser> { 929 friend class ParserBase<PreParser>; 930 friend class v8::internal::ExpressionClassifier<ParserTypes<PreParser>>; 931 932 public: 933 typedef PreParserIdentifier Identifier; 934 typedef PreParserExpression Expression; 935 typedef PreParserStatement Statement; 936 937 enum PreParseResult { 938 kPreParseStackOverflow, 939 kPreParseAbort, 940 kPreParseSuccess 941 }; 942 943 PreParser(Zone* zone, Scanner* scanner, uintptr_t stack_limit, 944 AstValueFactory* ast_value_factory, 945 PendingCompilationErrorHandler* pending_error_handler, 946 RuntimeCallStats* runtime_call_stats, Logger* logger, 947 int script_id = -1, bool parsing_module = false, 948 bool parsing_on_main_thread = true) 949 : ParserBase<PreParser>(zone, scanner, stack_limit, nullptr, 950 ast_value_factory, pending_error_handler, 951 runtime_call_stats, logger, script_id, 952 parsing_module, parsing_on_main_thread), 953 use_counts_(nullptr), 954 track_unresolved_variables_(false), 955 produced_preparsed_scope_data_(nullptr) {} 956 957 static bool IsPreParser() { return true; } 958 959 PreParserLogger* logger() { return &log_; } 960 961 // Pre-parse the program from the character stream; returns true on 962 // success (even if parsing failed, the pre-parse data successfully 963 // captured the syntax error), and false if a stack-overflow happened 964 // during parsing. 965 PreParseResult PreParseProgram(); 966 967 // Parses a single function literal, from the opening parentheses before 968 // parameters to the closing brace after the body. 969 // Returns a FunctionEntry describing the body of the function in enough 970 // detail that it can be lazily compiled. 971 // The scanner is expected to have matched the "function" or "function*" 972 // keyword and parameters, and have consumed the initial '{'. 973 // At return, unless an error occurred, the scanner is positioned before the 974 // the final '}'. 975 PreParseResult PreParseFunction( 976 const AstRawString* function_name, FunctionKind kind, 977 FunctionLiteral::FunctionType function_type, 978 DeclarationScope* function_scope, bool track_unresolved_variables, 979 bool may_abort, int* use_counts, 980 ProducedPreParsedScopeData** produced_preparser_scope_data, 981 int script_id); 982 983 ProducedPreParsedScopeData* produced_preparsed_scope_data() const { 984 return produced_preparsed_scope_data_; 985 } 986 987 void set_produced_preparsed_scope_data( 988 ProducedPreParsedScopeData* produced_preparsed_scope_data) { 989 produced_preparsed_scope_data_ = produced_preparsed_scope_data; 990 } 991 992 private: 993 // These types form an algebra over syntactic categories that is just 994 // rich enough to let us recognize and propagate the constructs that 995 // are either being counted in the preparser data, or is important 996 // to throw the correct syntax error exceptions. 997 998 // All ParseXXX functions take as the last argument an *ok parameter 999 // which is set to false if parsing failed; it is unchanged otherwise. 1000 // By making the 'exception handling' explicit, we are forced to check 1001 // for failure at the call sites. 1002 1003 // Indicates that we won't switch from the preparser to the preparser; we'll 1004 // just stay where we are. 1005 bool AllowsLazyParsingWithoutUnresolvedVariables() const { return false; } 1006 bool parse_lazily() const { return false; } 1007 1008 PendingCompilationErrorHandler* pending_error_handler() { 1009 return pending_error_handler_; 1010 } 1011 1012 V8_INLINE LazyParsingResult 1013 SkipFunction(const AstRawString* name, FunctionKind kind, 1014 FunctionLiteral::FunctionType function_type, 1015 DeclarationScope* function_scope, int* num_parameters, 1016 ProducedPreParsedScopeData** produced_preparsed_scope_data, 1017 bool is_inner_function, bool may_abort, bool* ok) { 1018 UNREACHABLE(); 1019 } 1020 1021 Expression ParseFunctionLiteral( 1022 Identifier name, Scanner::Location function_name_location, 1023 FunctionNameValidity function_name_validity, FunctionKind kind, 1024 int function_token_pos, FunctionLiteral::FunctionType function_type, 1025 LanguageMode language_mode, 1026 ZonePtrList<const AstRawString>* arguments_for_wrapped_function, 1027 bool* ok); 1028 1029 PreParserExpression InitializeObjectLiteral(PreParserExpression literal) { 1030 return literal; 1031 } 1032 1033 LazyParsingResult ParseStatementListAndLogFunction( 1034 PreParserFormalParameters* formals, bool maybe_abort, bool* ok); 1035 1036 struct TemplateLiteralState {}; 1037 1038 V8_INLINE TemplateLiteralState OpenTemplateLiteral(int pos) { 1039 return TemplateLiteralState(); 1040 } 1041 V8_INLINE void AddTemplateExpression(TemplateLiteralState* state, 1042 const PreParserExpression& expression) {} 1043 V8_INLINE void AddTemplateSpan(TemplateLiteralState* state, bool should_cook, 1044 bool tail) {} 1045 V8_INLINE PreParserExpression CloseTemplateLiteral( 1046 TemplateLiteralState* state, int start, const PreParserExpression& tag) { 1047 return PreParserExpression::Default(); 1048 } 1049 V8_INLINE bool IsPropertyWithPrivateFieldKey( 1050 const PreParserExpression& expression) { 1051 return expression.IsPropertyWithPrivateFieldKey(); 1052 } 1053 V8_INLINE void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} 1054 1055 V8_INLINE void SetLanguageMode(Scope* scope, LanguageMode mode) { 1056 scope->SetLanguageMode(mode); 1057 } 1058 V8_INLINE void SetAsmModule() {} 1059 1060 V8_INLINE PreParserExpression SpreadCall(const PreParserExpression& function, 1061 const PreParserExpressionList& args, 1062 int pos, 1063 Call::PossiblyEval possibly_eval); 1064 V8_INLINE PreParserExpression 1065 SpreadCallNew(const PreParserExpression& function, 1066 const PreParserExpressionList& args, int pos); 1067 1068 V8_INLINE void RewriteDestructuringAssignments() {} 1069 1070 V8_INLINE void PrepareGeneratorVariables() {} 1071 V8_INLINE void RewriteAsyncFunctionBody( 1072 PreParserStatementList body, PreParserStatement block, 1073 const PreParserExpression& return_value, bool* ok) {} 1074 1075 void DeclareAndInitializeVariables( 1076 PreParserStatement block, 1077 const DeclarationDescriptor* declaration_descriptor, 1078 const DeclarationParsingResult::Declaration* declaration, 1079 ZonePtrList<const AstRawString>* names, bool* ok); 1080 1081 V8_INLINE void DeclareLabel(ZonePtrList<const AstRawString>** labels, 1082 ZonePtrList<const AstRawString>** own_labels, 1083 const PreParserExpression& expr, bool* ok) { 1084 DCHECK(!parsing_module_ || !expr.AsIdentifier().IsAwait()); 1085 DCHECK(IsIdentifier(expr)); 1086 } 1087 1088 // TODO(nikolaos): The preparser currently does not keep track of labels. 1089 V8_INLINE bool ContainsLabel(ZonePtrList<const AstRawString>* labels, 1090 const PreParserIdentifier& label) { 1091 return false; 1092 } 1093 1094 V8_INLINE PreParserExpression 1095 RewriteReturn(const PreParserExpression& return_value, int pos) { 1096 return return_value; 1097 } 1098 V8_INLINE PreParserStatement 1099 RewriteSwitchStatement(PreParserStatement switch_statement, Scope* scope) { 1100 return PreParserStatement::Default(); 1101 } 1102 1103 V8_INLINE void RewriteCatchPattern(CatchInfo* catch_info, bool* ok) { 1104 if (track_unresolved_variables_) { 1105 const AstRawString* catch_name = catch_info->name.string_; 1106 if (catch_name == nullptr) { 1107 catch_name = ast_value_factory()->dot_catch_string(); 1108 } 1109 catch_info->scope->DeclareCatchVariableName(catch_name); 1110 1111 if (catch_info->pattern.variables_ != nullptr) { 1112 for (auto variable : *catch_info->pattern.variables_) { 1113 scope()->DeclareVariableName(variable->raw_name(), 1114 VariableMode::kLet); 1115 } 1116 } 1117 } 1118 } 1119 1120 V8_INLINE void ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {} 1121 V8_INLINE PreParserStatement RewriteTryStatement( 1122 PreParserStatement try_block, PreParserStatement catch_block, 1123 const SourceRange& catch_range, PreParserStatement finally_block, 1124 const SourceRange& finally_range, const CatchInfo& catch_info, int pos) { 1125 return PreParserStatement::Default(); 1126 } 1127 1128 V8_INLINE void ParseAndRewriteGeneratorFunctionBody( 1129 int pos, FunctionKind kind, PreParserStatementList body, bool* ok) { 1130 ParseStatementList(body, Token::RBRACE, ok); 1131 } 1132 V8_INLINE void ParseAndRewriteAsyncGeneratorFunctionBody( 1133 int pos, FunctionKind kind, PreParserStatementList body, bool* ok) { 1134 ParseStatementList(body, Token::RBRACE, ok); 1135 } 1136 V8_INLINE void DeclareFunctionNameVar( 1137 const AstRawString* function_name, 1138 FunctionLiteral::FunctionType function_type, 1139 DeclarationScope* function_scope) { 1140 if (track_unresolved_variables_ && 1141 function_type == FunctionLiteral::kNamedExpression && 1142 function_scope->LookupLocal(function_name) == nullptr) { 1143 DCHECK_EQ(function_scope, scope()); 1144 function_scope->DeclareFunctionVar(function_name); 1145 } 1146 } 1147 1148 V8_INLINE void DeclareFunctionNameVar( 1149 const PreParserIdentifier& function_name, 1150 FunctionLiteral::FunctionType function_type, 1151 DeclarationScope* function_scope) { 1152 DeclareFunctionNameVar(function_name.string_, function_type, 1153 function_scope); 1154 } 1155 1156 V8_INLINE PreParserExpression RewriteDoExpression(PreParserStatement body, 1157 int pos, bool* ok) { 1158 return PreParserExpression::Default(); 1159 } 1160 1161 // TODO(nikolaos): The preparser currently does not keep track of labels 1162 // and targets. 1163 V8_INLINE PreParserStatement 1164 LookupBreakTarget(const PreParserIdentifier& label, bool* ok) { 1165 return PreParserStatement::Default(); 1166 } 1167 V8_INLINE PreParserStatement 1168 LookupContinueTarget(const PreParserIdentifier& label, bool* ok) { 1169 return PreParserStatement::Default(); 1170 } 1171 1172 V8_INLINE PreParserStatement 1173 DeclareFunction(const PreParserIdentifier& variable_name, 1174 const PreParserExpression& function, VariableMode mode, 1175 int pos, bool is_sloppy_block_function, 1176 ZonePtrList<const AstRawString>* names, bool* ok) { 1177 DCHECK_NULL(names); 1178 if (variable_name.string_ != nullptr) { 1179 DCHECK(track_unresolved_variables_); 1180 scope()->DeclareVariableName(variable_name.string_, mode); 1181 if (is_sloppy_block_function) { 1182 GetDeclarationScope()->DeclareSloppyBlockFunction(variable_name.string_, 1183 scope()); 1184 } 1185 } 1186 return Statement::Default(); 1187 } 1188 1189 V8_INLINE PreParserStatement DeclareClass( 1190 const PreParserIdentifier& variable_name, 1191 const PreParserExpression& value, ZonePtrList<const AstRawString>* names, 1192 int class_token_pos, int end_pos, bool* ok) { 1193 // Preparser shouldn't be used in contexts where we need to track the names. 1194 DCHECK_NULL(names); 1195 if (variable_name.string_ != nullptr) { 1196 DCHECK(track_unresolved_variables_); 1197 scope()->DeclareVariableName(variable_name.string_, VariableMode::kLet); 1198 } 1199 return PreParserStatement::Default(); 1200 } 1201 V8_INLINE void DeclareClassVariable(const PreParserIdentifier& name, 1202 ClassInfo* class_info, 1203 int class_token_pos, bool* ok) { 1204 if (name.string_ != nullptr) { 1205 DCHECK(track_unresolved_variables_); 1206 scope()->DeclareVariableName(name.string_, VariableMode::kConst); 1207 } 1208 } 1209 V8_INLINE void DeclareClassProperty(const PreParserIdentifier& class_name, 1210 const PreParserExpression& property, 1211 const PreParserIdentifier& property_name, 1212 ClassLiteralProperty::Kind kind, 1213 bool is_static, bool is_constructor, 1214 bool is_computed_name, 1215 ClassInfo* class_info, bool* ok) { 1216 if (kind == ClassLiteralProperty::PUBLIC_FIELD && is_computed_name) { 1217 scope()->DeclareVariableName( 1218 ClassFieldVariableName(ast_value_factory(), 1219 class_info->computed_field_count), 1220 VariableMode::kConst); 1221 } 1222 1223 if (kind == ClassLiteralProperty::PRIVATE_FIELD && 1224 property_name.string_ != nullptr) { 1225 DCHECK(track_unresolved_variables_); 1226 scope()->DeclareVariableName(property_name.string_, VariableMode::kConst); 1227 } 1228 } 1229 1230 V8_INLINE PreParserExpression 1231 RewriteClassLiteral(Scope* scope, const PreParserIdentifier& name, 1232 ClassInfo* class_info, int pos, int end_pos, bool* ok) { 1233 bool has_default_constructor = !class_info->has_seen_constructor; 1234 // Account for the default constructor. 1235 if (has_default_constructor) { 1236 // Creating and disposing of a FunctionState makes tracking of 1237 // next_function_is_likely_called match what Parser does. TODO(marja): 1238 // Make the lazy function + next_function_is_likely_called + default ctor 1239 // logic less surprising. Default ctors shouldn't affect the laziness of 1240 // functions. 1241 bool has_extends = class_info->extends.IsNull(); 1242 FunctionKind kind = has_extends ? FunctionKind::kDefaultDerivedConstructor 1243 : FunctionKind::kDefaultBaseConstructor; 1244 DeclarationScope* function_scope = NewFunctionScope(kind); 1245 SetLanguageMode(function_scope, LanguageMode::kStrict); 1246 function_scope->set_start_position(pos); 1247 function_scope->set_end_position(pos); 1248 FunctionState function_state(&function_state_, &scope_, function_scope); 1249 GetNextFunctionLiteralId(); 1250 } 1251 if (class_info->has_static_class_fields) { 1252 GetNextFunctionLiteralId(); 1253 } 1254 if (class_info->has_instance_class_fields) { 1255 GetNextFunctionLiteralId(); 1256 } 1257 return PreParserExpression::Default(); 1258 } 1259 1260 V8_INLINE PreParserStatement DeclareNative(const PreParserIdentifier& name, 1261 int pos, bool* ok) { 1262 return PreParserStatement::Default(); 1263 } 1264 1265 V8_INLINE void QueueDestructuringAssignmentForRewriting( 1266 PreParserExpression assignment) {} 1267 1268 // Helper functions for recursive descent. 1269 V8_INLINE bool IsEval(const PreParserIdentifier& identifier) const { 1270 return identifier.IsEval(); 1271 } 1272 1273 V8_INLINE bool IsArguments(const PreParserIdentifier& identifier) const { 1274 return identifier.IsArguments(); 1275 } 1276 1277 V8_INLINE bool IsEvalOrArguments( 1278 const PreParserIdentifier& identifier) const { 1279 return identifier.IsEvalOrArguments(); 1280 } 1281 1282 V8_INLINE bool IsAwait(const PreParserIdentifier& identifier) const { 1283 return identifier.IsAwait(); 1284 } 1285 1286 // Returns true if the expression is of type "this.foo". 1287 V8_INLINE static bool IsThisProperty(const PreParserExpression& expression) { 1288 return expression.IsThisProperty(); 1289 } 1290 1291 V8_INLINE static bool IsIdentifier(const PreParserExpression& expression) { 1292 return expression.IsIdentifier(); 1293 } 1294 1295 V8_INLINE static PreParserIdentifier AsIdentifier( 1296 const PreParserExpression& expression) { 1297 return expression.AsIdentifier(); 1298 } 1299 1300 V8_INLINE static PreParserExpression AsIdentifierExpression( 1301 const PreParserExpression& expression) { 1302 return expression; 1303 } 1304 1305 V8_INLINE bool IsConstructor(const PreParserIdentifier& identifier) const { 1306 return identifier.IsConstructor(); 1307 } 1308 1309 V8_INLINE bool IsName(const PreParserIdentifier& identifier) const { 1310 return identifier.IsName(); 1311 } 1312 1313 V8_INLINE static bool IsBoilerplateProperty( 1314 const PreParserExpression& property) { 1315 // PreParser doesn't count boilerplate properties. 1316 return false; 1317 } 1318 1319 V8_INLINE bool IsNative(const PreParserExpression& expr) const { 1320 // Preparsing is disabled for extensions (because the extension 1321 // details aren't passed to lazily compiled functions), so we 1322 // don't accept "native function" in the preparser and there is 1323 // no need to keep track of "native". 1324 return false; 1325 } 1326 1327 V8_INLINE static bool IsArrayIndex(const PreParserIdentifier& string, 1328 uint32_t* index) { 1329 return false; 1330 } 1331 1332 V8_INLINE bool IsUseStrictDirective(PreParserStatement statement) const { 1333 return statement.IsUseStrictLiteral(); 1334 } 1335 1336 V8_INLINE bool IsUseAsmDirective(PreParserStatement statement) const { 1337 return statement.IsUseAsmLiteral(); 1338 } 1339 1340 V8_INLINE bool IsStringLiteral(PreParserStatement statement) const { 1341 return statement.IsStringLiteral(); 1342 } 1343 1344 V8_INLINE static void GetDefaultStrings( 1345 PreParserIdentifier* default_string, 1346 PreParserIdentifier* star_default_star_string) {} 1347 1348 // Functions for encapsulating the differences between parsing and preparsing; 1349 // operations interleaved with the recursive descent. 1350 V8_INLINE static void PushLiteralName(const PreParserIdentifier& id) {} 1351 V8_INLINE static void PushVariableName(const PreParserIdentifier& id) {} 1352 V8_INLINE void PushPropertyName(const PreParserExpression& expression) {} 1353 V8_INLINE void PushEnclosingName(const PreParserIdentifier& name) {} 1354 V8_INLINE static void AddFunctionForNameInference( 1355 const PreParserExpression& expression) {} 1356 V8_INLINE static void InferFunctionName() {} 1357 1358 V8_INLINE static void CheckAssigningFunctionLiteralToProperty( 1359 const PreParserExpression& left, const PreParserExpression& right) {} 1360 1361 V8_INLINE void MarkExpressionAsAssigned( 1362 const PreParserExpression& expression) { 1363 // TODO(marja): To be able to produce the same errors, the preparser needs 1364 // to start tracking which expressions are variables and which are assigned. 1365 if (expression.variables_ != nullptr) { 1366 DCHECK(FLAG_lazy_inner_functions); 1367 DCHECK(track_unresolved_variables_); 1368 for (auto variable : *expression.variables_) { 1369 variable->set_is_assigned(); 1370 } 1371 } 1372 } 1373 1374 V8_INLINE bool ShortcutNumericLiteralBinaryExpression( 1375 PreParserExpression* x, const PreParserExpression& y, Token::Value op, 1376 int pos) { 1377 return false; 1378 } 1379 1380 V8_INLINE NaryOperation* CollapseNaryExpression(PreParserExpression* x, 1381 PreParserExpression y, 1382 Token::Value op, int pos, 1383 const SourceRange& range) { 1384 return nullptr; 1385 } 1386 1387 V8_INLINE PreParserExpression BuildUnaryExpression( 1388 const PreParserExpression& expression, Token::Value op, int pos) { 1389 return PreParserExpression::Default(); 1390 } 1391 1392 V8_INLINE PreParserStatement 1393 BuildInitializationBlock(DeclarationParsingResult* parsing_result, 1394 ZonePtrList<const AstRawString>* names, bool* ok) { 1395 for (auto declaration : parsing_result->declarations) { 1396 DeclareAndInitializeVariables(PreParserStatement::Default(), 1397 &(parsing_result->descriptor), &declaration, 1398 names, ok); 1399 } 1400 return PreParserStatement::Default(); 1401 } 1402 1403 V8_INLINE PreParserStatement InitializeForEachStatement( 1404 PreParserStatement stmt, const PreParserExpression& each, 1405 const PreParserExpression& subject, PreParserStatement body) { 1406 MarkExpressionAsAssigned(each); 1407 return stmt; 1408 } 1409 1410 V8_INLINE PreParserStatement InitializeForOfStatement( 1411 PreParserStatement stmt, const PreParserExpression& each, 1412 const PreParserExpression& iterable, PreParserStatement body, 1413 bool finalize, IteratorType type, 1414 int next_result_pos = kNoSourcePosition) { 1415 MarkExpressionAsAssigned(each); 1416 return stmt; 1417 } 1418 1419 V8_INLINE PreParserStatement RewriteForVarInLegacy(const ForInfo& for_info) { 1420 return PreParserStatement::Null(); 1421 } 1422 1423 V8_INLINE void DesugarBindingInForEachStatement( 1424 ForInfo* for_info, PreParserStatement* body_block, 1425 PreParserExpression* each_variable, bool* ok) { 1426 if (track_unresolved_variables_) { 1427 DCHECK_EQ(1, for_info->parsing_result.declarations.size()); 1428 bool is_for_var_of = 1429 for_info->mode == ForEachStatement::ITERATE && 1430 for_info->parsing_result.descriptor.mode == VariableMode::kVar; 1431 bool collect_names = 1432 IsLexicalVariableMode(for_info->parsing_result.descriptor.mode) || 1433 is_for_var_of; 1434 1435 DeclareAndInitializeVariables( 1436 PreParserStatement::Default(), &for_info->parsing_result.descriptor, 1437 &for_info->parsing_result.declarations[0], 1438 collect_names ? &for_info->bound_names : nullptr, ok); 1439 } 1440 } 1441 1442 V8_INLINE PreParserStatement CreateForEachStatementTDZ( 1443 PreParserStatement init_block, const ForInfo& for_info, bool* ok) { 1444 if (track_unresolved_variables_) { 1445 if (IsLexicalVariableMode(for_info.parsing_result.descriptor.mode)) { 1446 for (auto name : for_info.bound_names) { 1447 scope()->DeclareVariableName(name, VariableMode::kLet); 1448 } 1449 return PreParserStatement::Default(); 1450 } 1451 } 1452 return init_block; 1453 } 1454 1455 V8_INLINE StatementT DesugarLexicalBindingsInForStatement( 1456 PreParserStatement loop, PreParserStatement init, 1457 const PreParserExpression& cond, PreParserStatement next, 1458 PreParserStatement body, Scope* inner_scope, const ForInfo& for_info, 1459 bool* ok) { 1460 // See Parser::DesugarLexicalBindingsInForStatement. 1461 if (track_unresolved_variables_) { 1462 for (auto name : for_info.bound_names) { 1463 inner_scope->DeclareVariableName( 1464 name, for_info.parsing_result.descriptor.mode); 1465 } 1466 } 1467 return loop; 1468 } 1469 1470 PreParserStatement BuildParameterInitializationBlock( 1471 const PreParserFormalParameters& parameters, bool* ok); 1472 1473 V8_INLINE PreParserStatement 1474 BuildRejectPromiseOnException(PreParserStatement init_block) { 1475 return PreParserStatement::Default(); 1476 } 1477 1478 V8_INLINE void InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope) { 1479 scope->HoistSloppyBlockFunctions(nullptr); 1480 } 1481 1482 V8_INLINE void InsertShadowingVarBindingInitializers( 1483 PreParserStatement block) {} 1484 1485 V8_INLINE PreParserExpression 1486 NewThrowReferenceError(MessageTemplate::Template message, int pos) { 1487 return PreParserExpression::Default(); 1488 } 1489 1490 V8_INLINE PreParserExpression 1491 NewThrowSyntaxError(MessageTemplate::Template message, 1492 const PreParserIdentifier& arg, int pos) { 1493 return PreParserExpression::Default(); 1494 } 1495 1496 V8_INLINE PreParserExpression 1497 NewThrowTypeError(MessageTemplate::Template message, 1498 const PreParserIdentifier& arg, int pos) { 1499 return PreParserExpression::Default(); 1500 } 1501 1502 // Reporting errors. 1503 void ReportMessageAt(Scanner::Location source_location, 1504 MessageTemplate::Template message, 1505 const char* arg = nullptr, 1506 ParseErrorType error_type = kSyntaxError) { 1507 pending_error_handler()->ReportMessageAt(source_location.beg_pos, 1508 source_location.end_pos, message, 1509 arg, error_type); 1510 } 1511 1512 V8_INLINE void ReportMessageAt(Scanner::Location source_location, 1513 MessageTemplate::Template message, 1514 const PreParserIdentifier& arg, 1515 ParseErrorType error_type = kSyntaxError) { 1516 UNREACHABLE(); 1517 } 1518 1519 // "null" return type creators. 1520 V8_INLINE static PreParserIdentifier NullIdentifier() { 1521 return PreParserIdentifier::Null(); 1522 } 1523 V8_INLINE static PreParserExpression NullExpression() { 1524 return PreParserExpression::Null(); 1525 } 1526 V8_INLINE static PreParserExpression NullLiteralProperty() { 1527 return PreParserExpression::Null(); 1528 } 1529 V8_INLINE static PreParserExpressionList NullExpressionList() { 1530 return PreParserExpressionList::Null(); 1531 } 1532 1533 V8_INLINE static PreParserStatementList NullStatementList() { 1534 return PreParserStatementList::Null(); 1535 } 1536 V8_INLINE static PreParserStatement NullStatement() { 1537 return PreParserStatement::Null(); 1538 } 1539 1540 template <typename T> 1541 V8_INLINE static bool IsNull(T subject) { 1542 return subject.IsNull(); 1543 } 1544 1545 V8_INLINE PreParserIdentifier EmptyIdentifierString() const { 1546 return PreParserIdentifier::Default(); 1547 } 1548 1549 // Producing data during the recursive descent. 1550 PreParserIdentifier GetSymbol() const; 1551 1552 V8_INLINE PreParserIdentifier GetNextSymbol() const { 1553 return PreParserIdentifier::Default(); 1554 } 1555 1556 V8_INLINE PreParserIdentifier GetNumberAsSymbol() const { 1557 return PreParserIdentifier::Default(); 1558 } 1559 1560 V8_INLINE PreParserExpression ThisExpression(int pos = kNoSourcePosition) { 1561 ZonePtrList<VariableProxy>* variables = nullptr; 1562 if (track_unresolved_variables_) { 1563 VariableProxy* proxy = scope()->NewUnresolved( 1564 factory()->ast_node_factory(), ast_value_factory()->this_string(), 1565 pos, THIS_VARIABLE); 1566 1567 variables = new (zone()) ZonePtrList<VariableProxy>(1, zone()); 1568 variables->Add(proxy, zone()); 1569 } 1570 return PreParserExpression::This(variables); 1571 } 1572 1573 V8_INLINE PreParserExpression NewSuperPropertyReference(int pos) { 1574 if (track_unresolved_variables_) { 1575 scope()->NewUnresolved(factory()->ast_node_factory(), 1576 ast_value_factory()->this_function_string(), pos, 1577 NORMAL_VARIABLE); 1578 scope()->NewUnresolved(factory()->ast_node_factory(), 1579 ast_value_factory()->this_string(), pos, 1580 THIS_VARIABLE); 1581 } 1582 return PreParserExpression::Default(); 1583 } 1584 1585 V8_INLINE PreParserExpression NewSuperCallReference(int pos) { 1586 if (track_unresolved_variables_) { 1587 scope()->NewUnresolved(factory()->ast_node_factory(), 1588 ast_value_factory()->this_function_string(), pos, 1589 NORMAL_VARIABLE); 1590 scope()->NewUnresolved(factory()->ast_node_factory(), 1591 ast_value_factory()->new_target_string(), pos, 1592 NORMAL_VARIABLE); 1593 scope()->NewUnresolved(factory()->ast_node_factory(), 1594 ast_value_factory()->this_string(), pos, 1595 THIS_VARIABLE); 1596 } 1597 return PreParserExpression::SuperCallReference(); 1598 } 1599 1600 V8_INLINE PreParserExpression NewTargetExpression(int pos) { 1601 return PreParserExpression::NewTargetExpression(); 1602 } 1603 1604 V8_INLINE PreParserExpression ImportMetaExpression(int pos) { 1605 return PreParserExpression::Default(); 1606 } 1607 1608 V8_INLINE PreParserExpression ExpressionFromLiteral(Token::Value token, 1609 int pos) { 1610 return PreParserExpression::Default(); 1611 } 1612 1613 PreParserExpression ExpressionFromIdentifier( 1614 const PreParserIdentifier& name, int start_position, 1615 InferName infer = InferName::kYes); 1616 1617 V8_INLINE PreParserExpression ExpressionFromString(int pos) { 1618 if (scanner()->IsUseStrict()) { 1619 return PreParserExpression::UseStrictStringLiteral(); 1620 } 1621 return PreParserExpression::StringLiteral(); 1622 } 1623 1624 V8_INLINE PreParserExpressionList NewExpressionList(int size) const { 1625 return PreParserExpressionList(); 1626 } 1627 1628 V8_INLINE PreParserExpressionList NewObjectPropertyList(int size) const { 1629 return PreParserExpressionList(); 1630 } 1631 1632 V8_INLINE PreParserExpressionList NewClassPropertyList(int size) const { 1633 return PreParserExpressionList(); 1634 } 1635 1636 V8_INLINE PreParserStatementList NewStatementList(int size) const { 1637 return PreParserStatementList(); 1638 } 1639 1640 V8_INLINE PreParserExpression 1641 NewV8Intrinsic(const PreParserIdentifier& name, 1642 const PreParserExpressionList& arguments, int pos, bool* ok) { 1643 return PreParserExpression::Default(); 1644 } 1645 1646 V8_INLINE PreParserStatement 1647 NewThrowStatement(const PreParserExpression& exception, int pos) { 1648 return PreParserStatement::Jump(); 1649 } 1650 1651 V8_INLINE void AddParameterInitializationBlock( 1652 const PreParserFormalParameters& parameters, PreParserStatementList body, 1653 bool is_async, bool* ok) { 1654 if (!parameters.is_simple) { 1655 BuildParameterInitializationBlock(parameters, ok); 1656 } 1657 } 1658 1659 V8_INLINE void AddFormalParameter(PreParserFormalParameters* parameters, 1660 const PreParserExpression& pattern, 1661 const PreParserExpression& initializer, 1662 int initializer_end_position, 1663 bool is_rest) { 1664 if (track_unresolved_variables_) { 1665 DCHECK(FLAG_lazy_inner_functions); 1666 parameters->params.Add(new (zone()) PreParserFormalParameters::Parameter( 1667 pattern.variables_, is_rest)); 1668 } 1669 parameters->UpdateArityAndFunctionLength(!initializer.IsNull(), is_rest); 1670 } 1671 1672 V8_INLINE void DeclareFormalParameters( 1673 DeclarationScope* scope, 1674 const ThreadedList<PreParserFormalParameters::Parameter>& parameters, 1675 bool is_simple) { 1676 if (!is_simple) scope->SetHasNonSimpleParameters(); 1677 if (track_unresolved_variables_) { 1678 DCHECK(FLAG_lazy_inner_functions); 1679 for (auto parameter : parameters) { 1680 DCHECK_IMPLIES(is_simple, parameter->variables_ != nullptr); 1681 DCHECK_IMPLIES(is_simple, parameter->variables_->length() == 1); 1682 // Make sure each parameter is added only once even if it's a 1683 // destructuring parameter which contains multiple names. 1684 bool add_parameter = true; 1685 if (parameter->variables_ != nullptr) { 1686 for (auto variable : (*parameter->variables_)) { 1687 // We declare the parameter name for all names, but only create a 1688 // parameter entry for the first one. 1689 scope->DeclareParameterName(variable->raw_name(), 1690 parameter->is_rest, ast_value_factory(), 1691 true, add_parameter); 1692 add_parameter = false; 1693 } 1694 } 1695 if (add_parameter) { 1696 // No names were declared; declare a dummy one here to up the 1697 // parameter count. 1698 DCHECK(!is_simple); 1699 scope->DeclareParameterName(ast_value_factory()->empty_string(), 1700 parameter->is_rest, ast_value_factory(), 1701 false, add_parameter); 1702 } 1703 } 1704 } 1705 } 1706 1707 V8_INLINE void DeclareArrowFunctionFormalParameters( 1708 PreParserFormalParameters* parameters, const PreParserExpression& params, 1709 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, 1710 bool* ok) { 1711 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect 1712 // parameter lists that are too long. 1713 if (track_unresolved_variables_) { 1714 DCHECK(FLAG_lazy_inner_functions); 1715 if (params.variables_ != nullptr) { 1716 for (auto variable : *params.variables_) { 1717 parameters->scope->DeclareVariableName(variable->raw_name(), 1718 VariableMode::kVar); 1719 } 1720 } 1721 } 1722 } 1723 1724 V8_INLINE PreParserExpression 1725 ExpressionListToExpression(const PreParserExpressionList& args) { 1726 return PreParserExpression::Default(args.variables_); 1727 } 1728 1729 V8_INLINE void SetFunctionNameFromPropertyName( 1730 const PreParserExpression& property, const PreParserIdentifier& name, 1731 const AstRawString* prefix = nullptr) {} 1732 V8_INLINE void SetFunctionNameFromIdentifierRef( 1733 const PreParserExpression& value, const PreParserExpression& identifier) { 1734 } 1735 1736 V8_INLINE ZoneVector<typename ExpressionClassifier::Error>* 1737 GetReportedErrorList() const { 1738 return function_state_->GetReportedErrorList(); 1739 } 1740 1741 V8_INLINE void CountUsage(v8::Isolate::UseCounterFeature feature) { 1742 if (use_counts_ != nullptr) ++use_counts_[feature]; 1743 } 1744 1745 V8_INLINE bool ParsingDynamicFunctionDeclaration() const { return false; } 1746 1747 // Generate empty functions here as the preparser does not collect source 1748 // ranges for block coverage. 1749 #define DEFINE_RECORD_SOURCE_RANGE(Name) \ 1750 template <typename... Ts> \ 1751 V8_INLINE void Record##Name##SourceRange(Ts... args) {} 1752 AST_SOURCE_RANGE_LIST(DEFINE_RECORD_SOURCE_RANGE) 1753 #undef DEFINE_RECORD_SOURCE_RANGE 1754 1755 // Preparser's private field members. 1756 1757 int* use_counts_; 1758 bool track_unresolved_variables_; 1759 PreParserLogger log_; 1760 1761 ProducedPreParsedScopeData* produced_preparsed_scope_data_; 1762 }; 1763 1764 PreParserExpression PreParser::SpreadCall(const PreParserExpression& function, 1765 const PreParserExpressionList& args, 1766 int pos, 1767 Call::PossiblyEval possibly_eval) { 1768 return factory()->NewCall(function, args, pos, possibly_eval); 1769 } 1770 1771 PreParserExpression PreParser::SpreadCallNew( 1772 const PreParserExpression& function, const PreParserExpressionList& args, 1773 int pos) { 1774 return factory()->NewCallNew(function, args, pos); 1775 } 1776 1777 } // namespace internal 1778 } // namespace v8 1779 1780 #endif // V8_PARSING_PREPARSER_H_ 1781