OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/func-name-inferrer.h" | 10 #include "src/func-name-inferrer.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 // }; | 55 // }; |
56 // // ... | 56 // // ... |
57 // }; | 57 // }; |
58 | 58 |
59 template <typename Traits> | 59 template <typename Traits> |
60 class ParserBase : public Traits { | 60 class ParserBase : public Traits { |
61 public: | 61 public: |
62 // Shorten type names defined by Traits. | 62 // Shorten type names defined by Traits. |
63 typedef typename Traits::Type::Expression ExpressionT; | 63 typedef typename Traits::Type::Expression ExpressionT; |
64 typedef typename Traits::Type::Identifier IdentifierT; | 64 typedef typename Traits::Type::Identifier IdentifierT; |
| 65 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; |
65 | 66 |
66 ParserBase(Scanner* scanner, uintptr_t stack_limit, | 67 ParserBase(Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension, |
67 v8::Extension* extension, | 68 ParserRecorder* log, typename Traits::Type::Zone* zone, |
68 ParserRecorder* log, | |
69 typename Traits::Type::Zone* zone, | |
70 typename Traits::Type::Parser this_object) | 69 typename Traits::Type::Parser this_object) |
71 : Traits(this_object), | 70 : Traits(this_object), |
72 parenthesized_function_(false), | 71 parenthesized_function_(false), |
73 scope_(NULL), | 72 scope_(NULL), |
74 function_state_(NULL), | 73 function_state_(NULL), |
75 extension_(extension), | 74 extension_(extension), |
76 fni_(NULL), | 75 fni_(NULL), |
77 log_(log), | 76 log_(log), |
78 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 77 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
79 scanner_(scanner), | 78 scanner_(scanner), |
80 stack_limit_(stack_limit), | 79 stack_limit_(stack_limit), |
81 stack_overflow_(false), | 80 stack_overflow_(false), |
82 allow_lazy_(false), | 81 allow_lazy_(false), |
83 allow_natives_syntax_(false), | 82 allow_natives_syntax_(false), |
84 allow_generators_(false), | 83 allow_generators_(false), |
85 allow_for_of_(false), | 84 allow_for_of_(false), |
86 zone_(zone) { } | 85 allow_arrow_functions_(false), |
| 86 zone_(zone) {} |
87 | 87 |
88 // Getters that indicate whether certain syntactical constructs are | 88 // Getters that indicate whether certain syntactical constructs are |
89 // allowed to be parsed by this instance of the parser. | 89 // allowed to be parsed by this instance of the parser. |
90 bool allow_lazy() const { return allow_lazy_; } | 90 bool allow_lazy() const { return allow_lazy_; } |
91 bool allow_natives_syntax() const { return allow_natives_syntax_; } | 91 bool allow_natives_syntax() const { return allow_natives_syntax_; } |
92 bool allow_generators() const { return allow_generators_; } | 92 bool allow_generators() const { return allow_generators_; } |
93 bool allow_for_of() const { return allow_for_of_; } | 93 bool allow_for_of() const { return allow_for_of_; } |
| 94 bool allow_arrow_functions() const { return allow_arrow_functions_; } |
94 bool allow_modules() const { return scanner()->HarmonyModules(); } | 95 bool allow_modules() const { return scanner()->HarmonyModules(); } |
95 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } | 96 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } |
96 bool allow_harmony_numeric_literals() const { | 97 bool allow_harmony_numeric_literals() const { |
97 return scanner()->HarmonyNumericLiterals(); | 98 return scanner()->HarmonyNumericLiterals(); |
98 } | 99 } |
99 | 100 |
100 // Setters that determine whether certain syntactical constructs are | 101 // Setters that determine whether certain syntactical constructs are |
101 // allowed to be parsed by this instance of the parser. | 102 // allowed to be parsed by this instance of the parser. |
102 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 103 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
103 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } | 104 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } |
104 void set_allow_generators(bool allow) { allow_generators_ = allow; } | 105 void set_allow_generators(bool allow) { allow_generators_ = allow; } |
105 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } | 106 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } |
| 107 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; } |
106 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } | 108 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } |
107 void set_allow_harmony_scoping(bool allow) { | 109 void set_allow_harmony_scoping(bool allow) { |
108 scanner()->SetHarmonyScoping(allow); | 110 scanner()->SetHarmonyScoping(allow); |
109 } | 111 } |
110 void set_allow_harmony_numeric_literals(bool allow) { | 112 void set_allow_harmony_numeric_literals(bool allow) { |
111 scanner()->SetHarmonyNumericLiterals(allow); | 113 scanner()->SetHarmonyNumericLiterals(allow); |
112 } | 114 } |
113 | 115 |
114 protected: | 116 protected: |
115 enum AllowEvalOrArgumentsAsIdentifier { | 117 enum AllowEvalOrArgumentsAsIdentifier { |
(...skipping 29 matching lines...) Expand all Loading... |
145 }; | 147 }; |
146 | 148 |
147 class FunctionState BASE_EMBEDDED { | 149 class FunctionState BASE_EMBEDDED { |
148 public: | 150 public: |
149 FunctionState( | 151 FunctionState( |
150 FunctionState** function_state_stack, | 152 FunctionState** function_state_stack, |
151 typename Traits::Type::Scope** scope_stack, | 153 typename Traits::Type::Scope** scope_stack, |
152 typename Traits::Type::Scope* scope, | 154 typename Traits::Type::Scope* scope, |
153 typename Traits::Type::Zone* zone = NULL, | 155 typename Traits::Type::Zone* zone = NULL, |
154 AstValueFactory* ast_value_factory = NULL); | 156 AstValueFactory* ast_value_factory = NULL); |
| 157 FunctionState(FunctionState** function_state_stack, |
| 158 typename Traits::Type::Scope** scope_stack, |
| 159 typename Traits::Type::Scope** scope, |
| 160 typename Traits::Type::Zone* zone = NULL, |
| 161 AstValueFactory* ast_value_factory = NULL); |
155 ~FunctionState(); | 162 ~FunctionState(); |
156 | 163 |
157 int NextMaterializedLiteralIndex() { | 164 int NextMaterializedLiteralIndex() { |
158 return next_materialized_literal_index_++; | 165 return next_materialized_literal_index_++; |
159 } | 166 } |
160 int materialized_literal_count() { | 167 int materialized_literal_count() { |
161 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; | 168 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; |
162 } | 169 } |
163 | 170 |
164 int NextHandlerIndex() { return next_handler_index_++; } | 171 int NextHandlerIndex() { return next_handler_index_++; } |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 ExpressionT ParseYieldExpression(bool* ok); | 441 ExpressionT ParseYieldExpression(bool* ok); |
435 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 442 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
436 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 443 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
437 ExpressionT ParseUnaryExpression(bool* ok); | 444 ExpressionT ParseUnaryExpression(bool* ok); |
438 ExpressionT ParsePostfixExpression(bool* ok); | 445 ExpressionT ParsePostfixExpression(bool* ok); |
439 ExpressionT ParseLeftHandSideExpression(bool* ok); | 446 ExpressionT ParseLeftHandSideExpression(bool* ok); |
440 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 447 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
441 ExpressionT ParseMemberExpression(bool* ok); | 448 ExpressionT ParseMemberExpression(bool* ok); |
442 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 449 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
443 bool* ok); | 450 bool* ok); |
| 451 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
| 452 bool* ok); |
| 453 ExpressionT ParseArrowFunctionLiteralBody( |
| 454 FunctionState* function_state, typename Traits::Type::ScopePtr scope, |
| 455 int num_parameters, const Scanner::Location& eval_args_error_loc, |
| 456 const Scanner::Location& dupe_error_loc, |
| 457 const Scanner::Location& reserved_loc, |
| 458 FunctionLiteral::IsParenthesizedFlag parenthesized, int start_pos, |
| 459 bool* ok); |
444 | 460 |
445 // Checks if the expression is a valid reference expression (e.g., on the | 461 // Checks if the expression is a valid reference expression (e.g., on the |
446 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 462 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
447 // we allow calls for web compatibility and rewrite them to a runtime throw. | 463 // we allow calls for web compatibility and rewrite them to a runtime throw. |
448 ExpressionT CheckAndRewriteReferenceExpression( | 464 ExpressionT CheckAndRewriteReferenceExpression( |
449 ExpressionT expression, | 465 ExpressionT expression, |
450 Scanner::Location location, const char* message, bool* ok); | 466 Scanner::Location location, const char* message, bool* ok); |
451 | 467 |
452 // Used to detect duplicates in object literals. Each of the values | 468 // Used to detect duplicates in object literals. Each of the values |
453 // kGetterProperty, kSetterProperty and kValueProperty represents | 469 // kGetterProperty, kSetterProperty and kValueProperty represents |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 | 534 |
519 private: | 535 private: |
520 Scanner* scanner_; | 536 Scanner* scanner_; |
521 uintptr_t stack_limit_; | 537 uintptr_t stack_limit_; |
522 bool stack_overflow_; | 538 bool stack_overflow_; |
523 | 539 |
524 bool allow_lazy_; | 540 bool allow_lazy_; |
525 bool allow_natives_syntax_; | 541 bool allow_natives_syntax_; |
526 bool allow_generators_; | 542 bool allow_generators_; |
527 bool allow_for_of_; | 543 bool allow_for_of_; |
| 544 bool allow_arrow_functions_; |
528 | 545 |
529 typename Traits::Type::Zone* zone_; // Only used by Parser. | 546 typename Traits::Type::Zone* zone_; // Only used by Parser. |
530 }; | 547 }; |
531 | 548 |
532 | 549 |
533 class PreParserIdentifier { | 550 class PreParserIdentifier { |
534 public: | 551 public: |
535 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 552 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
536 static PreParserIdentifier Default() { | 553 static PreParserIdentifier Default() { |
537 return PreParserIdentifier(kUnknownIdentifier); | 554 return PreParserIdentifier(kUnknownIdentifier); |
538 } | 555 } |
539 static PreParserIdentifier Eval() { | 556 static PreParserIdentifier Eval() { |
540 return PreParserIdentifier(kEvalIdentifier); | 557 return PreParserIdentifier(kEvalIdentifier); |
541 } | 558 } |
542 static PreParserIdentifier Arguments() { | 559 static PreParserIdentifier Arguments() { |
543 return PreParserIdentifier(kArgumentsIdentifier); | 560 return PreParserIdentifier(kArgumentsIdentifier); |
544 } | 561 } |
545 static PreParserIdentifier FutureReserved() { | 562 static PreParserIdentifier FutureReserved() { |
546 return PreParserIdentifier(kFutureReservedIdentifier); | 563 return PreParserIdentifier(kFutureReservedIdentifier); |
547 } | 564 } |
548 static PreParserIdentifier FutureStrictReserved() { | 565 static PreParserIdentifier FutureStrictReserved() { |
549 return PreParserIdentifier(kFutureStrictReservedIdentifier); | 566 return PreParserIdentifier(kFutureStrictReservedIdentifier); |
550 } | 567 } |
551 static PreParserIdentifier Yield() { | 568 static PreParserIdentifier Yield() { |
552 return PreParserIdentifier(kYieldIdentifier); | 569 return PreParserIdentifier(kYieldIdentifier); |
553 } | 570 } |
554 bool IsEval() { return type_ == kEvalIdentifier; } | 571 bool IsEval() const { return type_ == kEvalIdentifier; } |
555 bool IsArguments() { return type_ == kArgumentsIdentifier; } | 572 bool IsArguments() const { return type_ == kArgumentsIdentifier; } |
556 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } | 573 bool IsEvalOrArguments() const { return type_ >= kEvalIdentifier; } |
557 bool IsYield() { return type_ == kYieldIdentifier; } | 574 bool IsYield() const { return type_ == kYieldIdentifier; } |
558 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } | 575 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } |
559 bool IsFutureStrictReserved() { | 576 bool IsFutureStrictReserved() const { |
560 return type_ == kFutureStrictReservedIdentifier; | 577 return type_ == kFutureStrictReservedIdentifier; |
561 } | 578 } |
562 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } | 579 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; } |
| 580 |
| 581 // Allow identifier->name()[->length()] to work. The preparser |
| 582 // does not need the actual positions/lengths of the identifiers. |
| 583 const PreParserIdentifier* operator->() const { return this; } |
| 584 const PreParserIdentifier raw_name() const { return *this; } |
| 585 |
| 586 int position() const { return 0; } |
| 587 int length() const { return 0; } |
563 | 588 |
564 private: | 589 private: |
565 enum Type { | 590 enum Type { |
566 kUnknownIdentifier, | 591 kUnknownIdentifier, |
567 kFutureReservedIdentifier, | 592 kFutureReservedIdentifier, |
568 kFutureStrictReservedIdentifier, | 593 kFutureStrictReservedIdentifier, |
569 kYieldIdentifier, | 594 kYieldIdentifier, |
570 kEvalIdentifier, | 595 kEvalIdentifier, |
571 kArgumentsIdentifier | 596 kArgumentsIdentifier |
572 }; | 597 }; |
573 explicit PreParserIdentifier(Type type) : type_(type) {} | 598 explicit PreParserIdentifier(Type type) : type_(type) {} |
574 Type type_; | 599 Type type_; |
575 | 600 |
576 friend class PreParserExpression; | 601 friend class PreParserExpression; |
| 602 friend class PreParserScope; |
577 }; | 603 }; |
578 | 604 |
579 | 605 |
580 // Bits 0 and 1 are used to identify the type of expression: | 606 // Bits 0 and 1 are used to identify the type of expression: |
581 // If bit 0 is set, it's an identifier. | 607 // If bit 0 is set, it's an identifier. |
582 // if bit 1 is set, it's a string literal. | 608 // if bit 1 is set, it's a string literal. |
583 // If neither is set, it's no particular type, and both set isn't | 609 // If neither is set, it's no particular type, and both set isn't |
584 // use yet. | 610 // use yet. |
585 class PreParserExpression { | 611 class PreParserExpression { |
586 public: | 612 public: |
587 static PreParserExpression Default() { | 613 static PreParserExpression Default() { |
588 return PreParserExpression(kUnknownExpression); | 614 return PreParserExpression(kUnknownExpression); |
589 } | 615 } |
590 | 616 |
591 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 617 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
592 return PreParserExpression(kIdentifierFlag | | 618 return PreParserExpression(kTypeIdentifier | |
593 (id.type_ << kIdentifierShift)); | 619 (id.type_ << kIdentifierShift)); |
594 } | 620 } |
595 | 621 |
| 622 static PreParserExpression BinaryOperation(PreParserExpression left, |
| 623 Token::Value op, |
| 624 PreParserExpression right) { |
| 625 int code = ((op == Token::COMMA) && !left.is_parenthesized() && |
| 626 !right.is_parenthesized()) |
| 627 ? left.ArrowParamListBit() & right.ArrowParamListBit() |
| 628 : 0; |
| 629 return PreParserExpression(kTypeBinaryOperation | code); |
| 630 } |
| 631 |
| 632 static PreParserExpression EmptyArrowParamList() { |
| 633 // Any expression for which IsValidArrowParamList() returns true |
| 634 // will work here. |
| 635 return FromIdentifier(PreParserIdentifier::Default()); |
| 636 } |
| 637 |
596 static PreParserExpression StringLiteral() { | 638 static PreParserExpression StringLiteral() { |
597 return PreParserExpression(kUnknownStringLiteral); | 639 return PreParserExpression(kUnknownStringLiteral); |
598 } | 640 } |
599 | 641 |
600 static PreParserExpression UseStrictStringLiteral() { | 642 static PreParserExpression UseStrictStringLiteral() { |
601 return PreParserExpression(kUseStrictString); | 643 return PreParserExpression(kUseStrictString); |
602 } | 644 } |
603 | 645 |
604 static PreParserExpression This() { | 646 static PreParserExpression This() { |
605 return PreParserExpression(kThisExpression); | 647 return PreParserExpression(kThisExpression); |
606 } | 648 } |
607 | 649 |
608 static PreParserExpression ThisProperty() { | 650 static PreParserExpression ThisProperty() { |
609 return PreParserExpression(kThisPropertyExpression); | 651 return PreParserExpression(kThisPropertyExpression); |
610 } | 652 } |
611 | 653 |
612 static PreParserExpression Property() { | 654 static PreParserExpression Property() { |
613 return PreParserExpression(kPropertyExpression); | 655 return PreParserExpression(kPropertyExpression); |
614 } | 656 } |
615 | 657 |
616 static PreParserExpression Call() { | 658 static PreParserExpression Call() { |
617 return PreParserExpression(kCallExpression); | 659 return PreParserExpression(kCallExpression); |
618 } | 660 } |
619 | 661 |
620 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } | 662 bool IsIdentifier() const { return (code_ & kTypeMask) == kTypeIdentifier; } |
621 | 663 |
622 PreParserIdentifier AsIdentifier() { | 664 PreParserIdentifier AsIdentifier() const { |
623 ASSERT(IsIdentifier()); | 665 ASSERT(IsIdentifier()); |
624 return PreParserIdentifier( | 666 return PreParserIdentifier( |
625 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); | 667 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); |
626 } | 668 } |
627 | 669 |
628 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } | 670 bool IsStringLiteral() const { |
| 671 return (code_ & kTypeMask) == kTypeStringLiteral; |
| 672 } |
629 | 673 |
630 bool IsUseStrictLiteral() { | 674 bool IsUseStrictLiteral() { |
631 return (code_ & kStringLiteralMask) == kUseStrictString; | 675 return (code_ & kUseStrictString) == kUseStrictString; |
632 } | 676 } |
633 | 677 |
634 bool IsThis() { return code_ == kThisExpression; } | 678 bool IsThis() { return code_ == kThisExpression; } |
635 | 679 |
636 bool IsThisProperty() { return code_ == kThisPropertyExpression; } | 680 bool IsThisProperty() { return code_ == kThisPropertyExpression; } |
637 | 681 |
638 bool IsProperty() { | 682 bool IsProperty() { |
639 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; | 683 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; |
640 } | 684 } |
641 | 685 |
642 bool IsCall() { return code_ == kCallExpression; } | 686 bool IsCall() { return code_ == kCallExpression; } |
643 | 687 |
644 bool IsValidReferenceExpression() { | 688 bool IsValidReferenceExpression() { |
645 return IsIdentifier() || IsProperty(); | 689 return IsIdentifier() || IsProperty(); |
646 } | 690 } |
647 | 691 |
| 692 bool IsValidArrowParamList() const { |
| 693 return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0 && |
| 694 (code_ & kMultiParenthesizedExpression) == 0; |
| 695 } |
| 696 |
648 // At the moment PreParser doesn't track these expression types. | 697 // At the moment PreParser doesn't track these expression types. |
649 bool IsFunctionLiteral() const { return false; } | 698 bool IsFunctionLiteral() const { return false; } |
650 bool IsCallNew() const { return false; } | 699 bool IsCallNew() const { return false; } |
651 | 700 |
652 PreParserExpression AsFunctionLiteral() { return *this; } | 701 PreParserExpression AsFunctionLiteral() { return *this; } |
653 | 702 |
| 703 bool IsBinaryOperation() const { |
| 704 return (code_ & kTypeMask) == kTypeBinaryOperation; |
| 705 } |
| 706 |
| 707 bool is_parenthesized() const { |
| 708 return (code_ & kParenthesizedExpression) != 0; |
| 709 } |
| 710 |
| 711 void increase_parenthesization_level() { |
| 712 code_ |= is_parenthesized() ? kMultiParenthesizedExpression |
| 713 : kParenthesizedExpression; |
| 714 } |
| 715 |
654 // Dummy implementation for making expression->somefunc() work in both Parser | 716 // Dummy implementation for making expression->somefunc() work in both Parser |
655 // and PreParser. | 717 // and PreParser. |
656 PreParserExpression* operator->() { return this; } | 718 PreParserExpression* operator->() { return this; } |
657 | 719 |
658 // More dummy implementations of things PreParser doesn't need to track: | 720 // More dummy implementations of things PreParser doesn't need to track: |
659 void set_index(int index) {} // For YieldExpressions | 721 void set_index(int index) {} // For YieldExpressions |
660 void set_parenthesized() {} | 722 void set_parenthesized() {} |
661 | 723 |
| 724 int position() const { return RelocInfo::kNoPosition; } |
| 725 void set_function_token_position(int position) {} |
| 726 void set_ast_properties(int* ast_properties) {} |
| 727 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {} |
| 728 |
| 729 bool operator==(const PreParserExpression& other) const { |
| 730 return code_ == other.code_; |
| 731 } |
| 732 bool operator!=(const PreParserExpression& other) const { |
| 733 return code_ != other.code_; |
| 734 } |
| 735 |
662 private: | 736 private: |
663 // Least significant 2 bits are used as flags. Bits 0 and 1 represent | 737 // Least significant 2 bits are used as expression type. The third least |
664 // identifiers or strings literals, and are mutually exclusive, but can both | 738 // significant bit tracks whether an expression is parenthesized. If the |
665 // be absent. If the expression is an identifier or a string literal, the | 739 // expression is an identifier or a string literal, the other bits |
666 // other bits describe the type (see PreParserIdentifier::Type and string | 740 // describe the type/ (see PreParserIdentifier::Type and string literal |
667 // literal constants below). | 741 // constants below). For binary operations, the other bits are flags |
| 742 // which further describe the contents of the expression. |
668 enum { | 743 enum { |
669 kUnknownExpression = 0, | 744 kUnknownExpression = 0, |
| 745 kTypeMask = 1 | 2, |
| 746 kParenthesizedExpression = (1 << 2), |
| 747 kMultiParenthesizedExpression = (1 << 3), |
| 748 |
670 // Identifiers | 749 // Identifiers |
671 kIdentifierFlag = 1, // Used to detect labels. | 750 kTypeIdentifier = 1, // Used to detect labels. |
672 kIdentifierShift = 3, | 751 kIdentifierShift = 5, |
| 752 kTypeStringLiteral = 2, // Used to detect directive prologue. |
| 753 kUnknownStringLiteral = kTypeStringLiteral, |
| 754 kUseStrictString = kTypeStringLiteral | 32, |
| 755 kStringLiteralMask = kUseStrictString, |
673 | 756 |
674 kStringLiteralFlag = 2, // Used to detect directive prologue. | 757 // Binary operations. Those are needed to detect certain keywords and |
675 kUnknownStringLiteral = kStringLiteralFlag, | 758 // duplicated identifier in parameter lists for arrow functions, because |
676 kUseStrictString = kStringLiteralFlag | 8, | 759 // they are initially parsed as comma-separated expressions. |
677 kStringLiteralMask = kUseStrictString, | 760 kTypeBinaryOperation = 3, |
| 761 kBinaryOperationArrowParamList = (1 << 4), |
678 | 762 |
679 // Below here applies if neither identifier nor string literal. Reserve the | 763 // Below here applies if neither identifier nor string literal. Reserve the |
680 // 2 least significant bits for flags. | 764 // 2 least significant bits for flags. |
681 kThisExpression = 1 << 2, | 765 kThisExpression = (1 << 4), |
682 kThisPropertyExpression = 2 << 2, | 766 kThisPropertyExpression = (2 << 4), |
683 kPropertyExpression = 3 << 2, | 767 kPropertyExpression = (3 << 4), |
684 kCallExpression = 4 << 2 | 768 kCallExpression = (4 << 4) |
685 }; | 769 }; |
686 | 770 |
687 explicit PreParserExpression(int expression_code) : code_(expression_code) {} | 771 explicit PreParserExpression(int expression_code) : code_(expression_code) {} |
688 | 772 |
| 773 V8_INLINE int ArrowParamListBit() const { |
| 774 if (IsBinaryOperation()) return code_ & kBinaryOperationArrowParamList; |
| 775 if (IsIdentifier()) { |
| 776 const PreParserIdentifier ident = AsIdentifier(); |
| 777 // A valid identifier can be an arrow function parameter list |
| 778 // except for eval, arguments, yield, and reserved keywords. |
| 779 if (ident.IsEval() || ident.IsArguments() || ident.IsYield() || |
| 780 ident.IsFutureStrictReserved()) |
| 781 return 0; |
| 782 return kBinaryOperationArrowParamList; |
| 783 } |
| 784 return 0; |
| 785 } |
| 786 |
689 int code_; | 787 int code_; |
690 }; | 788 }; |
691 | 789 |
692 | 790 |
693 // PreParserExpressionList doesn't actually store the expressions because | 791 // PreParserExpressionList doesn't actually store the expressions because |
694 // PreParser doesn't need to. | 792 // PreParser doesn't need to. |
695 class PreParserExpressionList { | 793 class PreParserExpressionList { |
696 public: | 794 public: |
697 // These functions make list->Add(some_expression) work (and do nothing). | 795 // These functions make list->Add(some_expression) work (and do nothing). |
698 PreParserExpressionList() : length_(0) {} | 796 PreParserExpressionList() : length_(0) {} |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 public: | 858 public: |
761 // These functions make list->Add(some_expression) work as no-ops. | 859 // These functions make list->Add(some_expression) work as no-ops. |
762 PreParserStatementList() {} | 860 PreParserStatementList() {} |
763 PreParserStatementList* operator->() { return this; } | 861 PreParserStatementList* operator->() { return this; } |
764 void Add(PreParserStatement, void*) {} | 862 void Add(PreParserStatement, void*) {} |
765 }; | 863 }; |
766 | 864 |
767 | 865 |
768 class PreParserScope { | 866 class PreParserScope { |
769 public: | 867 public: |
770 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) | 868 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type, |
| 869 void* = NULL) |
771 : scope_type_(scope_type) { | 870 : scope_type_(scope_type) { |
772 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; | 871 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; |
773 } | 872 } |
774 | 873 |
775 ScopeType type() { return scope_type_; } | 874 ScopeType type() { return scope_type_; } |
776 StrictMode strict_mode() const { return strict_mode_; } | 875 StrictMode strict_mode() const { return strict_mode_; } |
777 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } | 876 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } |
778 | 877 |
| 878 // When PreParser is in use, lazy compilation is already being done, |
| 879 // things cannot get lazier than that. |
| 880 bool AllowsLazyCompilation() const { return false; } |
| 881 |
| 882 void set_start_position(int position) {} |
| 883 void set_end_position(int position) {} |
| 884 |
| 885 bool IsDeclared(const PreParserIdentifier& identifier) const { return false; } |
| 886 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) {} |
| 887 |
| 888 // Allow scope->Foo() to work. |
| 889 PreParserScope* operator->() { return this; } |
| 890 |
779 private: | 891 private: |
780 ScopeType scope_type_; | 892 ScopeType scope_type_; |
781 StrictMode strict_mode_; | 893 StrictMode strict_mode_; |
782 }; | 894 }; |
783 | 895 |
784 | 896 |
785 class PreParserFactory { | 897 class PreParserFactory { |
786 public: | 898 public: |
787 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} | 899 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} |
788 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, | 900 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
832 return PreParserExpression::Property(); | 944 return PreParserExpression::Property(); |
833 } | 945 } |
834 PreParserExpression NewUnaryOperation(Token::Value op, | 946 PreParserExpression NewUnaryOperation(Token::Value op, |
835 PreParserExpression expression, | 947 PreParserExpression expression, |
836 int pos) { | 948 int pos) { |
837 return PreParserExpression::Default(); | 949 return PreParserExpression::Default(); |
838 } | 950 } |
839 PreParserExpression NewBinaryOperation(Token::Value op, | 951 PreParserExpression NewBinaryOperation(Token::Value op, |
840 PreParserExpression left, | 952 PreParserExpression left, |
841 PreParserExpression right, int pos) { | 953 PreParserExpression right, int pos) { |
842 return PreParserExpression::Default(); | 954 return PreParserExpression::BinaryOperation(left, op, right); |
843 } | 955 } |
844 PreParserExpression NewCompareOperation(Token::Value op, | 956 PreParserExpression NewCompareOperation(Token::Value op, |
845 PreParserExpression left, | 957 PreParserExpression left, |
846 PreParserExpression right, int pos) { | 958 PreParserExpression right, int pos) { |
847 return PreParserExpression::Default(); | 959 return PreParserExpression::Default(); |
848 } | 960 } |
849 PreParserExpression NewAssignment(Token::Value op, | 961 PreParserExpression NewAssignment(Token::Value op, |
850 PreParserExpression left, | 962 PreParserExpression left, |
851 PreParserExpression right, | 963 PreParserExpression right, |
852 int pos) { | 964 int pos) { |
(...skipping 20 matching lines...) Expand all Loading... |
873 PreParserExpression NewCall(PreParserExpression expression, | 985 PreParserExpression NewCall(PreParserExpression expression, |
874 PreParserExpressionList arguments, | 986 PreParserExpressionList arguments, |
875 int pos) { | 987 int pos) { |
876 return PreParserExpression::Call(); | 988 return PreParserExpression::Call(); |
877 } | 989 } |
878 PreParserExpression NewCallNew(PreParserExpression expression, | 990 PreParserExpression NewCallNew(PreParserExpression expression, |
879 PreParserExpressionList arguments, | 991 PreParserExpressionList arguments, |
880 int pos) { | 992 int pos) { |
881 return PreParserExpression::Default(); | 993 return PreParserExpression::Default(); |
882 } | 994 } |
| 995 PreParserStatement NewReturnStatement(PreParserExpression expression, |
| 996 int pos) { |
| 997 return PreParserStatement::Default(); |
| 998 } |
| 999 PreParserExpression NewFunctionLiteral( |
| 1000 PreParserIdentifier name, AstValueFactory* ast_value_factory, |
| 1001 const PreParserScope& scope, PreParserStatementList body, |
| 1002 int materialized_literal_count, int expected_property_count, |
| 1003 int handler_count, int parameter_count, |
| 1004 FunctionLiteral::ParameterFlag has_duplicate_parameters, |
| 1005 FunctionLiteral::FunctionType function_type, |
| 1006 FunctionLiteral::IsFunctionFlag is_function, |
| 1007 FunctionLiteral::IsParenthesizedFlag is_parenthesized, |
| 1008 FunctionLiteral::IsGeneratorFlag is_generator, int position) { |
| 1009 return PreParserExpression::Default(); |
| 1010 } |
| 1011 |
| 1012 // Return the object itself as AstVisitor and implement the needed |
| 1013 // dummy method right in this class. |
| 1014 PreParserFactory* visitor() { return this; } |
| 1015 BailoutReason dont_optimize_reason() { return kNoReason; } |
| 1016 int* ast_properties() { |
| 1017 static int dummy = 42; |
| 1018 return &dummy; |
| 1019 } |
883 }; | 1020 }; |
884 | 1021 |
885 | 1022 |
886 class PreParser; | 1023 class PreParser; |
887 | 1024 |
888 class PreParserTraits { | 1025 class PreParserTraits { |
889 public: | 1026 public: |
890 struct Type { | 1027 struct Type { |
891 // TODO(marja): To be removed. The Traits object should contain all the data | 1028 // TODO(marja): To be removed. The Traits object should contain all the data |
892 // it needs. | 1029 // it needs. |
893 typedef PreParser* Parser; | 1030 typedef PreParser* Parser; |
894 | 1031 |
895 // Used by FunctionState and BlockState. | 1032 // Used by FunctionState and BlockState. |
896 typedef PreParserScope Scope; | 1033 typedef PreParserScope Scope; |
| 1034 typedef PreParserScope ScopePtr; |
| 1035 |
897 // PreParser doesn't need to store generator variables. | 1036 // PreParser doesn't need to store generator variables. |
898 typedef void GeneratorVariable; | 1037 typedef void GeneratorVariable; |
899 // No interaction with Zones. | 1038 // No interaction with Zones. |
900 typedef void Zone; | 1039 typedef void Zone; |
901 | 1040 |
| 1041 typedef int AstProperties; |
| 1042 typedef Vector<PreParserIdentifier> ParameterIdentifierVector; |
| 1043 |
902 // Return types for traversing functions. | 1044 // Return types for traversing functions. |
903 typedef PreParserIdentifier Identifier; | 1045 typedef PreParserIdentifier Identifier; |
904 typedef PreParserExpression Expression; | 1046 typedef PreParserExpression Expression; |
905 typedef PreParserExpression YieldExpression; | 1047 typedef PreParserExpression YieldExpression; |
906 typedef PreParserExpression FunctionLiteral; | 1048 typedef PreParserExpression FunctionLiteral; |
907 typedef PreParserExpression ObjectLiteralProperty; | 1049 typedef PreParserExpression ObjectLiteralProperty; |
908 typedef PreParserExpression Literal; | 1050 typedef PreParserExpression Literal; |
909 typedef PreParserExpressionList ExpressionList; | 1051 typedef PreParserExpressionList ExpressionList; |
910 typedef PreParserExpressionList PropertyList; | 1052 typedef PreParserExpressionList PropertyList; |
911 typedef PreParserStatementList StatementList; | 1053 typedef PreParserStatementList StatementList; |
(...skipping 22 matching lines...) Expand all Loading... |
934 } | 1076 } |
935 | 1077 |
936 static bool IsIdentifier(PreParserExpression expression) { | 1078 static bool IsIdentifier(PreParserExpression expression) { |
937 return expression.IsIdentifier(); | 1079 return expression.IsIdentifier(); |
938 } | 1080 } |
939 | 1081 |
940 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { | 1082 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { |
941 return expression.AsIdentifier(); | 1083 return expression.AsIdentifier(); |
942 } | 1084 } |
943 | 1085 |
| 1086 static bool IsFutureStrictReserved(PreParserIdentifier identifier) { |
| 1087 return identifier.IsYield() || identifier.IsFutureStrictReserved(); |
| 1088 } |
| 1089 |
944 static bool IsBoilerplateProperty(PreParserExpression property) { | 1090 static bool IsBoilerplateProperty(PreParserExpression property) { |
945 // PreParser doesn't count boilerplate properties. | 1091 // PreParser doesn't count boilerplate properties. |
946 return false; | 1092 return false; |
947 } | 1093 } |
948 | 1094 |
949 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { | 1095 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { |
950 return false; | 1096 return false; |
951 } | 1097 } |
952 | 1098 |
953 // Functions for encapsulating the differences between parsing and preparsing; | 1099 // Functions for encapsulating the differences between parsing and preparsing; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 return PreParserExpression::Default(); | 1143 return PreParserExpression::Default(); |
998 } | 1144 } |
999 PreParserExpression NewThrowSyntaxError( | 1145 PreParserExpression NewThrowSyntaxError( |
1000 const char* type, Handle<Object> arg, int pos) { | 1146 const char* type, Handle<Object> arg, int pos) { |
1001 return PreParserExpression::Default(); | 1147 return PreParserExpression::Default(); |
1002 } | 1148 } |
1003 PreParserExpression NewThrowTypeError( | 1149 PreParserExpression NewThrowTypeError( |
1004 const char* type, Handle<Object> arg, int pos) { | 1150 const char* type, Handle<Object> arg, int pos) { |
1005 return PreParserExpression::Default(); | 1151 return PreParserExpression::Default(); |
1006 } | 1152 } |
| 1153 PreParserScope NewScope(PreParserScope* outer_scope, ScopeType scope_type) { |
| 1154 return PreParserScope(outer_scope, scope_type); |
| 1155 } |
1007 | 1156 |
1008 // Reporting errors. | 1157 // Reporting errors. |
1009 void ReportMessageAt(Scanner::Location location, | 1158 void ReportMessageAt(Scanner::Location location, |
1010 const char* message, | 1159 const char* message, |
1011 const char* arg = NULL, | 1160 const char* arg = NULL, |
1012 bool is_reference_error = false); | 1161 bool is_reference_error = false); |
1013 void ReportMessageAt(int start_pos, | 1162 void ReportMessageAt(int start_pos, |
1014 int end_pos, | 1163 int end_pos, |
1015 const char* message, | 1164 const char* message, |
1016 const char* arg = NULL, | 1165 const char* arg = NULL, |
1017 bool is_reference_error = false); | 1166 bool is_reference_error = false); |
1018 | 1167 |
1019 // "null" return type creators. | 1168 // "null" return type creators. |
1020 static PreParserIdentifier EmptyIdentifier() { | 1169 static PreParserIdentifier EmptyIdentifier() { |
1021 return PreParserIdentifier::Default(); | 1170 return PreParserIdentifier::Default(); |
1022 } | 1171 } |
| 1172 static PreParserIdentifier EmptyIdentifierString() { |
| 1173 return PreParserIdentifier::Default(); |
| 1174 } |
1023 static PreParserExpression EmptyExpression() { | 1175 static PreParserExpression EmptyExpression() { |
1024 return PreParserExpression::Default(); | 1176 return PreParserExpression::Default(); |
1025 } | 1177 } |
| 1178 static PreParserExpression EmptyArrowParamList() { |
| 1179 return PreParserExpression::EmptyArrowParamList(); |
| 1180 } |
1026 static PreParserExpression EmptyLiteral() { | 1181 static PreParserExpression EmptyLiteral() { |
1027 return PreParserExpression::Default(); | 1182 return PreParserExpression::Default(); |
1028 } | 1183 } |
1029 static PreParserExpressionList NullExpressionList() { | 1184 static PreParserExpressionList NullExpressionList() { |
1030 return PreParserExpressionList(); | 1185 return PreParserExpressionList(); |
1031 } | 1186 } |
1032 | 1187 |
1033 // Odd-ball literal creators. | 1188 // Odd-ball literal creators. |
1034 static PreParserExpression GetLiteralTheHole(int position, | 1189 static PreParserExpression GetLiteralTheHole(int position, |
1035 PreParserFactory* factory) { | 1190 PreParserFactory* factory) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1069 } | 1224 } |
1070 | 1225 |
1071 static PreParserStatementList NewStatementList(int size, void* zone) { | 1226 static PreParserStatementList NewStatementList(int size, void* zone) { |
1072 return PreParserStatementList(); | 1227 return PreParserStatementList(); |
1073 } | 1228 } |
1074 | 1229 |
1075 static PreParserExpressionList NewPropertyList(int size, void* zone) { | 1230 static PreParserExpressionList NewPropertyList(int size, void* zone) { |
1076 return PreParserExpressionList(); | 1231 return PreParserExpressionList(); |
1077 } | 1232 } |
1078 | 1233 |
| 1234 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, |
| 1235 int* materialized_literal_count, |
| 1236 int* expected_property_count, bool* ok) { |
| 1237 UNREACHABLE(); |
| 1238 } |
| 1239 |
| 1240 V8_INLINE PreParserStatementList |
| 1241 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
| 1242 Variable* fvar, Token::Value fvar_init_op, |
| 1243 bool is_generator, bool* ok); |
| 1244 |
| 1245 // Utility functions |
| 1246 Vector<PreParserIdentifier> ParameterListFromExpression( |
| 1247 PreParserExpression expression, bool* ok) { |
| 1248 // TODO(aperez): Detect duplicated identifiers in paramlists. |
| 1249 *ok = expression.IsValidArrowParamList(); |
| 1250 return Vector<PreParserIdentifier>::empty(); |
| 1251 } |
| 1252 |
| 1253 static AstValueFactory* ast_value_factory() { return NULL; } |
| 1254 |
| 1255 void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {} |
| 1256 |
1079 // Temporary glue; these functions will move to ParserBase. | 1257 // Temporary glue; these functions will move to ParserBase. |
1080 PreParserExpression ParseV8Intrinsic(bool* ok); | 1258 PreParserExpression ParseV8Intrinsic(bool* ok); |
1081 PreParserExpression ParseFunctionLiteral( | 1259 PreParserExpression ParseFunctionLiteral( |
1082 PreParserIdentifier name, | 1260 PreParserIdentifier name, |
1083 Scanner::Location function_name_location, | 1261 Scanner::Location function_name_location, |
1084 bool name_is_strict_reserved, | 1262 bool name_is_strict_reserved, |
1085 bool is_generator, | 1263 bool is_generator, |
1086 int function_token_position, | 1264 int function_token_position, |
1087 FunctionLiteral::FunctionType type, | 1265 FunctionLiteral::FunctionType type, |
1088 FunctionLiteral::ArityRestriction arity_restriction, | 1266 FunctionLiteral::ArityRestriction arity_restriction, |
(...skipping 30 matching lines...) Expand all Loading... |
1119 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) | 1297 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) |
1120 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, | 1298 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, |
1121 this) {} | 1299 this) {} |
1122 | 1300 |
1123 // Pre-parse the program from the character stream; returns true on | 1301 // Pre-parse the program from the character stream; returns true on |
1124 // success (even if parsing failed, the pre-parse data successfully | 1302 // success (even if parsing failed, the pre-parse data successfully |
1125 // captured the syntax error), and false if a stack-overflow happened | 1303 // captured the syntax error), and false if a stack-overflow happened |
1126 // during parsing. | 1304 // during parsing. |
1127 PreParseResult PreParseProgram() { | 1305 PreParseResult PreParseProgram() { |
1128 PreParserScope scope(scope_, GLOBAL_SCOPE); | 1306 PreParserScope scope(scope_, GLOBAL_SCOPE); |
1129 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); | 1307 FunctionState top_scope(&function_state_, &scope_, &scope); |
1130 bool ok = true; | 1308 bool ok = true; |
1131 int start_position = scanner()->peek_location().beg_pos; | 1309 int start_position = scanner()->peek_location().beg_pos; |
1132 ParseSourceElements(Token::EOS, &ok); | 1310 ParseSourceElements(Token::EOS, &ok); |
1133 if (stack_overflow()) return kPreParseStackOverflow; | 1311 if (stack_overflow()) return kPreParseStackOverflow; |
1134 if (!ok) { | 1312 if (!ok) { |
1135 ReportUnexpectedToken(scanner()->current_token()); | 1313 ReportUnexpectedToken(scanner()->current_token()); |
1136 } else if (scope_->strict_mode() == STRICT) { | 1314 } else if (scope_->strict_mode() == STRICT) { |
1137 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); | 1315 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); |
1138 } | 1316 } |
1139 return kPreParseSuccess; | 1317 return kPreParseSuccess; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 Statement ParseDoWhileStatement(bool* ok); | 1379 Statement ParseDoWhileStatement(bool* ok); |
1202 Statement ParseWhileStatement(bool* ok); | 1380 Statement ParseWhileStatement(bool* ok); |
1203 Statement ParseForStatement(bool* ok); | 1381 Statement ParseForStatement(bool* ok); |
1204 Statement ParseThrowStatement(bool* ok); | 1382 Statement ParseThrowStatement(bool* ok); |
1205 Statement ParseTryStatement(bool* ok); | 1383 Statement ParseTryStatement(bool* ok); |
1206 Statement ParseDebuggerStatement(bool* ok); | 1384 Statement ParseDebuggerStatement(bool* ok); |
1207 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 1385 Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
1208 Expression ParseObjectLiteral(bool* ok); | 1386 Expression ParseObjectLiteral(bool* ok); |
1209 Expression ParseV8Intrinsic(bool* ok); | 1387 Expression ParseV8Intrinsic(bool* ok); |
1210 | 1388 |
| 1389 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, |
| 1390 int* materialized_literal_count, |
| 1391 int* expected_property_count, bool* ok); |
| 1392 V8_INLINE PreParserStatementList |
| 1393 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
| 1394 Variable* fvar, Token::Value fvar_init_op, |
| 1395 bool is_generator, bool* ok); |
| 1396 |
1211 Expression ParseFunctionLiteral( | 1397 Expression ParseFunctionLiteral( |
1212 Identifier name, | 1398 Identifier name, |
1213 Scanner::Location function_name_location, | 1399 Scanner::Location function_name_location, |
1214 bool name_is_strict_reserved, | 1400 bool name_is_strict_reserved, |
1215 bool is_generator, | 1401 bool is_generator, |
1216 int function_token_pos, | 1402 int function_token_pos, |
1217 FunctionLiteral::FunctionType function_type, | 1403 FunctionLiteral::FunctionType function_type, |
1218 FunctionLiteral::ArityRestriction arity_restriction, | 1404 FunctionLiteral::ArityRestriction arity_restriction, |
1219 bool* ok); | 1405 bool* ok); |
1220 void ParseLazyFunctionLiteralBody(bool* ok); | 1406 void ParseLazyFunctionLiteralBody(bool* ok); |
1221 | 1407 |
1222 bool CheckInOrOf(bool accept_OF); | 1408 bool CheckInOrOf(bool accept_OF); |
1223 }; | 1409 }; |
1224 | 1410 |
| 1411 |
| 1412 PreParserStatementList PreParser::ParseEagerFunctionBody( |
| 1413 PreParserIdentifier function_name, int pos, Variable* fvar, |
| 1414 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
| 1415 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 1416 |
| 1417 ParseSourceElements(Token::RBRACE, ok); |
| 1418 if (!*ok) return PreParserStatementList(); |
| 1419 |
| 1420 Expect(Token::RBRACE, ok); |
| 1421 return PreParserStatementList(); |
| 1422 } |
| 1423 |
| 1424 |
| 1425 PreParserStatementList PreParserTraits::ParseEagerFunctionBody( |
| 1426 PreParserIdentifier function_name, int pos, Variable* fvar, |
| 1427 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
| 1428 return pre_parser_->ParseEagerFunctionBody(function_name, pos, fvar, |
| 1429 fvar_init_op, is_generator, ok); |
| 1430 } |
| 1431 |
| 1432 |
1225 template<class Traits> | 1433 template<class Traits> |
1226 ParserBase<Traits>::FunctionState::FunctionState( | 1434 ParserBase<Traits>::FunctionState::FunctionState( |
1227 FunctionState** function_state_stack, | 1435 FunctionState** function_state_stack, |
1228 typename Traits::Type::Scope** scope_stack, | 1436 typename Traits::Type::Scope** scope_stack, |
1229 typename Traits::Type::Scope* scope, | 1437 typename Traits::Type::Scope* scope, |
1230 typename Traits::Type::Zone* extra_param, | 1438 typename Traits::Type::Zone* extra_param, |
1231 AstValueFactory* ast_value_factory) | 1439 AstValueFactory* ast_value_factory) |
1232 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | 1440 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
1233 next_handler_index_(0), | 1441 next_handler_index_(0), |
1234 expected_property_count_(0), | 1442 expected_property_count_(0), |
1235 is_generator_(false), | 1443 is_generator_(false), |
1236 generator_object_variable_(NULL), | 1444 generator_object_variable_(NULL), |
1237 function_state_stack_(function_state_stack), | 1445 function_state_stack_(function_state_stack), |
1238 outer_function_state_(*function_state_stack), | 1446 outer_function_state_(*function_state_stack), |
1239 scope_stack_(scope_stack), | 1447 scope_stack_(scope_stack), |
1240 outer_scope_(*scope_stack), | 1448 outer_scope_(*scope_stack), |
1241 saved_ast_node_id_(0), | 1449 saved_ast_node_id_(0), |
1242 extra_param_(extra_param), | 1450 extra_param_(extra_param), |
1243 factory_(extra_param, ast_value_factory) { | 1451 factory_(extra_param, ast_value_factory) { |
1244 *scope_stack_ = scope; | 1452 *scope_stack_ = scope; |
1245 *function_state_stack = this; | 1453 *function_state_stack = this; |
1246 Traits::SetUpFunctionState(this, extra_param); | 1454 Traits::SetUpFunctionState(this, extra_param); |
1247 } | 1455 } |
1248 | 1456 |
1249 | 1457 |
1250 template<class Traits> | 1458 template <class Traits> |
| 1459 ParserBase<Traits>::FunctionState::FunctionState( |
| 1460 FunctionState** function_state_stack, |
| 1461 typename Traits::Type::Scope** scope_stack, |
| 1462 typename Traits::Type::Scope** scope, |
| 1463 typename Traits::Type::Zone* extra_param, |
| 1464 AstValueFactory* ast_value_factory) |
| 1465 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
| 1466 next_handler_index_(0), |
| 1467 expected_property_count_(0), |
| 1468 is_generator_(false), |
| 1469 generator_object_variable_(NULL), |
| 1470 function_state_stack_(function_state_stack), |
| 1471 outer_function_state_(*function_state_stack), |
| 1472 scope_stack_(scope_stack), |
| 1473 outer_scope_(*scope_stack), |
| 1474 saved_ast_node_id_(0), |
| 1475 extra_param_(extra_param), |
| 1476 factory_(extra_param, ast_value_factory) { |
| 1477 *scope_stack_ = *scope; |
| 1478 *function_state_stack = this; |
| 1479 Traits::SetUpFunctionState(this, extra_param); |
| 1480 } |
| 1481 |
| 1482 |
| 1483 template <class Traits> |
1251 ParserBase<Traits>::FunctionState::~FunctionState() { | 1484 ParserBase<Traits>::FunctionState::~FunctionState() { |
1252 *scope_stack_ = outer_scope_; | 1485 *scope_stack_ = outer_scope_; |
1253 *function_state_stack_ = outer_function_state_; | 1486 *function_state_stack_ = outer_function_state_; |
1254 Traits::TearDownFunctionState(this, extra_param_); | 1487 Traits::TearDownFunctionState(this, extra_param_); |
1255 } | 1488 } |
1256 | 1489 |
1257 | 1490 |
1258 template<class Traits> | 1491 template<class Traits> |
1259 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { | 1492 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { |
1260 Scanner::Location source_location = scanner()->location(); | 1493 Scanner::Location source_location = scanner()->location(); |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1452 case Token::LBRACK: | 1685 case Token::LBRACK: |
1453 result = this->ParseArrayLiteral(CHECK_OK); | 1686 result = this->ParseArrayLiteral(CHECK_OK); |
1454 break; | 1687 break; |
1455 | 1688 |
1456 case Token::LBRACE: | 1689 case Token::LBRACE: |
1457 result = this->ParseObjectLiteral(CHECK_OK); | 1690 result = this->ParseObjectLiteral(CHECK_OK); |
1458 break; | 1691 break; |
1459 | 1692 |
1460 case Token::LPAREN: | 1693 case Token::LPAREN: |
1461 Consume(Token::LPAREN); | 1694 Consume(Token::LPAREN); |
1462 // Heuristically try to detect immediately called functions before | 1695 if (allow_arrow_functions() && peek() == Token::RPAREN) { |
1463 // seeing the call parentheses. | 1696 // Arrow functions are the only expression type constructions |
1464 parenthesized_function_ = (peek() == Token::FUNCTION); | 1697 // for which an empty parameter list "()" is valid input. |
1465 result = this->ParseExpression(true, CHECK_OK); | 1698 Consume(Token::RPAREN); |
1466 Expect(Token::RPAREN, CHECK_OK); | 1699 return this->ParseArrowFunctionLiteral(pos, this->EmptyArrowParamList(), |
| 1700 CHECK_OK); |
| 1701 } else { |
| 1702 // Heuristically try to detect immediately called functions before |
| 1703 // seeing the call parentheses. |
| 1704 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 1705 result = this->ParseExpression(true, CHECK_OK); |
| 1706 result->increase_parenthesization_level(); |
| 1707 Expect(Token::RPAREN, CHECK_OK); |
| 1708 } |
1467 break; | 1709 break; |
1468 | 1710 |
1469 case Token::MOD: | 1711 case Token::MOD: |
1470 if (allow_natives_syntax() || extension_ != NULL) { | 1712 if (allow_natives_syntax() || extension_ != NULL) { |
1471 result = this->ParseV8Intrinsic(CHECK_OK); | 1713 result = this->ParseV8Intrinsic(CHECK_OK); |
1472 break; | 1714 break; |
1473 } | 1715 } |
1474 // If we're not allowing special syntax we fall-through to the | 1716 // If we're not allowing special syntax we fall-through to the |
1475 // default case. | 1717 // default case. |
1476 | 1718 |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1724 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 1966 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
1725 return result; | 1967 return result; |
1726 } | 1968 } |
1727 | 1969 |
1728 // Precedence = 2 | 1970 // Precedence = 2 |
1729 template <class Traits> | 1971 template <class Traits> |
1730 typename ParserBase<Traits>::ExpressionT | 1972 typename ParserBase<Traits>::ExpressionT |
1731 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 1973 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
1732 // AssignmentExpression :: | 1974 // AssignmentExpression :: |
1733 // ConditionalExpression | 1975 // ConditionalExpression |
| 1976 // ArrowFunction |
1734 // YieldExpression | 1977 // YieldExpression |
1735 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 1978 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
1736 | 1979 |
1737 Scanner::Location lhs_location = scanner()->peek_location(); | 1980 Scanner::Location lhs_location = scanner()->peek_location(); |
1738 | 1981 |
1739 if (peek() == Token::YIELD && is_generator()) { | 1982 if (peek() == Token::YIELD && is_generator()) { |
1740 return this->ParseYieldExpression(ok); | 1983 return this->ParseYieldExpression(ok); |
1741 } | 1984 } |
1742 | 1985 |
1743 if (fni_ != NULL) fni_->Enter(); | 1986 if (fni_ != NULL) fni_->Enter(); |
1744 ExpressionT expression = | 1987 ExpressionT expression = |
1745 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 1988 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
1746 | 1989 |
| 1990 if (allow_arrow_functions() && peek() == Token::ARROW) |
| 1991 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos, expression, |
| 1992 CHECK_OK); |
| 1993 |
1747 if (!Token::IsAssignmentOp(peek())) { | 1994 if (!Token::IsAssignmentOp(peek())) { |
1748 if (fni_ != NULL) fni_->Leave(); | 1995 if (fni_ != NULL) fni_->Leave(); |
1749 // Parsed conditional expression only (no assignment). | 1996 // Parsed conditional expression only (no assignment). |
1750 return expression; | 1997 return expression; |
1751 } | 1998 } |
1752 | 1999 |
1753 expression = this->CheckAndRewriteReferenceExpression( | 2000 expression = this->CheckAndRewriteReferenceExpression( |
1754 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 2001 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); |
1755 expression = this->MarkExpressionAsAssigned(expression); | 2002 expression = this->MarkExpressionAsAssigned(expression); |
1756 | 2003 |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2163 } | 2410 } |
2164 default: | 2411 default: |
2165 return expression; | 2412 return expression; |
2166 } | 2413 } |
2167 } | 2414 } |
2168 ASSERT(false); | 2415 ASSERT(false); |
2169 return this->EmptyExpression(); | 2416 return this->EmptyExpression(); |
2170 } | 2417 } |
2171 | 2418 |
2172 | 2419 |
| 2420 template <class Traits> |
| 2421 typename ParserBase<Traits>::ExpressionT ParserBase< |
| 2422 Traits>::ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
| 2423 bool* ok) { |
| 2424 typename Traits::Type::ParameterIdentifierVector params = |
| 2425 Traits::ParameterListFromExpression(params_ast, ok); |
| 2426 |
| 2427 if (!*ok) { |
| 2428 ReportMessageAt(Scanner::Location(start_pos, scanner()->location().beg_pos), |
| 2429 "malformed_arrow_function_parameter_list"); |
| 2430 return this->EmptyExpression(); |
| 2431 } |
| 2432 |
| 2433 // TODO(aperez): Change this to use ARROW_SCOPE |
| 2434 typename Traits::Type::ScopePtr scope = |
| 2435 this->NewScope(scope_, FUNCTION_SCOPE); |
| 2436 |
| 2437 FunctionState function_state(&function_state_, &scope_, &scope, zone(), |
| 2438 this->ast_value_factory()); |
| 2439 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
| 2440 |
| 2441 if (params.length() > Code::kMaxArguments) { |
| 2442 ReportMessageAt(Scanner::Location(params_ast->position(), position()), |
| 2443 "too_many_parameters"); |
| 2444 *ok = false; |
| 2445 return this->EmptyExpression(); |
| 2446 } |
| 2447 |
| 2448 for (int i = 0; i < params.length(); ++i) { |
| 2449 const IdentifierT param_name = params.at(i)->raw_name(); |
| 2450 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { |
| 2451 int param_pos = params.at(i)->position(); |
| 2452 dupe_error_loc = |
| 2453 Scanner::Location(param_pos, param_pos + param_name->length()); |
| 2454 } |
| 2455 scope_->DeclareParameter(param_name, VAR); |
| 2456 } |
| 2457 |
| 2458 ExpressionT expression = ParseArrowFunctionLiteralBody( |
| 2459 &function_state, scope, params.length(), Scanner::Location::invalid(), |
| 2460 dupe_error_loc, Scanner::Location::invalid(), |
| 2461 FunctionLiteral::kNotParenthesized, start_pos, CHECK_OK); |
| 2462 return expression; |
| 2463 } |
| 2464 |
| 2465 |
| 2466 template <class Traits> |
| 2467 typename ParserBase<Traits>::ExpressionT |
| 2468 ParserBase<Traits>::ParseArrowFunctionLiteralBody( |
| 2469 FunctionState* function_state, typename Traits::Type::ScopePtr scope, |
| 2470 int num_parameters, const Scanner::Location& eval_args_error_loc, |
| 2471 const Scanner::Location& dupe_error_loc, |
| 2472 const Scanner::Location& reserved_loc, |
| 2473 FunctionLiteral::IsParenthesizedFlag parenthesized, int start_pos, |
| 2474 bool* ok) { |
| 2475 int materialized_literal_count = -1; |
| 2476 int expected_property_count = -1; |
| 2477 |
| 2478 Expect(Token::ARROW, CHECK_OK); |
| 2479 |
| 2480 if (peek() == Token::LBRACE) { |
| 2481 // Multiple statemente body |
| 2482 Consume(Token::LBRACE); |
| 2483 bool is_lazily_parsed = |
| 2484 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
| 2485 if (is_lazily_parsed) { |
| 2486 this->SkipLazyFunctionBody(this->EmptyIdentifier(), |
| 2487 &materialized_literal_count, |
| 2488 &expected_property_count, CHECK_OK); |
| 2489 } else { |
| 2490 this->ParseEagerFunctionBody(this->EmptyIdentifier(), |
| 2491 RelocInfo::kNoPosition, NULL, |
| 2492 Token::INIT_VAR, false, // Not a generator. |
| 2493 CHECK_OK); |
| 2494 } |
| 2495 } else { |
| 2496 // Single-expression body |
| 2497 ParseAssignmentExpression(true, CHECK_OK); |
| 2498 } |
| 2499 |
| 2500 scope->set_start_position(start_pos); |
| 2501 scope->set_end_position(scanner()->location().end_pos); |
| 2502 |
| 2503 // Arrow function *parameter lists* are always checked as in strict mode. |
| 2504 this->CheckStrictFunctionNameAndParameters( |
| 2505 this->EmptyIdentifier(), false, Scanner::Location::invalid(), |
| 2506 Scanner::Location::invalid(), dupe_error_loc, |
| 2507 Scanner::Location::invalid(), CHECK_OK); |
| 2508 |
| 2509 // Validate strict mode. |
| 2510 if (strict_mode() == STRICT) { |
| 2511 CheckOctalLiteral(start_pos, scanner()->location().end_pos, CHECK_OK); |
| 2512 } |
| 2513 |
| 2514 if (allow_harmony_scoping() && strict_mode() == STRICT) |
| 2515 this->CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 2516 |
| 2517 // TODO(aperez): Generate a proper FunctionLiteral instead of |
| 2518 // returning a dummy value. |
| 2519 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| 2520 this->EmptyIdentifierString(), this->ast_value_factory(), scope, |
| 2521 this->NewStatementList(0, zone()), 0, 0, 0, num_parameters, |
| 2522 FunctionLiteral::kNoDuplicateParameters, |
| 2523 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, |
| 2524 FunctionLiteral::kNotParenthesized, FunctionLiteral::kNotGenerator, |
| 2525 start_pos); |
| 2526 function_literal->set_function_token_position(start_pos); |
| 2527 return function_literal; |
| 2528 } |
| 2529 |
| 2530 |
2173 template <typename Traits> | 2531 template <typename Traits> |
2174 typename ParserBase<Traits>::ExpressionT | 2532 typename ParserBase<Traits>::ExpressionT |
2175 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 2533 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
2176 ExpressionT expression, | 2534 ExpressionT expression, |
2177 Scanner::Location location, const char* message, bool* ok) { | 2535 Scanner::Location location, const char* message, bool* ok) { |
2178 if (strict_mode() == STRICT && this->IsIdentifier(expression) && | 2536 if (strict_mode() == STRICT && this->IsIdentifier(expression) && |
2179 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 2537 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
2180 this->ReportMessageAt(location, "strict_eval_arguments", false); | 2538 this->ReportMessageAt(location, "strict_eval_arguments", false); |
2181 *ok = false; | 2539 *ok = false; |
2182 return this->EmptyExpression(); | 2540 return this->EmptyExpression(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2226 parser()->ReportMessage("accessor_get_set"); | 2584 parser()->ReportMessage("accessor_get_set"); |
2227 } | 2585 } |
2228 *ok = false; | 2586 *ok = false; |
2229 } | 2587 } |
2230 } | 2588 } |
2231 | 2589 |
2232 | 2590 |
2233 } } // v8::internal | 2591 } } // v8::internal |
2234 | 2592 |
2235 #endif // V8_PREPARSER_H | 2593 #endif // V8_PREPARSER_H |
OLD | NEW |