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