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/scopes.h" 9 #include "src/bailout-reason.h" 10 #include "src/base/hashmap.h" 11 #include "src/messages.h" 12 #include "src/parsing/expression-classifier.h" 13 #include "src/parsing/func-name-inferrer.h" 14 #include "src/parsing/parser-base.h" 15 #include "src/parsing/scanner.h" 16 #include "src/parsing/token.h" 17 18 namespace v8 { 19 namespace internal { 20 21 22 class PreParserIdentifier { 23 public: 24 PreParserIdentifier() : type_(kUnknownIdentifier) {} 25 static PreParserIdentifier Default() { 26 return PreParserIdentifier(kUnknownIdentifier); 27 } 28 static PreParserIdentifier Eval() { 29 return PreParserIdentifier(kEvalIdentifier); 30 } 31 static PreParserIdentifier Arguments() { 32 return PreParserIdentifier(kArgumentsIdentifier); 33 } 34 static PreParserIdentifier Undefined() { 35 return PreParserIdentifier(kUndefinedIdentifier); 36 } 37 static PreParserIdentifier FutureReserved() { 38 return PreParserIdentifier(kFutureReservedIdentifier); 39 } 40 static PreParserIdentifier FutureStrictReserved() { 41 return PreParserIdentifier(kFutureStrictReservedIdentifier); 42 } 43 static PreParserIdentifier Let() { 44 return PreParserIdentifier(kLetIdentifier); 45 } 46 static PreParserIdentifier Static() { 47 return PreParserIdentifier(kStaticIdentifier); 48 } 49 static PreParserIdentifier Yield() { 50 return PreParserIdentifier(kYieldIdentifier); 51 } 52 static PreParserIdentifier Prototype() { 53 return PreParserIdentifier(kPrototypeIdentifier); 54 } 55 static PreParserIdentifier Constructor() { 56 return PreParserIdentifier(kConstructorIdentifier); 57 } 58 static PreParserIdentifier Enum() { 59 return PreParserIdentifier(kEnumIdentifier); 60 } 61 static PreParserIdentifier Await() { 62 return PreParserIdentifier(kAwaitIdentifier); 63 } 64 static PreParserIdentifier Async() { 65 return PreParserIdentifier(kAsyncIdentifier); 66 } 67 bool IsEval() const { return type_ == kEvalIdentifier; } 68 bool IsArguments() const { return type_ == kArgumentsIdentifier; } 69 bool IsEvalOrArguments() const { return IsEval() || IsArguments(); } 70 bool IsUndefined() const { return type_ == kUndefinedIdentifier; } 71 bool IsLet() const { return type_ == kLetIdentifier; } 72 bool IsStatic() const { return type_ == kStaticIdentifier; } 73 bool IsYield() const { return type_ == kYieldIdentifier; } 74 bool IsPrototype() const { return type_ == kPrototypeIdentifier; } 75 bool IsConstructor() const { return type_ == kConstructorIdentifier; } 76 bool IsEnum() const { return type_ == kEnumIdentifier; } 77 bool IsAwait() const { return type_ == kAwaitIdentifier; } 78 bool IsAsync() const { return type_ == kAsyncIdentifier; } 79 bool IsFutureStrictReserved() const { 80 return type_ == kFutureStrictReservedIdentifier || 81 type_ == kLetIdentifier || type_ == kStaticIdentifier || 82 type_ == kYieldIdentifier; 83 } 84 85 // Allow identifier->name()[->length()] to work. The preparser 86 // does not need the actual positions/lengths of the identifiers. 87 const PreParserIdentifier* operator->() const { return this; } 88 const PreParserIdentifier raw_name() const { return *this; } 89 90 int position() const { return 0; } 91 int length() const { return 0; } 92 93 private: 94 enum Type { 95 kUnknownIdentifier, 96 kFutureReservedIdentifier, 97 kFutureStrictReservedIdentifier, 98 kLetIdentifier, 99 kStaticIdentifier, 100 kYieldIdentifier, 101 kEvalIdentifier, 102 kArgumentsIdentifier, 103 kUndefinedIdentifier, 104 kPrototypeIdentifier, 105 kConstructorIdentifier, 106 kEnumIdentifier, 107 kAwaitIdentifier, 108 kAsyncIdentifier 109 }; 110 111 explicit PreParserIdentifier(Type type) : type_(type) {} 112 Type type_; 113 114 friend class PreParserExpression; 115 }; 116 117 118 class PreParserExpression { 119 public: 120 static PreParserExpression Default() { 121 return PreParserExpression(TypeField::encode(kExpression)); 122 } 123 124 static PreParserExpression Spread(PreParserExpression expression) { 125 return PreParserExpression(TypeField::encode(kSpreadExpression)); 126 } 127 128 static PreParserExpression FromIdentifier(PreParserIdentifier id) { 129 return PreParserExpression(TypeField::encode(kIdentifierExpression) | 130 IdentifierTypeField::encode(id.type_)); 131 } 132 133 static PreParserExpression BinaryOperation(PreParserExpression left, 134 Token::Value op, 135 PreParserExpression right) { 136 return PreParserExpression(TypeField::encode(kBinaryOperationExpression)); 137 } 138 139 static PreParserExpression Assignment() { 140 return PreParserExpression(TypeField::encode(kExpression) | 141 ExpressionTypeField::encode(kAssignment)); 142 } 143 144 static PreParserExpression ObjectLiteral() { 145 return PreParserExpression(TypeField::encode(kObjectLiteralExpression)); 146 } 147 148 static PreParserExpression ArrayLiteral() { 149 return PreParserExpression(TypeField::encode(kArrayLiteralExpression)); 150 } 151 152 static PreParserExpression StringLiteral() { 153 return PreParserExpression(TypeField::encode(kStringLiteralExpression)); 154 } 155 156 static PreParserExpression UseStrictStringLiteral() { 157 return PreParserExpression(TypeField::encode(kStringLiteralExpression) | 158 IsUseStrictField::encode(true)); 159 } 160 161 static PreParserExpression This() { 162 return PreParserExpression(TypeField::encode(kExpression) | 163 ExpressionTypeField::encode(kThisExpression)); 164 } 165 166 static PreParserExpression ThisProperty() { 167 return PreParserExpression( 168 TypeField::encode(kExpression) | 169 ExpressionTypeField::encode(kThisPropertyExpression)); 170 } 171 172 static PreParserExpression Property() { 173 return PreParserExpression( 174 TypeField::encode(kExpression) | 175 ExpressionTypeField::encode(kPropertyExpression)); 176 } 177 178 static PreParserExpression Call() { 179 return PreParserExpression(TypeField::encode(kExpression) | 180 ExpressionTypeField::encode(kCallExpression)); 181 } 182 183 static PreParserExpression CallEval() { 184 return PreParserExpression( 185 TypeField::encode(kExpression) | 186 ExpressionTypeField::encode(kCallEvalExpression)); 187 } 188 189 static PreParserExpression SuperCallReference() { 190 return PreParserExpression( 191 TypeField::encode(kExpression) | 192 ExpressionTypeField::encode(kSuperCallReference)); 193 } 194 195 static PreParserExpression NoTemplateTag() { 196 return PreParserExpression( 197 TypeField::encode(kExpression) | 198 ExpressionTypeField::encode(kNoTemplateTagExpression)); 199 } 200 201 bool IsIdentifier() const { 202 return TypeField::decode(code_) == kIdentifierExpression; 203 } 204 205 PreParserIdentifier AsIdentifier() const { 206 DCHECK(IsIdentifier()); 207 return PreParserIdentifier(IdentifierTypeField::decode(code_)); 208 } 209 210 bool IsAssignment() const { 211 return TypeField::decode(code_) == kExpression && 212 ExpressionTypeField::decode(code_) == kAssignment; 213 } 214 215 bool IsObjectLiteral() const { 216 return TypeField::decode(code_) == kObjectLiteralExpression; 217 } 218 219 bool IsArrayLiteral() const { 220 return TypeField::decode(code_) == kArrayLiteralExpression; 221 } 222 223 bool IsStringLiteral() const { 224 return TypeField::decode(code_) == kStringLiteralExpression; 225 } 226 227 bool IsUseStrictLiteral() const { 228 return TypeField::decode(code_) == kStringLiteralExpression && 229 IsUseStrictField::decode(code_); 230 } 231 232 bool IsThis() const { 233 return TypeField::decode(code_) == kExpression && 234 ExpressionTypeField::decode(code_) == kThisExpression; 235 } 236 237 bool IsThisProperty() const { 238 return TypeField::decode(code_) == kExpression && 239 ExpressionTypeField::decode(code_) == kThisPropertyExpression; 240 } 241 242 bool IsProperty() const { 243 return TypeField::decode(code_) == kExpression && 244 (ExpressionTypeField::decode(code_) == kPropertyExpression || 245 ExpressionTypeField::decode(code_) == kThisPropertyExpression); 246 } 247 248 bool IsCall() const { 249 return TypeField::decode(code_) == kExpression && 250 (ExpressionTypeField::decode(code_) == kCallExpression || 251 ExpressionTypeField::decode(code_) == kCallEvalExpression); 252 } 253 254 bool IsDirectEvalCall() const { 255 return TypeField::decode(code_) == kExpression && 256 ExpressionTypeField::decode(code_) == kCallEvalExpression; 257 } 258 259 bool IsSuperCallReference() const { 260 return TypeField::decode(code_) == kExpression && 261 ExpressionTypeField::decode(code_) == kSuperCallReference; 262 } 263 264 bool IsValidReferenceExpression() const { 265 return IsIdentifier() || IsProperty(); 266 } 267 268 // At the moment PreParser doesn't track these expression types. 269 bool IsFunctionLiteral() const { return false; } 270 bool IsCallNew() const { return false; } 271 272 bool IsNoTemplateTag() const { 273 return TypeField::decode(code_) == kExpression && 274 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; 275 } 276 277 bool IsSpreadExpression() const { 278 return TypeField::decode(code_) == kSpreadExpression; 279 } 280 281 PreParserExpression AsFunctionLiteral() { return *this; } 282 283 bool IsBinaryOperation() const { 284 return TypeField::decode(code_) == kBinaryOperationExpression; 285 } 286 287 // Dummy implementation for making expression->somefunc() work in both Parser 288 // and PreParser. 289 PreParserExpression* operator->() { return this; } 290 291 // More dummy implementations of things PreParser doesn't need to track: 292 void set_index(int index) {} // For YieldExpressions 293 void set_should_eager_compile() {} 294 295 int position() const { return RelocInfo::kNoPosition; } 296 void set_function_token_position(int position) {} 297 298 private: 299 enum Type { 300 kExpression, 301 kIdentifierExpression, 302 kStringLiteralExpression, 303 kBinaryOperationExpression, 304 kSpreadExpression, 305 kObjectLiteralExpression, 306 kArrayLiteralExpression 307 }; 308 309 enum ExpressionType { 310 kThisExpression, 311 kThisPropertyExpression, 312 kPropertyExpression, 313 kCallExpression, 314 kCallEvalExpression, 315 kSuperCallReference, 316 kNoTemplateTagExpression, 317 kAssignment 318 }; 319 320 explicit PreParserExpression(uint32_t expression_code) 321 : code_(expression_code) {} 322 323 // The first three bits are for the Type. 324 typedef BitField<Type, 0, 3> TypeField; 325 326 // The high order bit applies only to nodes which would inherit from the 327 // Expression ASTNode --- This is by necessity, due to the fact that 328 // Expression nodes may be represented as multiple Types, not exclusively 329 // through kExpression. 330 // TODO(caitp, adamk): clean up PreParserExpression bitfields. 331 typedef BitField<bool, 31, 1> ParenthesizedField; 332 333 // The rest of the bits are interpreted depending on the value 334 // of the Type field, so they can share the storage. 335 typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField; 336 typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField; 337 typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10> 338 IdentifierTypeField; 339 typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField; 340 341 uint32_t code_; 342 }; 343 344 345 // The pre-parser doesn't need to build lists of expressions, identifiers, or 346 // the like. 347 template <typename T> 348 class PreParserList { 349 public: 350 // These functions make list->Add(some_expression) work (and do nothing). 351 PreParserList() : length_(0) {} 352 PreParserList* operator->() { return this; } 353 void Add(T, void*) { ++length_; } 354 int length() const { return length_; } 355 private: 356 int length_; 357 }; 358 359 360 typedef PreParserList<PreParserExpression> PreParserExpressionList; 361 362 363 class PreParserStatement { 364 public: 365 static PreParserStatement Default() { 366 return PreParserStatement(kUnknownStatement); 367 } 368 369 static PreParserStatement Jump() { 370 return PreParserStatement(kJumpStatement); 371 } 372 373 static PreParserStatement FunctionDeclaration() { 374 return PreParserStatement(kFunctionDeclaration); 375 } 376 377 // Creates expression statement from expression. 378 // Preserves being an unparenthesized string literal, possibly 379 // "use strict". 380 static PreParserStatement ExpressionStatement( 381 PreParserExpression expression) { 382 if (expression.IsUseStrictLiteral()) { 383 return PreParserStatement(kUseStrictExpressionStatement); 384 } 385 if (expression.IsStringLiteral()) { 386 return PreParserStatement(kStringLiteralExpressionStatement); 387 } 388 return Default(); 389 } 390 391 bool IsStringLiteral() { 392 return code_ == kStringLiteralExpressionStatement || IsUseStrictLiteral(); 393 } 394 395 bool IsUseStrictLiteral() { 396 return code_ == kUseStrictExpressionStatement; 397 } 398 399 bool IsFunctionDeclaration() { 400 return code_ == kFunctionDeclaration; 401 } 402 403 bool IsJumpStatement() { 404 return code_ == kJumpStatement; 405 } 406 407 private: 408 enum Type { 409 kUnknownStatement, 410 kJumpStatement, 411 kStringLiteralExpressionStatement, 412 kUseStrictExpressionStatement, 413 kFunctionDeclaration 414 }; 415 416 explicit PreParserStatement(Type code) : code_(code) {} 417 Type code_; 418 }; 419 420 421 typedef PreParserList<PreParserStatement> PreParserStatementList; 422 423 424 class PreParserFactory { 425 public: 426 explicit PreParserFactory(void* unused_value_factory) {} 427 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, 428 int pos) { 429 return PreParserExpression::Default(); 430 } 431 PreParserExpression NewNumberLiteral(double number, 432 int pos) { 433 return PreParserExpression::Default(); 434 } 435 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern, 436 int js_flags, int literal_index, 437 int pos) { 438 return PreParserExpression::Default(); 439 } 440 PreParserExpression NewArrayLiteral(PreParserExpressionList values, 441 int literal_index, 442 int pos) { 443 return PreParserExpression::ArrayLiteral(); 444 } 445 PreParserExpression NewArrayLiteral(PreParserExpressionList values, 446 int first_spread_index, int literal_index, 447 int pos) { 448 return PreParserExpression::ArrayLiteral(); 449 } 450 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, 451 PreParserExpression value, 452 ObjectLiteralProperty::Kind kind, 453 bool is_static, 454 bool is_computed_name) { 455 return PreParserExpression::Default(); 456 } 457 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, 458 PreParserExpression value, 459 bool is_static, 460 bool is_computed_name) { 461 return PreParserExpression::Default(); 462 } 463 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, 464 int literal_index, 465 int boilerplate_properties, 466 int pos) { 467 return PreParserExpression::ObjectLiteral(); 468 } 469 PreParserExpression NewVariableProxy(void* variable) { 470 return PreParserExpression::Default(); 471 } 472 PreParserExpression NewProperty(PreParserExpression obj, 473 PreParserExpression key, 474 int pos) { 475 if (obj.IsThis()) { 476 return PreParserExpression::ThisProperty(); 477 } 478 return PreParserExpression::Property(); 479 } 480 PreParserExpression NewUnaryOperation(Token::Value op, 481 PreParserExpression expression, 482 int pos) { 483 return PreParserExpression::Default(); 484 } 485 PreParserExpression NewBinaryOperation(Token::Value op, 486 PreParserExpression left, 487 PreParserExpression right, int pos) { 488 return PreParserExpression::BinaryOperation(left, op, right); 489 } 490 PreParserExpression NewCompareOperation(Token::Value op, 491 PreParserExpression left, 492 PreParserExpression right, int pos) { 493 return PreParserExpression::Default(); 494 } 495 PreParserExpression NewRewritableExpression(PreParserExpression expression) { 496 return expression; 497 } 498 PreParserExpression NewAssignment(Token::Value op, 499 PreParserExpression left, 500 PreParserExpression right, 501 int pos) { 502 return PreParserExpression::Assignment(); 503 } 504 PreParserExpression NewYield(PreParserExpression generator_object, 505 PreParserExpression expression, 506 int pos) { 507 return PreParserExpression::Default(); 508 } 509 PreParserExpression NewConditional(PreParserExpression condition, 510 PreParserExpression then_expression, 511 PreParserExpression else_expression, 512 int pos) { 513 return PreParserExpression::Default(); 514 } 515 PreParserExpression NewCountOperation(Token::Value op, 516 bool is_prefix, 517 PreParserExpression expression, 518 int pos) { 519 return PreParserExpression::Default(); 520 } 521 PreParserExpression NewCall(PreParserExpression expression, 522 PreParserExpressionList arguments, 523 int pos) { 524 if (expression.IsIdentifier() && expression.AsIdentifier().IsEval()) { 525 return PreParserExpression::CallEval(); 526 } 527 return PreParserExpression::Call(); 528 } 529 PreParserExpression NewCallNew(PreParserExpression expression, 530 PreParserExpressionList arguments, 531 int pos) { 532 return PreParserExpression::Default(); 533 } 534 PreParserExpression NewCallRuntime(const AstRawString* name, 535 const Runtime::Function* function, 536 PreParserExpressionList arguments, 537 int pos) { 538 return PreParserExpression::Default(); 539 } 540 PreParserStatement NewReturnStatement(PreParserExpression expression, 541 int pos) { 542 return PreParserStatement::Default(); 543 } 544 PreParserExpression NewFunctionLiteral( 545 PreParserIdentifier name, Scope* scope, PreParserStatementList body, 546 int materialized_literal_count, int expected_property_count, 547 int parameter_count, 548 FunctionLiteral::ParameterFlag has_duplicate_parameters, 549 FunctionLiteral::FunctionType function_type, 550 FunctionLiteral::EagerCompileHint eager_compile_hint, FunctionKind kind, 551 int position) { 552 return PreParserExpression::Default(); 553 } 554 555 PreParserExpression NewSpread(PreParserExpression expression, int pos, 556 int expr_pos) { 557 return PreParserExpression::Spread(expression); 558 } 559 560 PreParserExpression NewEmptyParentheses(int pos) { 561 return PreParserExpression::Default(); 562 } 563 564 // Return the object itself as AstVisitor and implement the needed 565 // dummy method right in this class. 566 PreParserFactory* visitor() { return this; } 567 int* ast_properties() { 568 static int dummy = 42; 569 return &dummy; 570 } 571 }; 572 573 574 struct PreParserFormalParameters : FormalParametersBase { 575 explicit PreParserFormalParameters(Scope* scope) 576 : FormalParametersBase(scope) {} 577 int arity = 0; 578 579 int Arity() const { return arity; } 580 PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy 581 }; 582 583 584 class PreParser; 585 586 class PreParserTraits { 587 public: 588 struct Type { 589 // TODO(marja): To be removed. The Traits object should contain all the data 590 // it needs. 591 typedef PreParser* Parser; 592 593 // PreParser doesn't need to store generator variables. 594 typedef void GeneratorVariable; 595 596 typedef int AstProperties; 597 598 typedef v8::internal::ExpressionClassifier<PreParserTraits> 599 ExpressionClassifier; 600 601 // Return types for traversing functions. 602 typedef PreParserIdentifier Identifier; 603 typedef PreParserExpression Expression; 604 typedef PreParserExpression YieldExpression; 605 typedef PreParserExpression FunctionLiteral; 606 typedef PreParserExpression ClassLiteral; 607 typedef PreParserExpression ObjectLiteralProperty; 608 typedef PreParserExpression Literal; 609 typedef PreParserExpressionList ExpressionList; 610 typedef PreParserExpressionList PropertyList; 611 typedef PreParserIdentifier FormalParameter; 612 typedef PreParserFormalParameters FormalParameters; 613 typedef PreParserStatementList StatementList; 614 615 // For constructing objects returned by the traversing functions. 616 typedef PreParserFactory Factory; 617 }; 618 619 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} 620 621 // Helper functions for recursive descent. 622 static bool IsEval(PreParserIdentifier identifier) { 623 return identifier.IsEval(); 624 } 625 626 static bool IsArguments(PreParserIdentifier identifier) { 627 return identifier.IsArguments(); 628 } 629 630 static bool IsAwait(PreParserIdentifier identifier) { 631 return identifier.IsAwait(); 632 } 633 634 static bool IsAsync(PreParserIdentifier identifier) { 635 return identifier.IsAsync(); 636 } 637 638 static bool IsEvalOrArguments(PreParserIdentifier identifier) { 639 return identifier.IsEvalOrArguments(); 640 } 641 642 static bool IsUndefined(PreParserIdentifier identifier) { 643 return identifier.IsUndefined(); 644 } 645 646 static bool IsPrototype(PreParserIdentifier identifier) { 647 return identifier.IsPrototype(); 648 } 649 650 static bool IsConstructor(PreParserIdentifier identifier) { 651 return identifier.IsConstructor(); 652 } 653 654 // Returns true if the expression is of type "this.foo". 655 static bool IsThisProperty(PreParserExpression expression) { 656 return expression.IsThisProperty(); 657 } 658 659 static bool IsIdentifier(PreParserExpression expression) { 660 return expression.IsIdentifier(); 661 } 662 663 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { 664 return expression.AsIdentifier(); 665 } 666 667 static bool IsEvalIdentifier(PreParserExpression expression) { 668 return IsIdentifier(expression) && IsEval(AsIdentifier(expression)); 669 } 670 671 static bool IsDirectEvalCall(PreParserExpression expression) { 672 return expression.IsDirectEvalCall(); 673 } 674 675 static bool IsFutureStrictReserved(PreParserIdentifier identifier) { 676 return identifier.IsFutureStrictReserved(); 677 } 678 679 static bool IsBoilerplateProperty(PreParserExpression property) { 680 // PreParser doesn't count boilerplate properties. 681 return false; 682 } 683 684 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { 685 return false; 686 } 687 688 static PreParserExpression GetPropertyValue(PreParserExpression property) { 689 return PreParserExpression::Default(); 690 } 691 692 // Functions for encapsulating the differences between parsing and preparsing; 693 // operations interleaved with the recursive descent. 694 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { 695 // PreParser should not use FuncNameInferrer. 696 UNREACHABLE(); 697 } 698 699 static void PushPropertyName(FuncNameInferrer* fni, 700 PreParserExpression expression) { 701 // PreParser should not use FuncNameInferrer. 702 UNREACHABLE(); 703 } 704 705 static void InferFunctionName(FuncNameInferrer* fni, 706 PreParserExpression expression) { 707 // PreParser should not use FuncNameInferrer. 708 UNREACHABLE(); 709 } 710 711 static void CheckAssigningFunctionLiteralToProperty( 712 PreParserExpression left, PreParserExpression right) {} 713 714 static PreParserExpression MarkExpressionAsAssigned( 715 PreParserExpression expression) { 716 // TODO(marja): To be able to produce the same errors, the preparser needs 717 // to start tracking which expressions are variables and which are assigned. 718 return expression; 719 } 720 721 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x, 722 PreParserExpression y, 723 Token::Value op, 724 int pos, 725 PreParserFactory* factory) { 726 return false; 727 } 728 729 PreParserExpression BuildUnaryExpression(PreParserExpression expression, 730 Token::Value op, int pos, 731 PreParserFactory* factory) { 732 return PreParserExpression::Default(); 733 } 734 735 PreParserExpression BuildIteratorResult(PreParserExpression value, 736 bool done) { 737 return PreParserExpression::Default(); 738 } 739 PreParserExpression NewThrowReferenceError(MessageTemplate::Template message, 740 int pos) { 741 return PreParserExpression::Default(); 742 } 743 PreParserExpression NewThrowSyntaxError(MessageTemplate::Template message, 744 Handle<Object> arg, int pos) { 745 return PreParserExpression::Default(); 746 } 747 PreParserExpression NewThrowTypeError(MessageTemplate::Template message, 748 Handle<Object> arg, int pos) { 749 return PreParserExpression::Default(); 750 } 751 752 // Reporting errors. 753 void ReportMessageAt(Scanner::Location location, 754 MessageTemplate::Template message, 755 const char* arg = NULL, 756 ParseErrorType error_type = kSyntaxError); 757 void ReportMessageAt(int start_pos, int end_pos, 758 MessageTemplate::Template message, 759 const char* arg = NULL, 760 ParseErrorType error_type = kSyntaxError); 761 762 // "null" return type creators. 763 static PreParserIdentifier EmptyIdentifier() { 764 return PreParserIdentifier::Default(); 765 } 766 static PreParserIdentifier EmptyIdentifierString() { 767 return PreParserIdentifier::Default(); 768 } 769 static PreParserExpression EmptyExpression() { 770 return PreParserExpression::Default(); 771 } 772 static PreParserExpression EmptyLiteral() { 773 return PreParserExpression::Default(); 774 } 775 static PreParserExpression EmptyObjectLiteralProperty() { 776 return PreParserExpression::Default(); 777 } 778 static PreParserExpression EmptyFunctionLiteral() { 779 return PreParserExpression::Default(); 780 } 781 static PreParserExpressionList NullExpressionList() { 782 return PreParserExpressionList(); 783 } 784 785 // Odd-ball literal creators. 786 static PreParserExpression GetLiteralTheHole(int position, 787 PreParserFactory* factory) { 788 return PreParserExpression::Default(); 789 } 790 791 // Producing data during the recursive descent. 792 PreParserIdentifier GetSymbol(Scanner* scanner); 793 PreParserIdentifier GetNumberAsSymbol(Scanner* scanner); 794 795 static PreParserIdentifier GetNextSymbol(Scanner* scanner) { 796 return PreParserIdentifier::Default(); 797 } 798 799 static PreParserExpression ThisExpression(Scope* scope, 800 PreParserFactory* factory, 801 int pos) { 802 return PreParserExpression::This(); 803 } 804 805 static PreParserExpression SuperPropertyReference(Scope* scope, 806 PreParserFactory* factory, 807 int pos) { 808 return PreParserExpression::Default(); 809 } 810 811 static PreParserExpression SuperCallReference(Scope* scope, 812 PreParserFactory* factory, 813 int pos) { 814 return PreParserExpression::SuperCallReference(); 815 } 816 817 static PreParserExpression NewTargetExpression(Scope* scope, 818 PreParserFactory* factory, 819 int pos) { 820 return PreParserExpression::Default(); 821 } 822 823 static PreParserExpression FunctionSentExpression(Scope* scope, 824 PreParserFactory* factory, 825 int pos) { 826 return PreParserExpression::Default(); 827 } 828 829 static PreParserExpression ExpressionFromLiteral( 830 Token::Value token, int pos, Scanner* scanner, 831 PreParserFactory* factory) { 832 return PreParserExpression::Default(); 833 } 834 835 static PreParserExpression ExpressionFromIdentifier( 836 PreParserIdentifier name, int start_position, int end_position, 837 Scope* scope, PreParserFactory* factory) { 838 return PreParserExpression::FromIdentifier(name); 839 } 840 841 PreParserExpression ExpressionFromString(int pos, 842 Scanner* scanner, 843 PreParserFactory* factory = NULL); 844 845 PreParserExpression GetIterator(PreParserExpression iterable, 846 PreParserFactory* factory, int pos) { 847 return PreParserExpression::Default(); 848 } 849 850 static PreParserExpressionList NewExpressionList(int size, Zone* zone) { 851 return PreParserExpressionList(); 852 } 853 854 static PreParserStatementList NewStatementList(int size, Zone* zone) { 855 return PreParserStatementList(); 856 } 857 858 static PreParserExpressionList NewPropertyList(int size, Zone* zone) { 859 return PreParserExpressionList(); 860 } 861 862 static void AddParameterInitializationBlock( 863 const PreParserFormalParameters& parameters, PreParserStatementList list, 864 bool is_async, bool* ok) {} 865 866 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count, 867 int* expected_property_count, bool* ok) { 868 UNREACHABLE(); 869 } 870 871 V8_INLINE PreParserStatementList ParseEagerFunctionBody( 872 PreParserIdentifier function_name, int pos, 873 const PreParserFormalParameters& parameters, FunctionKind kind, 874 FunctionLiteral::FunctionType function_type, bool* ok); 875 876 V8_INLINE void ParseArrowFunctionFormalParameterList( 877 PreParserFormalParameters* parameters, 878 PreParserExpression expression, const Scanner::Location& params_loc, 879 Scanner::Location* duplicate_loc, bool* ok); 880 881 void ParseAsyncArrowSingleExpressionBody( 882 PreParserStatementList body, bool accept_IN, 883 Type::ExpressionClassifier* classifier, int pos, bool* ok); 884 885 V8_INLINE PreParserExpression ParseAsyncFunctionExpression(bool* ok); 886 887 void ReindexLiterals(const PreParserFormalParameters& paramaters) {} 888 889 struct TemplateLiteralState {}; 890 891 TemplateLiteralState OpenTemplateLiteral(int pos) { 892 return TemplateLiteralState(); 893 } 894 void AddTemplateSpan(TemplateLiteralState*, bool) {} 895 void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} 896 PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, 897 PreParserExpression tag) { 898 if (IsTaggedTemplate(tag)) { 899 // Emulate generation of array literals for tag callsite 900 // 1st is array of cooked strings, second is array of raw strings 901 MaterializeTemplateCallsiteLiterals(); 902 } 903 return EmptyExpression(); 904 } 905 inline void MaterializeTemplateCallsiteLiterals(); 906 PreParserExpression NoTemplateTag() { 907 return PreParserExpression::NoTemplateTag(); 908 } 909 static bool IsTaggedTemplate(const PreParserExpression tag) { 910 return !tag.IsNoTemplateTag(); 911 } 912 913 void AddFormalParameter(PreParserFormalParameters* parameters, 914 PreParserExpression pattern, 915 PreParserExpression initializer, 916 int initializer_end_position, bool is_rest) { 917 ++parameters->arity; 918 } 919 void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter, 920 Type::ExpressionClassifier* classifier) { 921 if (!classifier->is_simple_parameter_list()) { 922 scope->SetHasNonSimpleParameters(); 923 } 924 } 925 926 void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} 927 928 // Temporary glue; these functions will move to ParserBase. 929 PreParserExpression ParseV8Intrinsic(bool* ok); 930 V8_INLINE PreParserExpression ParseDoExpression(bool* ok); 931 PreParserExpression ParseFunctionLiteral( 932 PreParserIdentifier name, Scanner::Location function_name_location, 933 FunctionNameValidity function_name_validity, FunctionKind kind, 934 int function_token_position, FunctionLiteral::FunctionType type, 935 LanguageMode language_mode, bool* ok); 936 937 PreParserExpression ParseClassLiteral(Type::ExpressionClassifier* classifier, 938 PreParserIdentifier name, 939 Scanner::Location class_name_location, 940 bool name_is_strict_reserved, int pos, 941 bool* ok); 942 943 V8_INLINE void MarkCollectedTailCallExpressions() {} 944 V8_INLINE void MarkTailPosition(PreParserExpression) {} 945 946 PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) { 947 return list; 948 } 949 950 inline void MaterializeUnspreadArgumentsLiterals(int count); 951 952 inline PreParserExpression SpreadCall(PreParserExpression function, 953 PreParserExpressionList args, int pos); 954 955 inline PreParserExpression SpreadCallNew(PreParserExpression function, 956 PreParserExpressionList args, 957 int pos); 958 959 inline PreParserExpression ExpressionListToExpression( 960 PreParserExpressionList args) { 961 return PreParserExpression::Default(); 962 } 963 964 inline void RewriteDestructuringAssignments() {} 965 966 inline PreParserExpression RewriteExponentiation(PreParserExpression left, 967 PreParserExpression right, 968 int pos) { 969 return left; 970 } 971 inline PreParserExpression RewriteAssignExponentiation( 972 PreParserExpression left, PreParserExpression right, int pos) { 973 return left; 974 } 975 976 inline void QueueDestructuringAssignmentForRewriting(PreParserExpression) {} 977 inline void QueueNonPatternForRewriting(PreParserExpression, bool* ok) {} 978 979 void SetFunctionNameFromPropertyName(PreParserExpression, 980 PreParserIdentifier) {} 981 void SetFunctionNameFromIdentifierRef(PreParserExpression, 982 PreParserExpression) {} 983 984 inline void RewriteNonPattern(Type::ExpressionClassifier* classifier, 985 bool* ok); 986 987 inline PreParserExpression RewriteAwaitExpression(PreParserExpression value, 988 int pos); 989 990 V8_INLINE ZoneList<typename Type::ExpressionClassifier::Error>* 991 GetReportedErrorList() const; 992 V8_INLINE Zone* zone() const; 993 V8_INLINE ZoneList<PreParserExpression>* GetNonPatternList() const; 994 995 inline PreParserExpression RewriteYieldStar( 996 PreParserExpression generator, PreParserExpression expr, int pos); 997 998 private: 999 PreParser* pre_parser_; 1000 }; 1001 1002 1003 // Preparsing checks a JavaScript program and emits preparse-data that helps 1004 // a later parsing to be faster. 1005 // See preparse-data-format.h for the data format. 1006 1007 // The PreParser checks that the syntax follows the grammar for JavaScript, 1008 // and collects some information about the program along the way. 1009 // The grammar check is only performed in order to understand the program 1010 // sufficiently to deduce some information about it, that can be used 1011 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 1012 // rather it is to speed up properly written and correct programs. 1013 // That means that contextual checks (like a label being declared where 1014 // it is used) are generally omitted. 1015 class PreParser : public ParserBase<PreParserTraits> { 1016 public: 1017 typedef PreParserIdentifier Identifier; 1018 typedef PreParserExpression Expression; 1019 typedef PreParserStatement Statement; 1020 1021 enum PreParseResult { 1022 kPreParseStackOverflow, 1023 kPreParseSuccess 1024 }; 1025 1026 PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory, 1027 ParserRecorder* log, uintptr_t stack_limit) 1028 : ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL, 1029 ast_value_factory, log, this), 1030 use_counts_(nullptr) {} 1031 1032 // Pre-parse the program from the character stream; returns true on 1033 // success (even if parsing failed, the pre-parse data successfully 1034 // captured the syntax error), and false if a stack-overflow happened 1035 // during parsing. 1036 PreParseResult PreParseProgram(int* materialized_literals = 0, 1037 bool is_module = false) { 1038 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); 1039 1040 // ModuleDeclarationInstantiation for Source Text Module Records creates a 1041 // new Module Environment Record whose outer lexical environment record is 1042 // the global scope. 1043 if (is_module) { 1044 scope = NewScope(scope, MODULE_SCOPE); 1045 } 1046 1047 PreParserFactory factory(NULL); 1048 FunctionState top_scope(&function_state_, &scope_, scope, kNormalFunction, 1049 &factory); 1050 bool ok = true; 1051 int start_position = scanner()->peek_location().beg_pos; 1052 parsing_module_ = is_module; 1053 ParseStatementList(Token::EOS, &ok); 1054 if (stack_overflow()) return kPreParseStackOverflow; 1055 if (!ok) { 1056 ReportUnexpectedToken(scanner()->current_token()); 1057 } else if (is_strict(scope_->language_mode())) { 1058 CheckStrictOctalLiteral(start_position, scanner()->location().end_pos, 1059 &ok); 1060 CheckDecimalLiteralWithLeadingZero(use_counts_, start_position, 1061 scanner()->location().end_pos); 1062 } 1063 if (materialized_literals) { 1064 *materialized_literals = function_state_->materialized_literal_count(); 1065 } 1066 return kPreParseSuccess; 1067 } 1068 1069 // Parses a single function literal, from the opening parentheses before 1070 // parameters to the closing brace after the body. 1071 // Returns a FunctionEntry describing the body of the function in enough 1072 // detail that it can be lazily compiled. 1073 // The scanner is expected to have matched the "function" or "function*" 1074 // keyword and parameters, and have consumed the initial '{'. 1075 // At return, unless an error occurred, the scanner is positioned before the 1076 // the final '}'. 1077 PreParseResult PreParseLazyFunction(LanguageMode language_mode, 1078 FunctionKind kind, 1079 bool has_simple_parameters, 1080 bool parsing_module, ParserRecorder* log, 1081 Scanner::BookmarkScope* bookmark, 1082 int* use_counts); 1083 1084 private: 1085 friend class PreParserTraits; 1086 1087 static const int kLazyParseTrialLimit = 200; 1088 1089 // These types form an algebra over syntactic categories that is just 1090 // rich enough to let us recognize and propagate the constructs that 1091 // are either being counted in the preparser data, or is important 1092 // to throw the correct syntax error exceptions. 1093 1094 // All ParseXXX functions take as the last argument an *ok parameter 1095 // which is set to false if parsing failed; it is unchanged otherwise. 1096 // By making the 'exception handling' explicit, we are forced to check 1097 // for failure at the call sites. 1098 Statement ParseStatementListItem(bool* ok); 1099 void ParseStatementList(int end_token, bool* ok, 1100 Scanner::BookmarkScope* bookmark = nullptr); 1101 Statement ParseStatement(AllowLabelledFunctionStatement allow_function, 1102 bool* ok); 1103 Statement ParseSubStatement(AllowLabelledFunctionStatement allow_function, 1104 bool* ok); 1105 Statement ParseScopedStatement(bool legacy, bool* ok); 1106 Statement ParseHoistableDeclaration(bool* ok); 1107 Statement ParseHoistableDeclaration(int pos, ParseFunctionFlags flags, 1108 bool* ok); 1109 Statement ParseFunctionDeclaration(bool* ok); 1110 Statement ParseAsyncFunctionDeclaration(bool* ok); 1111 Expression ParseAsyncFunctionExpression(bool* ok); 1112 Statement ParseClassDeclaration(bool* ok); 1113 Statement ParseBlock(bool* ok); 1114 Statement ParseVariableStatement(VariableDeclarationContext var_context, 1115 bool* ok); 1116 Statement ParseVariableDeclarations(VariableDeclarationContext var_context, 1117 int* num_decl, bool* is_lexical, 1118 bool* is_binding_pattern, 1119 Scanner::Location* first_initializer_loc, 1120 Scanner::Location* bindings_loc, 1121 bool* ok); 1122 Statement ParseExpressionOrLabelledStatement( 1123 AllowLabelledFunctionStatement allow_function, bool* ok); 1124 Statement ParseIfStatement(bool* ok); 1125 Statement ParseContinueStatement(bool* ok); 1126 Statement ParseBreakStatement(bool* ok); 1127 Statement ParseReturnStatement(bool* ok); 1128 Statement ParseWithStatement(bool* ok); 1129 Statement ParseSwitchStatement(bool* ok); 1130 Statement ParseDoWhileStatement(bool* ok); 1131 Statement ParseWhileStatement(bool* ok); 1132 Statement ParseForStatement(bool* ok); 1133 Statement ParseThrowStatement(bool* ok); 1134 Statement ParseTryStatement(bool* ok); 1135 Statement ParseDebuggerStatement(bool* ok); 1136 Expression ParseConditionalExpression(bool accept_IN, bool* ok); 1137 Expression ParseObjectLiteral(bool* ok); 1138 Expression ParseV8Intrinsic(bool* ok); 1139 Expression ParseDoExpression(bool* ok); 1140 1141 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count, 1142 int* expected_property_count, bool* ok); 1143 V8_INLINE PreParserStatementList ParseEagerFunctionBody( 1144 PreParserIdentifier function_name, int pos, 1145 const PreParserFormalParameters& parameters, FunctionKind kind, 1146 FunctionLiteral::FunctionType function_type, bool* ok); 1147 1148 Expression ParseFunctionLiteral( 1149 Identifier name, Scanner::Location function_name_location, 1150 FunctionNameValidity function_name_validity, FunctionKind kind, 1151 int function_token_pos, FunctionLiteral::FunctionType function_type, 1152 LanguageMode language_mode, bool* ok); 1153 void ParseLazyFunctionLiteralBody(bool* ok, 1154 Scanner::BookmarkScope* bookmark = nullptr); 1155 1156 PreParserExpression ParseClassLiteral(ExpressionClassifier* classifier, 1157 PreParserIdentifier name, 1158 Scanner::Location class_name_location, 1159 bool name_is_strict_reserved, int pos, 1160 bool* ok); 1161 1162 int* use_counts_; 1163 }; 1164 1165 1166 void PreParserTraits::MaterializeTemplateCallsiteLiterals() { 1167 pre_parser_->function_state_->NextMaterializedLiteralIndex(); 1168 pre_parser_->function_state_->NextMaterializedLiteralIndex(); 1169 } 1170 1171 1172 void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) { 1173 for (int i = 0; i < count; ++i) { 1174 pre_parser_->function_state_->NextMaterializedLiteralIndex(); 1175 } 1176 } 1177 1178 1179 PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function, 1180 PreParserExpressionList args, 1181 int pos) { 1182 return pre_parser_->factory()->NewCall(function, args, pos); 1183 } 1184 1185 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, 1186 PreParserExpressionList args, 1187 int pos) { 1188 return pre_parser_->factory()->NewCallNew(function, args, pos); 1189 } 1190 1191 1192 void PreParserTraits::ParseArrowFunctionFormalParameterList( 1193 PreParserFormalParameters* parameters, 1194 PreParserExpression params, const Scanner::Location& params_loc, 1195 Scanner::Location* duplicate_loc, bool* ok) { 1196 // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter 1197 // lists that are too long. 1198 } 1199 1200 PreParserExpression PreParserTraits::ParseAsyncFunctionExpression(bool* ok) { 1201 return pre_parser_->ParseAsyncFunctionExpression(ok); 1202 } 1203 1204 PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) { 1205 return pre_parser_->ParseDoExpression(ok); 1206 } 1207 1208 1209 void PreParserTraits::RewriteNonPattern(Type::ExpressionClassifier* classifier, 1210 bool* ok) { 1211 pre_parser_->ValidateExpression(classifier, ok); 1212 } 1213 1214 PreParserExpression PreParserTraits::RewriteAwaitExpression( 1215 PreParserExpression value, int pos) { 1216 return value; 1217 } 1218 1219 ZoneList<PreParserExpression>* PreParserTraits::GetNonPatternList() const { 1220 return pre_parser_->function_state_->non_patterns_to_rewrite(); 1221 } 1222 1223 1224 ZoneList<typename PreParserTraits::Type::ExpressionClassifier::Error>* 1225 PreParserTraits::GetReportedErrorList() const { 1226 return pre_parser_->function_state_->GetReportedErrorList(); 1227 } 1228 1229 1230 Zone* PreParserTraits::zone() const { 1231 return pre_parser_->function_state_->scope()->zone(); 1232 } 1233 1234 1235 PreParserExpression PreParserTraits::RewriteYieldStar( 1236 PreParserExpression generator, PreParserExpression expression, int pos) { 1237 return PreParserExpression::Default(); 1238 } 1239 1240 PreParserStatementList PreParser::ParseEagerFunctionBody( 1241 PreParserIdentifier function_name, int pos, 1242 const PreParserFormalParameters& parameters, FunctionKind kind, 1243 FunctionLiteral::FunctionType function_type, bool* ok) { 1244 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 1245 1246 Scope* inner_scope = scope_; 1247 if (!parameters.is_simple) inner_scope = NewScope(scope_, BLOCK_SCOPE); 1248 1249 { 1250 BlockState block_state(&scope_, inner_scope); 1251 ParseStatementList(Token::RBRACE, ok); 1252 if (!*ok) return PreParserStatementList(); 1253 } 1254 1255 Expect(Token::RBRACE, ok); 1256 return PreParserStatementList(); 1257 } 1258 1259 1260 PreParserStatementList PreParserTraits::ParseEagerFunctionBody( 1261 PreParserIdentifier function_name, int pos, 1262 const PreParserFormalParameters& parameters, FunctionKind kind, 1263 FunctionLiteral::FunctionType function_type, bool* ok) { 1264 return pre_parser_->ParseEagerFunctionBody(function_name, pos, parameters, 1265 kind, function_type, ok); 1266 } 1267 1268 } // namespace internal 1269 } // namespace v8 1270 1271 #endif // V8_PARSING_PREPARSER_H 1272