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_PREPARSER_H 6 #define V8_PREPARSER_H 7 8 #include "src/func-name-inferrer.h" 9 #include "src/hashmap.h" 10 #include "src/scopes.h" 11 #include "src/token.h" 12 #include "src/scanner.h" 13 #include "src/v8.h" 14 15 namespace v8 { 16 namespace internal { 17 18 // Common base class shared between parser and pre-parser. Traits encapsulate 19 // the differences between Parser and PreParser: 20 21 // - Return types: For example, Parser functions return Expression* and 22 // PreParser functions return PreParserExpression. 23 24 // - Creating parse tree nodes: Parser generates an AST during the recursive 25 // descent. PreParser doesn't create a tree. Instead, it passes around minimal 26 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain 27 // just enough data for the upper layer functions. PreParserFactory is 28 // responsible for creating these dummy objects. It provides a similar kind of 29 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is 30 // used. 31 32 // - Miscellanous other tasks interleaved with the recursive descent. For 33 // example, Parser keeps track of which function literals should be marked as 34 // pretenured, and PreParser doesn't care. 35 36 // The traits are expected to contain the following typedefs: 37 // struct Traits { 38 // // In particular... 39 // struct Type { 40 // // Used by FunctionState and BlockState. 41 // typedef Scope; 42 // typedef GeneratorVariable; 43 // typedef Zone; 44 // // Return types for traversing functions. 45 // typedef Identifier; 46 // typedef Expression; 47 // typedef FunctionLiteral; 48 // typedef ObjectLiteralProperty; 49 // typedef Literal; 50 // typedef ExpressionList; 51 // typedef PropertyList; 52 // // For constructing objects returned by the traversing functions. 53 // typedef Factory; 54 // }; 55 // // ... 56 // }; 57 58 template <typename Traits> 59 class ParserBase : public Traits { 60 public: 61 // Shorten type names defined by Traits. 62 typedef typename Traits::Type::Expression ExpressionT; 63 typedef typename Traits::Type::Identifier IdentifierT; 64 65 ParserBase(Scanner* scanner, uintptr_t stack_limit, 66 v8::Extension* extension, 67 ParserRecorder* log, 68 typename Traits::Type::Zone* zone, 69 typename Traits::Type::Parser this_object) 70 : Traits(this_object), 71 parenthesized_function_(false), 72 scope_(NULL), 73 function_state_(NULL), 74 extension_(extension), 75 fni_(NULL), 76 log_(log), 77 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. 78 scanner_(scanner), 79 stack_limit_(stack_limit), 80 stack_overflow_(false), 81 allow_lazy_(false), 82 allow_natives_syntax_(false), 83 allow_generators_(false), 84 allow_for_of_(false), 85 zone_(zone) { } 86 87 // Getters that indicate whether certain syntactical constructs are 88 // allowed to be parsed by this instance of the parser. 89 bool allow_lazy() const { return allow_lazy_; } 90 bool allow_natives_syntax() const { return allow_natives_syntax_; } 91 bool allow_generators() const { return allow_generators_; } 92 bool allow_for_of() const { return allow_for_of_; } 93 bool allow_modules() const { return scanner()->HarmonyModules(); } 94 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } 95 bool allow_harmony_numeric_literals() const { 96 return scanner()->HarmonyNumericLiterals(); 97 } 98 99 // Setters that determine whether certain syntactical constructs are 100 // allowed to be parsed by this instance of the parser. 101 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } 102 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } 103 void set_allow_generators(bool allow) { allow_generators_ = allow; } 104 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } 105 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } 106 void set_allow_harmony_scoping(bool allow) { 107 scanner()->SetHarmonyScoping(allow); 108 } 109 void set_allow_harmony_numeric_literals(bool allow) { 110 scanner()->SetHarmonyNumericLiterals(allow); 111 } 112 113 protected: 114 enum AllowEvalOrArgumentsAsIdentifier { 115 kAllowEvalOrArguments, 116 kDontAllowEvalOrArguments 117 }; 118 119 enum Mode { 120 PARSE_LAZILY, 121 PARSE_EAGERLY 122 }; 123 124 // --------------------------------------------------------------------------- 125 // FunctionState and BlockState together implement the parser's scope stack. 126 // The parser's current scope is in scope_. BlockState and FunctionState 127 // constructors push on the scope stack and the destructors pop. They are also 128 // used to hold the parser's per-function and per-block state. 129 class BlockState BASE_EMBEDDED { 130 public: 131 BlockState(typename Traits::Type::Scope** scope_stack, 132 typename Traits::Type::Scope* scope) 133 : scope_stack_(scope_stack), 134 outer_scope_(*scope_stack), 135 scope_(scope) { 136 *scope_stack_ = scope_; 137 } 138 ~BlockState() { *scope_stack_ = outer_scope_; } 139 140 private: 141 typename Traits::Type::Scope** scope_stack_; 142 typename Traits::Type::Scope* outer_scope_; 143 typename Traits::Type::Scope* scope_; 144 }; 145 146 class FunctionState BASE_EMBEDDED { 147 public: 148 FunctionState( 149 FunctionState** function_state_stack, 150 typename Traits::Type::Scope** scope_stack, 151 typename Traits::Type::Scope* scope, 152 typename Traits::Type::Zone* zone = NULL); 153 ~FunctionState(); 154 155 int NextMaterializedLiteralIndex() { 156 return next_materialized_literal_index_++; 157 } 158 int materialized_literal_count() { 159 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; 160 } 161 162 int NextHandlerIndex() { return next_handler_index_++; } 163 int handler_count() { return next_handler_index_; } 164 165 void AddProperty() { expected_property_count_++; } 166 int expected_property_count() { return expected_property_count_; } 167 168 void set_is_generator(bool is_generator) { is_generator_ = is_generator; } 169 bool is_generator() const { return is_generator_; } 170 171 void set_generator_object_variable( 172 typename Traits::Type::GeneratorVariable* variable) { 173 ASSERT(variable != NULL); 174 ASSERT(!is_generator()); 175 generator_object_variable_ = variable; 176 is_generator_ = true; 177 } 178 typename Traits::Type::GeneratorVariable* generator_object_variable() 179 const { 180 return generator_object_variable_; 181 } 182 183 typename Traits::Type::Factory* factory() { return &factory_; } 184 185 private: 186 // Used to assign an index to each literal that needs materialization in 187 // the function. Includes regexp literals, and boilerplate for object and 188 // array literals. 189 int next_materialized_literal_index_; 190 191 // Used to assign a per-function index to try and catch handlers. 192 int next_handler_index_; 193 194 // Properties count estimation. 195 int expected_property_count_; 196 197 // Whether the function is a generator. 198 bool is_generator_; 199 // For generators, this variable may hold the generator object. It variable 200 // is used by yield expressions and return statements. It is not necessary 201 // for generator functions to have this variable set. 202 Variable* generator_object_variable_; 203 204 FunctionState** function_state_stack_; 205 FunctionState* outer_function_state_; 206 typename Traits::Type::Scope** scope_stack_; 207 typename Traits::Type::Scope* outer_scope_; 208 int saved_ast_node_id_; // Only used by ParserTraits. 209 typename Traits::Type::Zone* extra_param_; 210 typename Traits::Type::Factory factory_; 211 212 friend class ParserTraits; 213 }; 214 215 class ParsingModeScope BASE_EMBEDDED { 216 public: 217 ParsingModeScope(ParserBase* parser, Mode mode) 218 : parser_(parser), 219 old_mode_(parser->mode()) { 220 parser_->mode_ = mode; 221 } 222 ~ParsingModeScope() { 223 parser_->mode_ = old_mode_; 224 } 225 226 private: 227 ParserBase* parser_; 228 Mode old_mode_; 229 }; 230 231 Scanner* scanner() const { return scanner_; } 232 int position() { return scanner_->location().beg_pos; } 233 int peek_position() { return scanner_->peek_location().beg_pos; } 234 bool stack_overflow() const { return stack_overflow_; } 235 void set_stack_overflow() { stack_overflow_ = true; } 236 Mode mode() const { return mode_; } 237 typename Traits::Type::Zone* zone() const { return zone_; } 238 239 INLINE(Token::Value peek()) { 240 if (stack_overflow_) return Token::ILLEGAL; 241 return scanner()->peek(); 242 } 243 244 INLINE(Token::Value Next()) { 245 if (stack_overflow_) return Token::ILLEGAL; 246 { 247 int marker; 248 if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) { 249 // Any further calls to Next or peek will return the illegal token. 250 // The current call must return the next token, which might already 251 // have been peek'ed. 252 stack_overflow_ = true; 253 } 254 } 255 return scanner()->Next(); 256 } 257 258 void Consume(Token::Value token) { 259 Token::Value next = Next(); 260 USE(next); 261 USE(token); 262 ASSERT(next == token); 263 } 264 265 bool Check(Token::Value token) { 266 Token::Value next = peek(); 267 if (next == token) { 268 Consume(next); 269 return true; 270 } 271 return false; 272 } 273 274 void Expect(Token::Value token, bool* ok) { 275 Token::Value next = Next(); 276 if (next != token) { 277 ReportUnexpectedToken(next); 278 *ok = false; 279 } 280 } 281 282 void ExpectSemicolon(bool* ok) { 283 // Check for automatic semicolon insertion according to 284 // the rules given in ECMA-262, section 7.9, page 21. 285 Token::Value tok = peek(); 286 if (tok == Token::SEMICOLON) { 287 Next(); 288 return; 289 } 290 if (scanner()->HasAnyLineTerminatorBeforeNext() || 291 tok == Token::RBRACE || 292 tok == Token::EOS) { 293 return; 294 } 295 Expect(Token::SEMICOLON, ok); 296 } 297 298 bool peek_any_identifier() { 299 Token::Value next = peek(); 300 return next == Token::IDENTIFIER || 301 next == Token::FUTURE_RESERVED_WORD || 302 next == Token::FUTURE_STRICT_RESERVED_WORD || 303 next == Token::YIELD; 304 } 305 306 bool CheckContextualKeyword(Vector<const char> keyword) { 307 if (peek() == Token::IDENTIFIER && 308 scanner()->is_next_contextual_keyword(keyword)) { 309 Consume(Token::IDENTIFIER); 310 return true; 311 } 312 return false; 313 } 314 315 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { 316 Expect(Token::IDENTIFIER, ok); 317 if (!*ok) return; 318 if (!scanner()->is_literal_contextual_keyword(keyword)) { 319 ReportUnexpectedToken(scanner()->current_token()); 320 *ok = false; 321 } 322 } 323 324 // Checks whether an octal literal was last seen between beg_pos and end_pos. 325 // If so, reports an error. Only called for strict mode. 326 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { 327 Scanner::Location octal = scanner()->octal_position(); 328 if (octal.IsValid() && beg_pos <= octal.beg_pos && 329 octal.end_pos <= end_pos) { 330 ReportMessageAt(octal, "strict_octal_literal"); 331 scanner()->clear_octal_position(); 332 *ok = false; 333 } 334 } 335 336 // Determine precedence of given token. 337 static int Precedence(Token::Value token, bool accept_IN) { 338 if (token == Token::IN && !accept_IN) 339 return 0; // 0 precedence will terminate binary expression parsing 340 return Token::Precedence(token); 341 } 342 343 typename Traits::Type::Factory* factory() { 344 return function_state_->factory(); 345 } 346 347 StrictMode strict_mode() { return scope_->strict_mode(); } 348 bool is_generator() const { return function_state_->is_generator(); } 349 350 // Report syntax errors. 351 void ReportMessage(const char* message, const char* arg = NULL, 352 bool is_reference_error = false) { 353 Scanner::Location source_location = scanner()->location(); 354 Traits::ReportMessageAt(source_location, message, arg, is_reference_error); 355 } 356 357 void ReportMessageAt(Scanner::Location location, const char* message, 358 bool is_reference_error = false) { 359 Traits::ReportMessageAt(location, message, NULL, is_reference_error); 360 } 361 362 void ReportUnexpectedToken(Token::Value token); 363 364 // Recursive descent functions: 365 366 // Parses an identifier that is valid for the current scope, in particular it 367 // fails on strict mode future reserved keywords in a strict scope. If 368 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or 369 // "arguments" as identifier even in strict mode (this is needed in cases like 370 // "var foo = eval;"). 371 IdentifierT ParseIdentifier( 372 AllowEvalOrArgumentsAsIdentifier, 373 bool* ok); 374 // Parses an identifier or a strict mode future reserved word, and indicate 375 // whether it is strict mode future reserved. 376 IdentifierT ParseIdentifierOrStrictReservedWord( 377 bool* is_strict_reserved, 378 bool* ok); 379 IdentifierT ParseIdentifierName(bool* ok); 380 // Parses an identifier and determines whether or not it is 'get' or 'set'. 381 IdentifierT ParseIdentifierNameOrGetOrSet(bool* is_get, 382 bool* is_set, 383 bool* ok); 384 385 ExpressionT ParseRegExpLiteral(bool seen_equal, bool* ok); 386 387 ExpressionT ParsePrimaryExpression(bool* ok); 388 ExpressionT ParseExpression(bool accept_IN, bool* ok); 389 ExpressionT ParseArrayLiteral(bool* ok); 390 ExpressionT ParseObjectLiteral(bool* ok); 391 typename Traits::Type::ExpressionList ParseArguments(bool* ok); 392 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); 393 ExpressionT ParseYieldExpression(bool* ok); 394 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); 395 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 396 ExpressionT ParseUnaryExpression(bool* ok); 397 ExpressionT ParsePostfixExpression(bool* ok); 398 ExpressionT ParseLeftHandSideExpression(bool* ok); 399 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); 400 ExpressionT ParseMemberExpression(bool* ok); 401 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 402 bool* ok); 403 404 // Checks if the expression is a valid reference expression (e.g., on the 405 // left-hand side of assignments). Although ruled out by ECMA as early errors, 406 // we allow calls for web compatibility and rewrite them to a runtime throw. 407 ExpressionT CheckAndRewriteReferenceExpression( 408 ExpressionT expression, 409 Scanner::Location location, const char* message, bool* ok); 410 411 // Used to detect duplicates in object literals. Each of the values 412 // kGetterProperty, kSetterProperty and kValueProperty represents 413 // a type of object literal property. When parsing a property, its 414 // type value is stored in the DuplicateFinder for the property name. 415 // Values are chosen so that having intersection bits means the there is 416 // an incompatibility. 417 // I.e., you can add a getter to a property that already has a setter, since 418 // kGetterProperty and kSetterProperty doesn't intersect, but not if it 419 // already has a getter or a value. Adding the getter to an existing 420 // setter will store the value (kGetterProperty | kSetterProperty), which 421 // is incompatible with adding any further properties. 422 enum PropertyKind { 423 kNone = 0, 424 // Bit patterns representing different object literal property types. 425 kGetterProperty = 1, 426 kSetterProperty = 2, 427 kValueProperty = 7, 428 // Helper constants. 429 kValueFlag = 4 430 }; 431 432 // Validation per ECMA 262 - 11.1.5 "Object Initialiser". 433 class ObjectLiteralChecker { 434 public: 435 ObjectLiteralChecker(ParserBase* parser, StrictMode strict_mode) 436 : parser_(parser), 437 finder_(scanner()->unicode_cache()), 438 strict_mode_(strict_mode) { } 439 440 void CheckProperty(Token::Value property, PropertyKind type, bool* ok); 441 442 private: 443 ParserBase* parser() const { return parser_; } 444 Scanner* scanner() const { return parser_->scanner(); } 445 446 // Checks the type of conflict based on values coming from PropertyType. 447 bool HasConflict(PropertyKind type1, PropertyKind type2) { 448 return (type1 & type2) != 0; 449 } 450 bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) { 451 return ((type1 & type2) & kValueFlag) != 0; 452 } 453 bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) { 454 return ((type1 ^ type2) & kValueFlag) != 0; 455 } 456 bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) { 457 return ((type1 | type2) & kValueFlag) == 0; 458 } 459 460 ParserBase* parser_; 461 DuplicateFinder finder_; 462 StrictMode strict_mode_; 463 }; 464 465 // If true, the next (and immediately following) function literal is 466 // preceded by a parenthesis. 467 // Heuristically that means that the function will be called immediately, 468 // so never lazily compile it. 469 bool parenthesized_function_; 470 471 typename Traits::Type::Scope* scope_; // Scope stack. 472 FunctionState* function_state_; // Function state stack. 473 v8::Extension* extension_; 474 FuncNameInferrer* fni_; 475 ParserRecorder* log_; 476 Mode mode_; 477 478 private: 479 Scanner* scanner_; 480 uintptr_t stack_limit_; 481 bool stack_overflow_; 482 483 bool allow_lazy_; 484 bool allow_natives_syntax_; 485 bool allow_generators_; 486 bool allow_for_of_; 487 488 typename Traits::Type::Zone* zone_; // Only used by Parser. 489 }; 490 491 492 class PreParserIdentifier { 493 public: 494 PreParserIdentifier() : type_(kUnknownIdentifier) {} 495 static PreParserIdentifier Default() { 496 return PreParserIdentifier(kUnknownIdentifier); 497 } 498 static PreParserIdentifier Eval() { 499 return PreParserIdentifier(kEvalIdentifier); 500 } 501 static PreParserIdentifier Arguments() { 502 return PreParserIdentifier(kArgumentsIdentifier); 503 } 504 static PreParserIdentifier FutureReserved() { 505 return PreParserIdentifier(kFutureReservedIdentifier); 506 } 507 static PreParserIdentifier FutureStrictReserved() { 508 return PreParserIdentifier(kFutureStrictReservedIdentifier); 509 } 510 static PreParserIdentifier Yield() { 511 return PreParserIdentifier(kYieldIdentifier); 512 } 513 bool IsEval() { return type_ == kEvalIdentifier; } 514 bool IsArguments() { return type_ == kArgumentsIdentifier; } 515 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } 516 bool IsYield() { return type_ == kYieldIdentifier; } 517 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } 518 bool IsFutureStrictReserved() { 519 return type_ == kFutureStrictReservedIdentifier; 520 } 521 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } 522 523 private: 524 enum Type { 525 kUnknownIdentifier, 526 kFutureReservedIdentifier, 527 kFutureStrictReservedIdentifier, 528 kYieldIdentifier, 529 kEvalIdentifier, 530 kArgumentsIdentifier 531 }; 532 explicit PreParserIdentifier(Type type) : type_(type) {} 533 Type type_; 534 535 friend class PreParserExpression; 536 }; 537 538 539 // Bits 0 and 1 are used to identify the type of expression: 540 // If bit 0 is set, it's an identifier. 541 // if bit 1 is set, it's a string literal. 542 // If neither is set, it's no particular type, and both set isn't 543 // use yet. 544 class PreParserExpression { 545 public: 546 static PreParserExpression Default() { 547 return PreParserExpression(kUnknownExpression); 548 } 549 550 static PreParserExpression FromIdentifier(PreParserIdentifier id) { 551 return PreParserExpression(kIdentifierFlag | 552 (id.type_ << kIdentifierShift)); 553 } 554 555 static PreParserExpression StringLiteral() { 556 return PreParserExpression(kUnknownStringLiteral); 557 } 558 559 static PreParserExpression UseStrictStringLiteral() { 560 return PreParserExpression(kUseStrictString); 561 } 562 563 static PreParserExpression This() { 564 return PreParserExpression(kThisExpression); 565 } 566 567 static PreParserExpression ThisProperty() { 568 return PreParserExpression(kThisPropertyExpression); 569 } 570 571 static PreParserExpression Property() { 572 return PreParserExpression(kPropertyExpression); 573 } 574 575 static PreParserExpression Call() { 576 return PreParserExpression(kCallExpression); 577 } 578 579 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } 580 581 PreParserIdentifier AsIdentifier() { 582 ASSERT(IsIdentifier()); 583 return PreParserIdentifier( 584 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); 585 } 586 587 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } 588 589 bool IsUseStrictLiteral() { 590 return (code_ & kStringLiteralMask) == kUseStrictString; 591 } 592 593 bool IsThis() { return code_ == kThisExpression; } 594 595 bool IsThisProperty() { return code_ == kThisPropertyExpression; } 596 597 bool IsProperty() { 598 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; 599 } 600 601 bool IsCall() { return code_ == kCallExpression; } 602 603 bool IsValidReferenceExpression() { 604 return IsIdentifier() || IsProperty(); 605 } 606 607 // At the moment PreParser doesn't track these expression types. 608 bool IsFunctionLiteral() const { return false; } 609 bool IsCallNew() const { return false; } 610 611 PreParserExpression AsFunctionLiteral() { return *this; } 612 613 // Dummy implementation for making expression->somefunc() work in both Parser 614 // and PreParser. 615 PreParserExpression* operator->() { return this; } 616 617 // More dummy implementations of things PreParser doesn't need to track: 618 void set_index(int index) {} // For YieldExpressions 619 void set_parenthesized() {} 620 621 private: 622 // Least significant 2 bits are used as flags. Bits 0 and 1 represent 623 // identifiers or strings literals, and are mutually exclusive, but can both 624 // be absent. If the expression is an identifier or a string literal, the 625 // other bits describe the type (see PreParserIdentifier::Type and string 626 // literal constants below). 627 enum { 628 kUnknownExpression = 0, 629 // Identifiers 630 kIdentifierFlag = 1, // Used to detect labels. 631 kIdentifierShift = 3, 632 633 kStringLiteralFlag = 2, // Used to detect directive prologue. 634 kUnknownStringLiteral = kStringLiteralFlag, 635 kUseStrictString = kStringLiteralFlag | 8, 636 kStringLiteralMask = kUseStrictString, 637 638 // Below here applies if neither identifier nor string literal. Reserve the 639 // 2 least significant bits for flags. 640 kThisExpression = 1 << 2, 641 kThisPropertyExpression = 2 << 2, 642 kPropertyExpression = 3 << 2, 643 kCallExpression = 4 << 2 644 }; 645 646 explicit PreParserExpression(int expression_code) : code_(expression_code) {} 647 648 int code_; 649 }; 650 651 652 // PreParserExpressionList doesn't actually store the expressions because 653 // PreParser doesn't need to. 654 class PreParserExpressionList { 655 public: 656 // These functions make list->Add(some_expression) work (and do nothing). 657 PreParserExpressionList() : length_(0) {} 658 PreParserExpressionList* operator->() { return this; } 659 void Add(PreParserExpression, void*) { ++length_; } 660 int length() const { return length_; } 661 private: 662 int length_; 663 }; 664 665 666 class PreParserStatement { 667 public: 668 static PreParserStatement Default() { 669 return PreParserStatement(kUnknownStatement); 670 } 671 672 static PreParserStatement FunctionDeclaration() { 673 return PreParserStatement(kFunctionDeclaration); 674 } 675 676 // Creates expression statement from expression. 677 // Preserves being an unparenthesized string literal, possibly 678 // "use strict". 679 static PreParserStatement ExpressionStatement( 680 PreParserExpression expression) { 681 if (expression.IsUseStrictLiteral()) { 682 return PreParserStatement(kUseStrictExpressionStatement); 683 } 684 if (expression.IsStringLiteral()) { 685 return PreParserStatement(kStringLiteralExpressionStatement); 686 } 687 return Default(); 688 } 689 690 bool IsStringLiteral() { 691 return code_ == kStringLiteralExpressionStatement; 692 } 693 694 bool IsUseStrictLiteral() { 695 return code_ == kUseStrictExpressionStatement; 696 } 697 698 bool IsFunctionDeclaration() { 699 return code_ == kFunctionDeclaration; 700 } 701 702 private: 703 enum Type { 704 kUnknownStatement, 705 kStringLiteralExpressionStatement, 706 kUseStrictExpressionStatement, 707 kFunctionDeclaration 708 }; 709 710 explicit PreParserStatement(Type code) : code_(code) {} 711 Type code_; 712 }; 713 714 715 716 // PreParserStatementList doesn't actually store the statements because 717 // the PreParser does not need them. 718 class PreParserStatementList { 719 public: 720 // These functions make list->Add(some_expression) work as no-ops. 721 PreParserStatementList() {} 722 PreParserStatementList* operator->() { return this; } 723 void Add(PreParserStatement, void*) {} 724 }; 725 726 727 class PreParserScope { 728 public: 729 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) 730 : scope_type_(scope_type) { 731 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; 732 } 733 734 ScopeType type() { return scope_type_; } 735 StrictMode strict_mode() const { return strict_mode_; } 736 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } 737 738 private: 739 ScopeType scope_type_; 740 StrictMode strict_mode_; 741 }; 742 743 744 class PreParserFactory { 745 public: 746 explicit PreParserFactory(void* extra_param) {} 747 PreParserExpression NewLiteral(PreParserIdentifier identifier, 748 int pos) { 749 return PreParserExpression::Default(); 750 } 751 PreParserExpression NewNumberLiteral(double number, 752 int pos) { 753 return PreParserExpression::Default(); 754 } 755 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern, 756 PreParserIdentifier js_flags, 757 int literal_index, 758 int pos) { 759 return PreParserExpression::Default(); 760 } 761 PreParserExpression NewArrayLiteral(PreParserExpressionList values, 762 int literal_index, 763 int pos) { 764 return PreParserExpression::Default(); 765 } 766 PreParserExpression NewObjectLiteralProperty(bool is_getter, 767 PreParserExpression value, 768 int pos) { 769 return PreParserExpression::Default(); 770 } 771 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, 772 PreParserExpression value) { 773 return PreParserExpression::Default(); 774 } 775 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, 776 int literal_index, 777 int boilerplate_properties, 778 bool has_function, 779 int pos) { 780 return PreParserExpression::Default(); 781 } 782 PreParserExpression NewVariableProxy(void* generator_variable) { 783 return PreParserExpression::Default(); 784 } 785 PreParserExpression NewProperty(PreParserExpression obj, 786 PreParserExpression key, 787 int pos) { 788 if (obj.IsThis()) { 789 return PreParserExpression::ThisProperty(); 790 } 791 return PreParserExpression::Property(); 792 } 793 PreParserExpression NewUnaryOperation(Token::Value op, 794 PreParserExpression expression, 795 int pos) { 796 return PreParserExpression::Default(); 797 } 798 PreParserExpression NewBinaryOperation(Token::Value op, 799 PreParserExpression left, 800 PreParserExpression right, int pos) { 801 return PreParserExpression::Default(); 802 } 803 PreParserExpression NewCompareOperation(Token::Value op, 804 PreParserExpression left, 805 PreParserExpression right, int pos) { 806 return PreParserExpression::Default(); 807 } 808 PreParserExpression NewAssignment(Token::Value op, 809 PreParserExpression left, 810 PreParserExpression right, 811 int pos) { 812 return PreParserExpression::Default(); 813 } 814 PreParserExpression NewYield(PreParserExpression generator_object, 815 PreParserExpression expression, 816 Yield::Kind yield_kind, 817 int pos) { 818 return PreParserExpression::Default(); 819 } 820 PreParserExpression NewConditional(PreParserExpression condition, 821 PreParserExpression then_expression, 822 PreParserExpression else_expression, 823 int pos) { 824 return PreParserExpression::Default(); 825 } 826 PreParserExpression NewCountOperation(Token::Value op, 827 bool is_prefix, 828 PreParserExpression expression, 829 int pos) { 830 return PreParserExpression::Default(); 831 } 832 PreParserExpression NewCall(PreParserExpression expression, 833 PreParserExpressionList arguments, 834 int pos) { 835 return PreParserExpression::Call(); 836 } 837 PreParserExpression NewCallNew(PreParserExpression expression, 838 PreParserExpressionList arguments, 839 int pos) { 840 return PreParserExpression::Default(); 841 } 842 }; 843 844 845 class PreParser; 846 847 class PreParserTraits { 848 public: 849 struct Type { 850 // TODO(marja): To be removed. The Traits object should contain all the data 851 // it needs. 852 typedef PreParser* Parser; 853 854 // Used by FunctionState and BlockState. 855 typedef PreParserScope Scope; 856 // PreParser doesn't need to store generator variables. 857 typedef void GeneratorVariable; 858 // No interaction with Zones. 859 typedef void Zone; 860 861 // Return types for traversing functions. 862 typedef PreParserIdentifier Identifier; 863 typedef PreParserExpression Expression; 864 typedef PreParserExpression YieldExpression; 865 typedef PreParserExpression FunctionLiteral; 866 typedef PreParserExpression ObjectLiteralProperty; 867 typedef PreParserExpression Literal; 868 typedef PreParserExpressionList ExpressionList; 869 typedef PreParserExpressionList PropertyList; 870 typedef PreParserStatementList StatementList; 871 872 // For constructing objects returned by the traversing functions. 873 typedef PreParserFactory Factory; 874 }; 875 876 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} 877 878 // Custom operations executed when FunctionStates are created and 879 // destructed. (The PreParser doesn't need to do anything.) 880 template<typename FunctionState> 881 static void SetUpFunctionState(FunctionState* function_state, void*) {} 882 template<typename FunctionState> 883 static void TearDownFunctionState(FunctionState* function_state, void*) {} 884 885 // Helper functions for recursive descent. 886 static bool IsEvalOrArguments(PreParserIdentifier identifier) { 887 return identifier.IsEvalOrArguments(); 888 } 889 890 // Returns true if the expression is of type "this.foo". 891 static bool IsThisProperty(PreParserExpression expression) { 892 return expression.IsThisProperty(); 893 } 894 895 static bool IsIdentifier(PreParserExpression expression) { 896 return expression.IsIdentifier(); 897 } 898 899 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { 900 return expression.AsIdentifier(); 901 } 902 903 static bool IsBoilerplateProperty(PreParserExpression property) { 904 // PreParser doesn't count boilerplate properties. 905 return false; 906 } 907 908 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { 909 return false; 910 } 911 912 // Functions for encapsulating the differences between parsing and preparsing; 913 // operations interleaved with the recursive descent. 914 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { 915 // PreParser should not use FuncNameInferrer. 916 UNREACHABLE(); 917 } 918 static void PushPropertyName(FuncNameInferrer* fni, 919 PreParserExpression expression) { 920 // PreParser should not use FuncNameInferrer. 921 UNREACHABLE(); 922 } 923 924 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( 925 PreParserScope* scope, PreParserExpression value, bool* has_function) {} 926 927 static void CheckAssigningFunctionLiteralToProperty( 928 PreParserExpression left, PreParserExpression right) {} 929 930 // PreParser doesn't need to keep track of eval calls. 931 static void CheckPossibleEvalCall(PreParserExpression expression, 932 PreParserScope* scope) {} 933 934 static PreParserExpression MarkExpressionAsLValue( 935 PreParserExpression expression) { 936 // TODO(marja): To be able to produce the same errors, the preparser needs 937 // to start tracking which expressions are variables and which are lvalues. 938 return expression; 939 } 940 941 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x, 942 PreParserExpression y, 943 Token::Value op, 944 int pos, 945 PreParserFactory* factory) { 946 return false; 947 } 948 949 PreParserExpression BuildUnaryExpression(PreParserExpression expression, 950 Token::Value op, int pos, 951 PreParserFactory* factory) { 952 return PreParserExpression::Default(); 953 } 954 955 PreParserExpression NewThrowReferenceError(const char* type, int pos) { 956 return PreParserExpression::Default(); 957 } 958 PreParserExpression NewThrowSyntaxError( 959 const char* type, Handle<Object> arg, int pos) { 960 return PreParserExpression::Default(); 961 } 962 PreParserExpression NewThrowTypeError( 963 const char* type, Handle<Object> arg, int pos) { 964 return PreParserExpression::Default(); 965 } 966 967 // Reporting errors. 968 void ReportMessageAt(Scanner::Location location, 969 const char* message, 970 const char* arg = NULL, 971 bool is_reference_error = false); 972 void ReportMessageAt(int start_pos, 973 int end_pos, 974 const char* message, 975 const char* arg = NULL, 976 bool is_reference_error = false); 977 978 // "null" return type creators. 979 static PreParserIdentifier EmptyIdentifier() { 980 return PreParserIdentifier::Default(); 981 } 982 static PreParserExpression EmptyExpression() { 983 return PreParserExpression::Default(); 984 } 985 static PreParserExpression EmptyLiteral() { 986 return PreParserExpression::Default(); 987 } 988 static PreParserExpressionList NullExpressionList() { 989 return PreParserExpressionList(); 990 } 991 992 // Odd-ball literal creators. 993 static PreParserExpression GetLiteralTheHole(int position, 994 PreParserFactory* factory) { 995 return PreParserExpression::Default(); 996 } 997 998 // Producing data during the recursive descent. 999 PreParserIdentifier GetSymbol(Scanner* scanner); 1000 static PreParserIdentifier NextLiteralString(Scanner* scanner, 1001 PretenureFlag tenured) { 1002 return PreParserIdentifier::Default(); 1003 } 1004 1005 static PreParserExpression ThisExpression(PreParserScope* scope, 1006 PreParserFactory* factory) { 1007 return PreParserExpression::This(); 1008 } 1009 1010 static PreParserExpression ExpressionFromLiteral( 1011 Token::Value token, int pos, Scanner* scanner, 1012 PreParserFactory* factory) { 1013 return PreParserExpression::Default(); 1014 } 1015 1016 static PreParserExpression ExpressionFromIdentifier( 1017 PreParserIdentifier name, int pos, PreParserScope* scope, 1018 PreParserFactory* factory) { 1019 return PreParserExpression::FromIdentifier(name); 1020 } 1021 1022 PreParserExpression ExpressionFromString(int pos, 1023 Scanner* scanner, 1024 PreParserFactory* factory = NULL); 1025 1026 static PreParserExpressionList NewExpressionList(int size, void* zone) { 1027 return PreParserExpressionList(); 1028 } 1029 1030 static PreParserStatementList NewStatementList(int size, void* zone) { 1031 return PreParserStatementList(); 1032 } 1033 1034 static PreParserExpressionList NewPropertyList(int size, void* zone) { 1035 return PreParserExpressionList(); 1036 } 1037 1038 // Temporary glue; these functions will move to ParserBase. 1039 PreParserExpression ParseV8Intrinsic(bool* ok); 1040 PreParserExpression ParseFunctionLiteral( 1041 PreParserIdentifier name, 1042 Scanner::Location function_name_location, 1043 bool name_is_strict_reserved, 1044 bool is_generator, 1045 int function_token_position, 1046 FunctionLiteral::FunctionType type, 1047 FunctionLiteral::ArityRestriction arity_restriction, 1048 bool* ok); 1049 1050 private: 1051 PreParser* pre_parser_; 1052 }; 1053 1054 1055 // Preparsing checks a JavaScript program and emits preparse-data that helps 1056 // a later parsing to be faster. 1057 // See preparse-data-format.h for the data format. 1058 1059 // The PreParser checks that the syntax follows the grammar for JavaScript, 1060 // and collects some information about the program along the way. 1061 // The grammar check is only performed in order to understand the program 1062 // sufficiently to deduce some information about it, that can be used 1063 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 1064 // rather it is to speed up properly written and correct programs. 1065 // That means that contextual checks (like a label being declared where 1066 // it is used) are generally omitted. 1067 class PreParser : public ParserBase<PreParserTraits> { 1068 public: 1069 typedef PreParserIdentifier Identifier; 1070 typedef PreParserExpression Expression; 1071 typedef PreParserStatement Statement; 1072 1073 enum PreParseResult { 1074 kPreParseStackOverflow, 1075 kPreParseSuccess 1076 }; 1077 1078 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) 1079 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, 1080 this) {} 1081 1082 // Pre-parse the program from the character stream; returns true on 1083 // success (even if parsing failed, the pre-parse data successfully 1084 // captured the syntax error), and false if a stack-overflow happened 1085 // during parsing. 1086 PreParseResult PreParseProgram() { 1087 PreParserScope scope(scope_, GLOBAL_SCOPE); 1088 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); 1089 bool ok = true; 1090 int start_position = scanner()->peek_location().beg_pos; 1091 ParseSourceElements(Token::EOS, &ok); 1092 if (stack_overflow()) return kPreParseStackOverflow; 1093 if (!ok) { 1094 ReportUnexpectedToken(scanner()->current_token()); 1095 } else if (scope_->strict_mode() == STRICT) { 1096 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); 1097 } 1098 return kPreParseSuccess; 1099 } 1100 1101 // Parses a single function literal, from the opening parentheses before 1102 // parameters to the closing brace after the body. 1103 // Returns a FunctionEntry describing the body of the function in enough 1104 // detail that it can be lazily compiled. 1105 // The scanner is expected to have matched the "function" or "function*" 1106 // keyword and parameters, and have consumed the initial '{'. 1107 // At return, unless an error occurred, the scanner is positioned before the 1108 // the final '}'. 1109 PreParseResult PreParseLazyFunction(StrictMode strict_mode, 1110 bool is_generator, 1111 ParserRecorder* log); 1112 1113 private: 1114 friend class PreParserTraits; 1115 1116 // These types form an algebra over syntactic categories that is just 1117 // rich enough to let us recognize and propagate the constructs that 1118 // are either being counted in the preparser data, or is important 1119 // to throw the correct syntax error exceptions. 1120 1121 enum VariableDeclarationContext { 1122 kSourceElement, 1123 kStatement, 1124 kForStatement 1125 }; 1126 1127 // If a list of variable declarations includes any initializers. 1128 enum VariableDeclarationProperties { 1129 kHasInitializers, 1130 kHasNoInitializers 1131 }; 1132 1133 1134 enum SourceElements { 1135 kUnknownSourceElements 1136 }; 1137 1138 // All ParseXXX functions take as the last argument an *ok parameter 1139 // which is set to false if parsing failed; it is unchanged otherwise. 1140 // By making the 'exception handling' explicit, we are forced to check 1141 // for failure at the call sites. 1142 Statement ParseSourceElement(bool* ok); 1143 SourceElements ParseSourceElements(int end_token, bool* ok); 1144 Statement ParseStatement(bool* ok); 1145 Statement ParseFunctionDeclaration(bool* ok); 1146 Statement ParseBlock(bool* ok); 1147 Statement ParseVariableStatement(VariableDeclarationContext var_context, 1148 bool* ok); 1149 Statement ParseVariableDeclarations(VariableDeclarationContext var_context, 1150 VariableDeclarationProperties* decl_props, 1151 int* num_decl, 1152 bool* ok); 1153 Statement ParseExpressionOrLabelledStatement(bool* ok); 1154 Statement ParseIfStatement(bool* ok); 1155 Statement ParseContinueStatement(bool* ok); 1156 Statement ParseBreakStatement(bool* ok); 1157 Statement ParseReturnStatement(bool* ok); 1158 Statement ParseWithStatement(bool* ok); 1159 Statement ParseSwitchStatement(bool* ok); 1160 Statement ParseDoWhileStatement(bool* ok); 1161 Statement ParseWhileStatement(bool* ok); 1162 Statement ParseForStatement(bool* ok); 1163 Statement ParseThrowStatement(bool* ok); 1164 Statement ParseTryStatement(bool* ok); 1165 Statement ParseDebuggerStatement(bool* ok); 1166 Expression ParseConditionalExpression(bool accept_IN, bool* ok); 1167 Expression ParseObjectLiteral(bool* ok); 1168 Expression ParseV8Intrinsic(bool* ok); 1169 1170 Expression ParseFunctionLiteral( 1171 Identifier name, 1172 Scanner::Location function_name_location, 1173 bool name_is_strict_reserved, 1174 bool is_generator, 1175 int function_token_pos, 1176 FunctionLiteral::FunctionType function_type, 1177 FunctionLiteral::ArityRestriction arity_restriction, 1178 bool* ok); 1179 void ParseLazyFunctionLiteralBody(bool* ok); 1180 1181 bool CheckInOrOf(bool accept_OF); 1182 }; 1183 1184 template<class Traits> 1185 ParserBase<Traits>::FunctionState::FunctionState( 1186 FunctionState** function_state_stack, 1187 typename Traits::Type::Scope** scope_stack, 1188 typename Traits::Type::Scope* scope, 1189 typename Traits::Type::Zone* extra_param) 1190 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), 1191 next_handler_index_(0), 1192 expected_property_count_(0), 1193 is_generator_(false), 1194 generator_object_variable_(NULL), 1195 function_state_stack_(function_state_stack), 1196 outer_function_state_(*function_state_stack), 1197 scope_stack_(scope_stack), 1198 outer_scope_(*scope_stack), 1199 saved_ast_node_id_(0), 1200 extra_param_(extra_param), 1201 factory_(extra_param) { 1202 *scope_stack_ = scope; 1203 *function_state_stack = this; 1204 Traits::SetUpFunctionState(this, extra_param); 1205 } 1206 1207 1208 template<class Traits> 1209 ParserBase<Traits>::FunctionState::~FunctionState() { 1210 *scope_stack_ = outer_scope_; 1211 *function_state_stack_ = outer_function_state_; 1212 Traits::TearDownFunctionState(this, extra_param_); 1213 } 1214 1215 1216 template<class Traits> 1217 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 1218 Scanner::Location source_location = scanner()->location(); 1219 1220 // Four of the tokens are treated specially 1221 switch (token) { 1222 case Token::EOS: 1223 return ReportMessageAt(source_location, "unexpected_eos"); 1224 case Token::NUMBER: 1225 return ReportMessageAt(source_location, "unexpected_token_number"); 1226 case Token::STRING: 1227 return ReportMessageAt(source_location, "unexpected_token_string"); 1228 case Token::IDENTIFIER: 1229 return ReportMessageAt(source_location, "unexpected_token_identifier"); 1230 case Token::FUTURE_RESERVED_WORD: 1231 return ReportMessageAt(source_location, "unexpected_reserved"); 1232 case Token::YIELD: 1233 case Token::FUTURE_STRICT_RESERVED_WORD: 1234 return ReportMessageAt(source_location, strict_mode() == SLOPPY 1235 ? "unexpected_token_identifier" : "unexpected_strict_reserved"); 1236 default: 1237 const char* name = Token::String(token); 1238 ASSERT(name != NULL); 1239 Traits::ReportMessageAt(source_location, "unexpected_token", name); 1240 } 1241 } 1242 1243 1244 template<class Traits> 1245 typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( 1246 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, 1247 bool* ok) { 1248 Token::Value next = Next(); 1249 if (next == Token::IDENTIFIER) { 1250 IdentifierT name = this->GetSymbol(scanner()); 1251 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && 1252 strict_mode() == STRICT && this->IsEvalOrArguments(name)) { 1253 ReportMessage("strict_eval_arguments"); 1254 *ok = false; 1255 } 1256 return name; 1257 } else if (strict_mode() == SLOPPY && 1258 (next == Token::FUTURE_STRICT_RESERVED_WORD || 1259 (next == Token::YIELD && !is_generator()))) { 1260 return this->GetSymbol(scanner()); 1261 } else { 1262 this->ReportUnexpectedToken(next); 1263 *ok = false; 1264 return Traits::EmptyIdentifier(); 1265 } 1266 } 1267 1268 1269 template <class Traits> 1270 typename ParserBase<Traits>::IdentifierT ParserBase< 1271 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, 1272 bool* ok) { 1273 Token::Value next = Next(); 1274 if (next == Token::IDENTIFIER) { 1275 *is_strict_reserved = false; 1276 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || 1277 (next == Token::YIELD && !this->is_generator())) { 1278 *is_strict_reserved = true; 1279 } else { 1280 ReportUnexpectedToken(next); 1281 *ok = false; 1282 return Traits::EmptyIdentifier(); 1283 } 1284 return this->GetSymbol(scanner()); 1285 } 1286 1287 1288 template <class Traits> 1289 typename ParserBase<Traits>::IdentifierT 1290 ParserBase<Traits>::ParseIdentifierName(bool* ok) { 1291 Token::Value next = Next(); 1292 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && 1293 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { 1294 this->ReportUnexpectedToken(next); 1295 *ok = false; 1296 return Traits::EmptyIdentifier(); 1297 } 1298 return this->GetSymbol(scanner()); 1299 } 1300 1301 1302 template <class Traits> 1303 typename ParserBase<Traits>::IdentifierT 1304 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get, 1305 bool* is_set, 1306 bool* ok) { 1307 IdentifierT result = ParseIdentifierName(ok); 1308 if (!*ok) return Traits::EmptyIdentifier(); 1309 scanner()->IsGetOrSet(is_get, is_set); 1310 return result; 1311 } 1312 1313 1314 template <class Traits> 1315 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral( 1316 bool seen_equal, bool* ok) { 1317 int pos = peek_position(); 1318 if (!scanner()->ScanRegExpPattern(seen_equal)) { 1319 Next(); 1320 ReportMessage("unterminated_regexp"); 1321 *ok = false; 1322 return Traits::EmptyExpression(); 1323 } 1324 1325 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1326 1327 IdentifierT js_pattern = this->NextLiteralString(scanner(), TENURED); 1328 if (!scanner()->ScanRegExpFlags()) { 1329 Next(); 1330 ReportMessage("invalid_regexp_flags"); 1331 *ok = false; 1332 return Traits::EmptyExpression(); 1333 } 1334 IdentifierT js_flags = this->NextLiteralString(scanner(), TENURED); 1335 Next(); 1336 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); 1337 } 1338 1339 1340 #define CHECK_OK ok); \ 1341 if (!*ok) return this->EmptyExpression(); \ 1342 ((void)0 1343 #define DUMMY ) // to make indentation work 1344 #undef DUMMY 1345 1346 // Used in functions where the return type is not ExpressionT. 1347 #define CHECK_OK_CUSTOM(x) ok); \ 1348 if (!*ok) return this->x(); \ 1349 ((void)0 1350 #define DUMMY ) // to make indentation work 1351 #undef DUMMY 1352 1353 template <class Traits> 1354 typename ParserBase<Traits>::ExpressionT 1355 ParserBase<Traits>::ParsePrimaryExpression(bool* ok) { 1356 // PrimaryExpression :: 1357 // 'this' 1358 // 'null' 1359 // 'true' 1360 // 'false' 1361 // Identifier 1362 // Number 1363 // String 1364 // ArrayLiteral 1365 // ObjectLiteral 1366 // RegExpLiteral 1367 // '(' Expression ')' 1368 1369 int pos = peek_position(); 1370 ExpressionT result = this->EmptyExpression(); 1371 Token::Value token = peek(); 1372 switch (token) { 1373 case Token::THIS: { 1374 Consume(Token::THIS); 1375 result = this->ThisExpression(scope_, factory()); 1376 break; 1377 } 1378 1379 case Token::NULL_LITERAL: 1380 case Token::TRUE_LITERAL: 1381 case Token::FALSE_LITERAL: 1382 case Token::NUMBER: 1383 Next(); 1384 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); 1385 break; 1386 1387 case Token::IDENTIFIER: 1388 case Token::YIELD: 1389 case Token::FUTURE_STRICT_RESERVED_WORD: { 1390 // Using eval or arguments in this context is OK even in strict mode. 1391 IdentifierT name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 1392 result = this->ExpressionFromIdentifier(name, pos, scope_, factory()); 1393 break; 1394 } 1395 1396 case Token::STRING: { 1397 Consume(Token::STRING); 1398 result = this->ExpressionFromString(pos, scanner(), factory()); 1399 break; 1400 } 1401 1402 case Token::ASSIGN_DIV: 1403 result = this->ParseRegExpLiteral(true, CHECK_OK); 1404 break; 1405 1406 case Token::DIV: 1407 result = this->ParseRegExpLiteral(false, CHECK_OK); 1408 break; 1409 1410 case Token::LBRACK: 1411 result = this->ParseArrayLiteral(CHECK_OK); 1412 break; 1413 1414 case Token::LBRACE: 1415 result = this->ParseObjectLiteral(CHECK_OK); 1416 break; 1417 1418 case Token::LPAREN: 1419 Consume(Token::LPAREN); 1420 // Heuristically try to detect immediately called functions before 1421 // seeing the call parentheses. 1422 parenthesized_function_ = (peek() == Token::FUNCTION); 1423 result = this->ParseExpression(true, CHECK_OK); 1424 Expect(Token::RPAREN, CHECK_OK); 1425 break; 1426 1427 case Token::MOD: 1428 if (allow_natives_syntax() || extension_ != NULL) { 1429 result = this->ParseV8Intrinsic(CHECK_OK); 1430 break; 1431 } 1432 // If we're not allowing special syntax we fall-through to the 1433 // default case. 1434 1435 default: { 1436 Next(); 1437 ReportUnexpectedToken(token); 1438 *ok = false; 1439 } 1440 } 1441 1442 return result; 1443 } 1444 1445 // Precedence = 1 1446 template <class Traits> 1447 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( 1448 bool accept_IN, bool* ok) { 1449 // Expression :: 1450 // AssignmentExpression 1451 // Expression ',' AssignmentExpression 1452 1453 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK); 1454 while (peek() == Token::COMMA) { 1455 Expect(Token::COMMA, CHECK_OK); 1456 int pos = position(); 1457 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); 1458 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); 1459 } 1460 return result; 1461 } 1462 1463 1464 template <class Traits> 1465 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( 1466 bool* ok) { 1467 // ArrayLiteral :: 1468 // '[' Expression? (',' Expression?)* ']' 1469 1470 int pos = peek_position(); 1471 typename Traits::Type::ExpressionList values = 1472 this->NewExpressionList(4, zone_); 1473 Expect(Token::LBRACK, CHECK_OK); 1474 while (peek() != Token::RBRACK) { 1475 ExpressionT elem = this->EmptyExpression(); 1476 if (peek() == Token::COMMA) { 1477 elem = this->GetLiteralTheHole(peek_position(), factory()); 1478 } else { 1479 elem = this->ParseAssignmentExpression(true, CHECK_OK); 1480 } 1481 values->Add(elem, zone_); 1482 if (peek() != Token::RBRACK) { 1483 Expect(Token::COMMA, CHECK_OK); 1484 } 1485 } 1486 Expect(Token::RBRACK, CHECK_OK); 1487 1488 // Update the scope information before the pre-parsing bailout. 1489 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1490 1491 return factory()->NewArrayLiteral(values, literal_index, pos); 1492 } 1493 1494 1495 template <class Traits> 1496 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral( 1497 bool* ok) { 1498 // ObjectLiteral :: 1499 // '{' (( 1500 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 1501 // (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 1502 // ) ',')* '}' 1503 // (Except that trailing comma is not required and not allowed.) 1504 1505 int pos = peek_position(); 1506 typename Traits::Type::PropertyList properties = 1507 this->NewPropertyList(4, zone_); 1508 int number_of_boilerplate_properties = 0; 1509 bool has_function = false; 1510 1511 ObjectLiteralChecker checker(this, strict_mode()); 1512 1513 Expect(Token::LBRACE, CHECK_OK); 1514 1515 while (peek() != Token::RBRACE) { 1516 if (fni_ != NULL) fni_->Enter(); 1517 1518 typename Traits::Type::Literal key = this->EmptyLiteral(); 1519 Token::Value next = peek(); 1520 int next_pos = peek_position(); 1521 1522 switch (next) { 1523 case Token::FUTURE_RESERVED_WORD: 1524 case Token::FUTURE_STRICT_RESERVED_WORD: 1525 case Token::IDENTIFIER: { 1526 bool is_getter = false; 1527 bool is_setter = false; 1528 IdentifierT id = 1529 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 1530 if (fni_ != NULL) this->PushLiteralName(fni_, id); 1531 1532 if ((is_getter || is_setter) && peek() != Token::COLON) { 1533 // Special handling of getter and setter syntax: 1534 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } 1535 // We have already read the "get" or "set" keyword. 1536 Token::Value next = Next(); 1537 if (next != i::Token::IDENTIFIER && 1538 next != i::Token::FUTURE_RESERVED_WORD && 1539 next != i::Token::FUTURE_STRICT_RESERVED_WORD && 1540 next != i::Token::NUMBER && 1541 next != i::Token::STRING && 1542 !Token::IsKeyword(next)) { 1543 ReportUnexpectedToken(next); 1544 *ok = false; 1545 return this->EmptyLiteral(); 1546 } 1547 // Validate the property. 1548 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; 1549 checker.CheckProperty(next, type, CHECK_OK); 1550 IdentifierT name = this->GetSymbol(scanner_); 1551 typename Traits::Type::FunctionLiteral value = 1552 this->ParseFunctionLiteral( 1553 name, scanner()->location(), 1554 false, // reserved words are allowed here 1555 false, // not a generator 1556 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, 1557 is_getter ? FunctionLiteral::GETTER_ARITY 1558 : FunctionLiteral::SETTER_ARITY, 1559 CHECK_OK); 1560 typename Traits::Type::ObjectLiteralProperty property = 1561 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); 1562 if (this->IsBoilerplateProperty(property)) { 1563 number_of_boilerplate_properties++; 1564 } 1565 properties->Add(property, zone()); 1566 if (peek() != Token::RBRACE) { 1567 // Need {} because of the CHECK_OK macro. 1568 Expect(Token::COMMA, CHECK_OK); 1569 } 1570 1571 if (fni_ != NULL) { 1572 fni_->Infer(); 1573 fni_->Leave(); 1574 } 1575 continue; // restart the while 1576 } 1577 // Failed to parse as get/set property, so it's just a normal property 1578 // (which might be called "get" or "set" or something else). 1579 key = factory()->NewLiteral(id, next_pos); 1580 break; 1581 } 1582 case Token::STRING: { 1583 Consume(Token::STRING); 1584 IdentifierT string = this->GetSymbol(scanner_); 1585 if (fni_ != NULL) this->PushLiteralName(fni_, string); 1586 uint32_t index; 1587 if (this->IsArrayIndex(string, &index)) { 1588 key = factory()->NewNumberLiteral(index, next_pos); 1589 break; 1590 } 1591 key = factory()->NewLiteral(string, next_pos); 1592 break; 1593 } 1594 case Token::NUMBER: { 1595 Consume(Token::NUMBER); 1596 key = this->ExpressionFromLiteral(Token::NUMBER, next_pos, scanner_, 1597 factory()); 1598 break; 1599 } 1600 default: 1601 if (Token::IsKeyword(next)) { 1602 Consume(next); 1603 IdentifierT string = this->GetSymbol(scanner_); 1604 key = factory()->NewLiteral(string, next_pos); 1605 } else { 1606 Token::Value next = Next(); 1607 ReportUnexpectedToken(next); 1608 *ok = false; 1609 return this->EmptyLiteral(); 1610 } 1611 } 1612 1613 // Validate the property 1614 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1615 1616 Expect(Token::COLON, CHECK_OK); 1617 ExpressionT value = this->ParseAssignmentExpression(true, CHECK_OK); 1618 1619 typename Traits::Type::ObjectLiteralProperty property = 1620 factory()->NewObjectLiteralProperty(key, value); 1621 1622 // Mark top-level object literals that contain function literals and 1623 // pretenure the literal so it can be added as a constant function 1624 // property. (Parser only.) 1625 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value, 1626 &has_function); 1627 1628 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 1629 if (this->IsBoilerplateProperty(property)) { 1630 number_of_boilerplate_properties++; 1631 } 1632 properties->Add(property, zone()); 1633 1634 // TODO(1240767): Consider allowing trailing comma. 1635 if (peek() != Token::RBRACE) { 1636 // Need {} because of the CHECK_OK macro. 1637 Expect(Token::COMMA, CHECK_OK); 1638 } 1639 1640 if (fni_ != NULL) { 1641 fni_->Infer(); 1642 fni_->Leave(); 1643 } 1644 } 1645 Expect(Token::RBRACE, CHECK_OK); 1646 1647 // Computation of literal_index must happen before pre parse bailout. 1648 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1649 1650 return factory()->NewObjectLiteral(properties, 1651 literal_index, 1652 number_of_boilerplate_properties, 1653 has_function, 1654 pos); 1655 } 1656 1657 1658 template <class Traits> 1659 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( 1660 bool* ok) { 1661 // Arguments :: 1662 // '(' (AssignmentExpression)*[','] ')' 1663 1664 typename Traits::Type::ExpressionList result = 1665 this->NewExpressionList(4, zone_); 1666 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 1667 bool done = (peek() == Token::RPAREN); 1668 while (!done) { 1669 ExpressionT argument = this->ParseAssignmentExpression( 1670 true, CHECK_OK_CUSTOM(NullExpressionList)); 1671 result->Add(argument, zone_); 1672 if (result->length() > Code::kMaxArguments) { 1673 ReportMessage("too_many_arguments"); 1674 *ok = false; 1675 return this->NullExpressionList(); 1676 } 1677 done = (peek() == Token::RPAREN); 1678 if (!done) { 1679 // Need {} because of the CHECK_OK_CUSTOM macro. 1680 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList)); 1681 } 1682 } 1683 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 1684 return result; 1685 } 1686 1687 // Precedence = 2 1688 template <class Traits> 1689 typename ParserBase<Traits>::ExpressionT 1690 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { 1691 // AssignmentExpression :: 1692 // ConditionalExpression 1693 // YieldExpression 1694 // LeftHandSideExpression AssignmentOperator AssignmentExpression 1695 1696 Scanner::Location lhs_location = scanner()->peek_location(); 1697 1698 if (peek() == Token::YIELD && is_generator()) { 1699 return this->ParseYieldExpression(ok); 1700 } 1701 1702 if (fni_ != NULL) fni_->Enter(); 1703 ExpressionT expression = 1704 this->ParseConditionalExpression(accept_IN, CHECK_OK); 1705 1706 if (!Token::IsAssignmentOp(peek())) { 1707 if (fni_ != NULL) fni_->Leave(); 1708 // Parsed conditional expression only (no assignment). 1709 return expression; 1710 } 1711 1712 expression = this->CheckAndRewriteReferenceExpression( 1713 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); 1714 expression = this->MarkExpressionAsLValue(expression); 1715 1716 Token::Value op = Next(); // Get assignment operator. 1717 int pos = position(); 1718 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); 1719 1720 // TODO(1231235): We try to estimate the set of properties set by 1721 // constructors. We define a new property whenever there is an 1722 // assignment to a property of 'this'. We should probably only add 1723 // properties if we haven't seen them before. Otherwise we'll 1724 // probably overestimate the number of properties. 1725 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { 1726 function_state_->AddProperty(); 1727 } 1728 1729 this->CheckAssigningFunctionLiteralToProperty(expression, right); 1730 1731 if (fni_ != NULL) { 1732 // Check if the right hand side is a call to avoid inferring a 1733 // name if we're dealing with "a = function(){...}();"-like 1734 // expression. 1735 if ((op == Token::INIT_VAR 1736 || op == Token::INIT_CONST_LEGACY 1737 || op == Token::ASSIGN) 1738 && (!right->IsCall() && !right->IsCallNew())) { 1739 fni_->Infer(); 1740 } else { 1741 fni_->RemoveLastFunction(); 1742 } 1743 fni_->Leave(); 1744 } 1745 1746 return factory()->NewAssignment(op, expression, right, pos); 1747 } 1748 1749 template <class Traits> 1750 typename ParserBase<Traits>::ExpressionT 1751 ParserBase<Traits>::ParseYieldExpression(bool* ok) { 1752 // YieldExpression :: 1753 // 'yield' '*'? AssignmentExpression 1754 int pos = peek_position(); 1755 Expect(Token::YIELD, CHECK_OK); 1756 Yield::Kind kind = 1757 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; 1758 ExpressionT generator_object = 1759 factory()->NewVariableProxy(function_state_->generator_object_variable()); 1760 ExpressionT expression = 1761 ParseAssignmentExpression(false, CHECK_OK); 1762 typename Traits::Type::YieldExpression yield = 1763 factory()->NewYield(generator_object, expression, kind, pos); 1764 if (kind == Yield::DELEGATING) { 1765 yield->set_index(function_state_->NextHandlerIndex()); 1766 } 1767 return yield; 1768 } 1769 1770 1771 // Precedence = 3 1772 template <class Traits> 1773 typename ParserBase<Traits>::ExpressionT 1774 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, bool* ok) { 1775 // ConditionalExpression :: 1776 // LogicalOrExpression 1777 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 1778 1779 int pos = peek_position(); 1780 // We start using the binary expression parser for prec >= 4 only! 1781 ExpressionT expression = this->ParseBinaryExpression(4, accept_IN, CHECK_OK); 1782 if (peek() != Token::CONDITIONAL) return expression; 1783 Consume(Token::CONDITIONAL); 1784 // In parsing the first assignment expression in conditional 1785 // expressions we always accept the 'in' keyword; see ECMA-262, 1786 // section 11.12, page 58. 1787 ExpressionT left = ParseAssignmentExpression(true, CHECK_OK); 1788 Expect(Token::COLON, CHECK_OK); 1789 ExpressionT right = ParseAssignmentExpression(accept_IN, CHECK_OK); 1790 return factory()->NewConditional(expression, left, right, pos); 1791 } 1792 1793 1794 // Precedence >= 4 1795 template <class Traits> 1796 typename ParserBase<Traits>::ExpressionT 1797 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { 1798 ASSERT(prec >= 4); 1799 ExpressionT x = this->ParseUnaryExpression(CHECK_OK); 1800 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 1801 // prec1 >= 4 1802 while (Precedence(peek(), accept_IN) == prec1) { 1803 Token::Value op = Next(); 1804 int pos = position(); 1805 ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); 1806 1807 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, 1808 factory())) { 1809 continue; 1810 } 1811 1812 // For now we distinguish between comparisons and other binary 1813 // operations. (We could combine the two and get rid of this 1814 // code and AST node eventually.) 1815 if (Token::IsCompareOp(op)) { 1816 // We have a comparison. 1817 Token::Value cmp = op; 1818 switch (op) { 1819 case Token::NE: cmp = Token::EQ; break; 1820 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; 1821 default: break; 1822 } 1823 x = factory()->NewCompareOperation(cmp, x, y, pos); 1824 if (cmp != op) { 1825 // The comparison was negated - add a NOT. 1826 x = factory()->NewUnaryOperation(Token::NOT, x, pos); 1827 } 1828 1829 } else { 1830 // We have a "normal" binary operation. 1831 x = factory()->NewBinaryOperation(op, x, y, pos); 1832 } 1833 } 1834 } 1835 return x; 1836 } 1837 1838 1839 template <class Traits> 1840 typename ParserBase<Traits>::ExpressionT 1841 ParserBase<Traits>::ParseUnaryExpression(bool* ok) { 1842 // UnaryExpression :: 1843 // PostfixExpression 1844 // 'delete' UnaryExpression 1845 // 'void' UnaryExpression 1846 // 'typeof' UnaryExpression 1847 // '++' UnaryExpression 1848 // '--' UnaryExpression 1849 // '+' UnaryExpression 1850 // '-' UnaryExpression 1851 // '~' UnaryExpression 1852 // '!' UnaryExpression 1853 1854 Token::Value op = peek(); 1855 if (Token::IsUnaryOp(op)) { 1856 op = Next(); 1857 int pos = position(); 1858 ExpressionT expression = ParseUnaryExpression(CHECK_OK); 1859 1860 // "delete identifier" is a syntax error in strict mode. 1861 if (op == Token::DELETE && strict_mode() == STRICT && 1862 this->IsIdentifier(expression)) { 1863 ReportMessage("strict_delete"); 1864 *ok = false; 1865 return this->EmptyExpression(); 1866 } 1867 1868 // Allow Traits do rewrite the expression. 1869 return this->BuildUnaryExpression(expression, op, pos, factory()); 1870 } else if (Token::IsCountOp(op)) { 1871 op = Next(); 1872 Scanner::Location lhs_location = scanner()->peek_location(); 1873 ExpressionT expression = this->ParseUnaryExpression(CHECK_OK); 1874 expression = this->CheckAndRewriteReferenceExpression( 1875 expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK); 1876 this->MarkExpressionAsLValue(expression); 1877 1878 return factory()->NewCountOperation(op, 1879 true /* prefix */, 1880 expression, 1881 position()); 1882 1883 } else { 1884 return this->ParsePostfixExpression(ok); 1885 } 1886 } 1887 1888 1889 template <class Traits> 1890 typename ParserBase<Traits>::ExpressionT 1891 ParserBase<Traits>::ParsePostfixExpression(bool* ok) { 1892 // PostfixExpression :: 1893 // LeftHandSideExpression ('++' | '--')? 1894 1895 Scanner::Location lhs_location = scanner()->peek_location(); 1896 ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK); 1897 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 1898 Token::IsCountOp(peek())) { 1899 expression = this->CheckAndRewriteReferenceExpression( 1900 expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK); 1901 expression = this->MarkExpressionAsLValue(expression); 1902 1903 Token::Value next = Next(); 1904 expression = 1905 factory()->NewCountOperation(next, 1906 false /* postfix */, 1907 expression, 1908 position()); 1909 } 1910 return expression; 1911 } 1912 1913 1914 template <class Traits> 1915 typename ParserBase<Traits>::ExpressionT 1916 ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) { 1917 // LeftHandSideExpression :: 1918 // (NewExpression | MemberExpression) ... 1919 1920 ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); 1921 1922 while (true) { 1923 switch (peek()) { 1924 case Token::LBRACK: { 1925 Consume(Token::LBRACK); 1926 int pos = position(); 1927 ExpressionT index = ParseExpression(true, CHECK_OK); 1928 result = factory()->NewProperty(result, index, pos); 1929 Expect(Token::RBRACK, CHECK_OK); 1930 break; 1931 } 1932 1933 case Token::LPAREN: { 1934 int pos; 1935 if (scanner()->current_token() == Token::IDENTIFIER) { 1936 // For call of an identifier we want to report position of 1937 // the identifier as position of the call in the stack trace. 1938 pos = position(); 1939 } else { 1940 // For other kinds of calls we record position of the parenthesis as 1941 // position of the call. Note that this is extremely important for 1942 // expressions of the form function(){...}() for which call position 1943 // should not point to the closing brace otherwise it will intersect 1944 // with positions recorded for function literal and confuse debugger. 1945 pos = peek_position(); 1946 // Also the trailing parenthesis are a hint that the function will 1947 // be called immediately. If we happen to have parsed a preceding 1948 // function literal eagerly, we can also compile it eagerly. 1949 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { 1950 result->AsFunctionLiteral()->set_parenthesized(); 1951 } 1952 } 1953 typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK); 1954 1955 // Keep track of eval() calls since they disable all local variable 1956 // optimizations. 1957 // The calls that need special treatment are the 1958 // direct eval calls. These calls are all of the form eval(...), with 1959 // no explicit receiver. 1960 // These calls are marked as potentially direct eval calls. Whether 1961 // they are actually direct calls to eval is determined at run time. 1962 this->CheckPossibleEvalCall(result, scope_); 1963 result = factory()->NewCall(result, args, pos); 1964 if (fni_ != NULL) fni_->RemoveLastFunction(); 1965 break; 1966 } 1967 1968 case Token::PERIOD: { 1969 Consume(Token::PERIOD); 1970 int pos = position(); 1971 IdentifierT name = ParseIdentifierName(CHECK_OK); 1972 result = factory()->NewProperty( 1973 result, factory()->NewLiteral(name, pos), pos); 1974 if (fni_ != NULL) this->PushLiteralName(fni_, name); 1975 break; 1976 } 1977 1978 default: 1979 return result; 1980 } 1981 } 1982 } 1983 1984 1985 template <class Traits> 1986 typename ParserBase<Traits>::ExpressionT 1987 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { 1988 // NewExpression :: 1989 // ('new')+ MemberExpression 1990 1991 // The grammar for new expressions is pretty warped. We can have several 'new' 1992 // keywords following each other, and then a MemberExpression. When we see '(' 1993 // after the MemberExpression, it's associated with the rightmost unassociated 1994 // 'new' to create a NewExpression with arguments. However, a NewExpression 1995 // can also occur without arguments. 1996 1997 // Examples of new expression: 1998 // new foo.bar().baz means (new (foo.bar)()).baz 1999 // new foo()() means (new foo())() 2000 // new new foo()() means (new (new foo())()) 2001 // new new foo means new (new foo) 2002 // new new foo() means new (new foo()) 2003 // new new foo().bar().baz means (new (new foo()).bar()).baz 2004 2005 if (peek() == Token::NEW) { 2006 Consume(Token::NEW); 2007 int new_pos = position(); 2008 ExpressionT result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); 2009 if (peek() == Token::LPAREN) { 2010 // NewExpression with arguments. 2011 typename Traits::Type::ExpressionList args = 2012 this->ParseArguments(CHECK_OK); 2013 result = factory()->NewCallNew(result, args, new_pos); 2014 // The expression can still continue with . or [ after the arguments. 2015 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); 2016 return result; 2017 } 2018 // NewExpression without arguments. 2019 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), 2020 new_pos); 2021 } 2022 // No 'new' keyword. 2023 return this->ParseMemberExpression(ok); 2024 } 2025 2026 2027 template <class Traits> 2028 typename ParserBase<Traits>::ExpressionT 2029 ParserBase<Traits>::ParseMemberExpression(bool* ok) { 2030 // MemberExpression :: 2031 // (PrimaryExpression | FunctionLiteral) 2032 // ('[' Expression ']' | '.' Identifier | Arguments)* 2033 2034 // The '[' Expression ']' and '.' Identifier parts are parsed by 2035 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the 2036 // caller. 2037 2038 // Parse the initial primary or function expression. 2039 ExpressionT result = this->EmptyExpression(); 2040 if (peek() == Token::FUNCTION) { 2041 Consume(Token::FUNCTION); 2042 int function_token_position = position(); 2043 bool is_generator = allow_generators() && Check(Token::MUL); 2044 IdentifierT name = this->EmptyIdentifier(); 2045 bool is_strict_reserved_name = false; 2046 Scanner::Location function_name_location = Scanner::Location::invalid(); 2047 FunctionLiteral::FunctionType function_type = 2048 FunctionLiteral::ANONYMOUS_EXPRESSION; 2049 if (peek_any_identifier()) { 2050 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, 2051 CHECK_OK); 2052 function_name_location = scanner()->location(); 2053 function_type = FunctionLiteral::NAMED_EXPRESSION; 2054 } 2055 result = this->ParseFunctionLiteral(name, 2056 function_name_location, 2057 is_strict_reserved_name, 2058 is_generator, 2059 function_token_position, 2060 function_type, 2061 FunctionLiteral::NORMAL_ARITY, 2062 CHECK_OK); 2063 } else { 2064 result = ParsePrimaryExpression(CHECK_OK); 2065 } 2066 2067 result = ParseMemberExpressionContinuation(result, CHECK_OK); 2068 return result; 2069 } 2070 2071 2072 template <class Traits> 2073 typename ParserBase<Traits>::ExpressionT 2074 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, 2075 bool* ok) { 2076 // Parses this part of MemberExpression: 2077 // ('[' Expression ']' | '.' Identifier)* 2078 while (true) { 2079 switch (peek()) { 2080 case Token::LBRACK: { 2081 Consume(Token::LBRACK); 2082 int pos = position(); 2083 ExpressionT index = this->ParseExpression(true, CHECK_OK); 2084 expression = factory()->NewProperty(expression, index, pos); 2085 if (fni_ != NULL) { 2086 this->PushPropertyName(fni_, index); 2087 } 2088 Expect(Token::RBRACK, CHECK_OK); 2089 break; 2090 } 2091 case Token::PERIOD: { 2092 Consume(Token::PERIOD); 2093 int pos = position(); 2094 IdentifierT name = ParseIdentifierName(CHECK_OK); 2095 expression = factory()->NewProperty( 2096 expression, factory()->NewLiteral(name, pos), pos); 2097 if (fni_ != NULL) { 2098 this->PushLiteralName(fni_, name); 2099 } 2100 break; 2101 } 2102 default: 2103 return expression; 2104 } 2105 } 2106 ASSERT(false); 2107 return this->EmptyExpression(); 2108 } 2109 2110 2111 template <typename Traits> 2112 typename ParserBase<Traits>::ExpressionT 2113 ParserBase<Traits>::CheckAndRewriteReferenceExpression( 2114 ExpressionT expression, 2115 Scanner::Location location, const char* message, bool* ok) { 2116 if (strict_mode() == STRICT && this->IsIdentifier(expression) && 2117 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 2118 this->ReportMessageAt(location, "strict_eval_arguments", false); 2119 *ok = false; 2120 return this->EmptyExpression(); 2121 } else if (expression->IsValidReferenceExpression()) { 2122 return expression; 2123 } else if (expression->IsCall()) { 2124 // If it is a call, make it a runtime error for legacy web compatibility. 2125 // Rewrite `expr' to `expr[throw ReferenceError]'. 2126 int pos = location.beg_pos; 2127 ExpressionT error = this->NewThrowReferenceError(message, pos); 2128 return factory()->NewProperty(expression, error, pos); 2129 } else { 2130 this->ReportMessageAt(location, message, true); 2131 *ok = false; 2132 return this->EmptyExpression(); 2133 } 2134 } 2135 2136 2137 #undef CHECK_OK 2138 #undef CHECK_OK_CUSTOM 2139 2140 2141 template <typename Traits> 2142 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( 2143 Token::Value property, 2144 PropertyKind type, 2145 bool* ok) { 2146 int old; 2147 if (property == Token::NUMBER) { 2148 old = scanner()->FindNumber(&finder_, type); 2149 } else { 2150 old = scanner()->FindSymbol(&finder_, type); 2151 } 2152 PropertyKind old_type = static_cast<PropertyKind>(old); 2153 if (HasConflict(old_type, type)) { 2154 if (IsDataDataConflict(old_type, type)) { 2155 // Both are data properties. 2156 if (strict_mode_ == SLOPPY) return; 2157 parser()->ReportMessage("strict_duplicate_property"); 2158 } else if (IsDataAccessorConflict(old_type, type)) { 2159 // Both a data and an accessor property with the same name. 2160 parser()->ReportMessage("accessor_data_property"); 2161 } else { 2162 ASSERT(IsAccessorAccessorConflict(old_type, type)); 2163 // Both accessors of the same type. 2164 parser()->ReportMessage("accessor_get_set"); 2165 } 2166 *ok = false; 2167 } 2168 } 2169 2170 2171 } } // v8::internal 2172 2173 #endif // V8_PREPARSER_H 2174