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 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 ExpressionT ParseYieldExpression(bool* ok); | 442 ExpressionT ParseYieldExpression(bool* ok); |
436 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 443 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
437 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 444 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
438 ExpressionT ParseUnaryExpression(bool* ok); | 445 ExpressionT ParseUnaryExpression(bool* ok); |
439 ExpressionT ParsePostfixExpression(bool* ok); | 446 ExpressionT ParsePostfixExpression(bool* ok); |
440 ExpressionT ParseLeftHandSideExpression(bool* ok); | 447 ExpressionT ParseLeftHandSideExpression(bool* ok); |
441 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 448 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
442 ExpressionT ParseMemberExpression(bool* ok); | 449 ExpressionT ParseMemberExpression(bool* ok); |
443 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 450 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
444 bool* ok); | 451 bool* ok); |
| 452 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
| 453 bool* ok); |
| 454 ExpressionT ParseArrowFunctionLiteralBody( |
| 455 FunctionState* function_state, typename Traits::Type::ScopePtr scope, |
| 456 int num_parameters, const Scanner::Location& eval_args_error_loc, |
| 457 const Scanner::Location& dupe_error_loc, |
| 458 const Scanner::Location& reserved_loc, |
| 459 FunctionLiteral::IsParenthesizedFlag parenthesized, int start_pos, |
| 460 bool* ok); |
445 | 461 |
446 // Checks if the expression is a valid reference expression (e.g., on the | 462 // Checks if the expression is a valid reference expression (e.g., on the |
447 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 463 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
448 // we allow calls for web compatibility and rewrite them to a runtime throw. | 464 // we allow calls for web compatibility and rewrite them to a runtime throw. |
449 ExpressionT CheckAndRewriteReferenceExpression( | 465 ExpressionT CheckAndRewriteReferenceExpression( |
450 ExpressionT expression, | 466 ExpressionT expression, |
451 Scanner::Location location, const char* message, bool* ok); | 467 Scanner::Location location, const char* message, bool* ok); |
452 | 468 |
453 // Used to detect duplicates in object literals. Each of the values | 469 // Used to detect duplicates in object literals. Each of the values |
454 // kGetterProperty, kSetterProperty and kValueProperty represents | 470 // kGetterProperty, kSetterProperty and kValueProperty represents |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 | 535 |
520 private: | 536 private: |
521 Scanner* scanner_; | 537 Scanner* scanner_; |
522 uintptr_t stack_limit_; | 538 uintptr_t stack_limit_; |
523 bool stack_overflow_; | 539 bool stack_overflow_; |
524 | 540 |
525 bool allow_lazy_; | 541 bool allow_lazy_; |
526 bool allow_natives_syntax_; | 542 bool allow_natives_syntax_; |
527 bool allow_generators_; | 543 bool allow_generators_; |
528 bool allow_for_of_; | 544 bool allow_for_of_; |
| 545 bool allow_arrow_functions_; |
529 | 546 |
530 typename Traits::Type::Zone* zone_; // Only used by Parser. | 547 typename Traits::Type::Zone* zone_; // Only used by Parser. |
531 }; | 548 }; |
532 | 549 |
533 | 550 |
534 class PreParserIdentifier { | 551 class PreParserIdentifier { |
535 public: | 552 public: |
536 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 553 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
537 static PreParserIdentifier Default() { | 554 static PreParserIdentifier Default() { |
538 return PreParserIdentifier(kUnknownIdentifier); | 555 return PreParserIdentifier(kUnknownIdentifier); |
539 } | 556 } |
540 static PreParserIdentifier Eval() { | 557 static PreParserIdentifier Eval() { |
541 return PreParserIdentifier(kEvalIdentifier); | 558 return PreParserIdentifier(kEvalIdentifier); |
542 } | 559 } |
543 static PreParserIdentifier Arguments() { | 560 static PreParserIdentifier Arguments() { |
544 return PreParserIdentifier(kArgumentsIdentifier); | 561 return PreParserIdentifier(kArgumentsIdentifier); |
545 } | 562 } |
546 static PreParserIdentifier FutureReserved() { | 563 static PreParserIdentifier FutureReserved() { |
547 return PreParserIdentifier(kFutureReservedIdentifier); | 564 return PreParserIdentifier(kFutureReservedIdentifier); |
548 } | 565 } |
549 static PreParserIdentifier FutureStrictReserved() { | 566 static PreParserIdentifier FutureStrictReserved() { |
550 return PreParserIdentifier(kFutureStrictReservedIdentifier); | 567 return PreParserIdentifier(kFutureStrictReservedIdentifier); |
551 } | 568 } |
552 static PreParserIdentifier Let() { | 569 static PreParserIdentifier Let() { |
553 return PreParserIdentifier(kLetIdentifier); | 570 return PreParserIdentifier(kLetIdentifier); |
554 } | 571 } |
555 static PreParserIdentifier Yield() { | 572 static PreParserIdentifier Yield() { |
556 return PreParserIdentifier(kYieldIdentifier); | 573 return PreParserIdentifier(kYieldIdentifier); |
557 } | 574 } |
558 bool IsEval() { return type_ == kEvalIdentifier; } | 575 bool IsEval() const { return type_ == kEvalIdentifier; } |
559 bool IsArguments() { return type_ == kArgumentsIdentifier; } | 576 bool IsArguments() const { return type_ == kArgumentsIdentifier; } |
560 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } | 577 bool IsEvalOrArguments() const { return type_ >= kEvalIdentifier; } |
561 bool IsYield() { return type_ == kYieldIdentifier; } | 578 bool IsYield() const { return type_ == kYieldIdentifier; } |
562 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } | 579 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } |
563 bool IsFutureStrictReserved() { | 580 bool IsFutureStrictReserved() const { |
564 return type_ == kFutureStrictReservedIdentifier; | 581 return type_ == kFutureStrictReservedIdentifier; |
565 } | 582 } |
566 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } | 583 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; } |
| 584 |
| 585 // Allow identifier->name()[->length()] to work. The preparser |
| 586 // does not need the actual positions/lengths of the identifiers. |
| 587 const PreParserIdentifier* operator->() const { return this; } |
| 588 const PreParserIdentifier raw_name() const { return *this; } |
| 589 |
| 590 int position() const { return 0; } |
| 591 int length() const { return 0; } |
567 | 592 |
568 private: | 593 private: |
569 enum Type { | 594 enum Type { |
570 kUnknownIdentifier, | 595 kUnknownIdentifier, |
571 kFutureReservedIdentifier, | 596 kFutureReservedIdentifier, |
572 kFutureStrictReservedIdentifier, | 597 kFutureStrictReservedIdentifier, |
573 kLetIdentifier, | 598 kLetIdentifier, |
574 kYieldIdentifier, | 599 kYieldIdentifier, |
575 kEvalIdentifier, | 600 kEvalIdentifier, |
576 kArgumentsIdentifier | 601 kArgumentsIdentifier |
577 }; | 602 }; |
578 explicit PreParserIdentifier(Type type) : type_(type) {} | 603 explicit PreParserIdentifier(Type type) : type_(type) {} |
579 Type type_; | 604 Type type_; |
580 | 605 |
581 friend class PreParserExpression; | 606 friend class PreParserExpression; |
| 607 friend class PreParserScope; |
582 }; | 608 }; |
583 | 609 |
584 | 610 |
585 // Bits 0 and 1 are used to identify the type of expression: | 611 // Bits 0 and 1 are used to identify the type of expression: |
586 // If bit 0 is set, it's an identifier. | 612 // If bit 0 is set, it's an identifier. |
587 // if bit 1 is set, it's a string literal. | 613 // if bit 1 is set, it's a string literal. |
588 // If neither is set, it's no particular type, and both set isn't | 614 // If neither is set, it's no particular type, and both set isn't |
589 // use yet. | 615 // use yet. |
590 class PreParserExpression { | 616 class PreParserExpression { |
591 public: | 617 public: |
592 static PreParserExpression Default() { | 618 static PreParserExpression Default() { |
593 return PreParserExpression(kUnknownExpression); | 619 return PreParserExpression(kUnknownExpression); |
594 } | 620 } |
595 | 621 |
596 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 622 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
597 return PreParserExpression(kIdentifierFlag | | 623 return PreParserExpression(kTypeIdentifier | |
598 (id.type_ << kIdentifierShift)); | 624 (id.type_ << kIdentifierShift)); |
599 } | 625 } |
600 | 626 |
| 627 static PreParserExpression BinaryOperation(PreParserExpression left, |
| 628 Token::Value op, |
| 629 PreParserExpression right) { |
| 630 int code = ((op == Token::COMMA) && !left.is_parenthesized() && |
| 631 !right.is_parenthesized()) |
| 632 ? left.ArrowParamListBit() & right.ArrowParamListBit() |
| 633 : 0; |
| 634 return PreParserExpression(kTypeBinaryOperation | code); |
| 635 } |
| 636 |
| 637 static PreParserExpression EmptyArrowParamList() { |
| 638 // Any expression for which IsValidArrowParamList() returns true |
| 639 // will work here. |
| 640 return FromIdentifier(PreParserIdentifier::Default()); |
| 641 } |
| 642 |
601 static PreParserExpression StringLiteral() { | 643 static PreParserExpression StringLiteral() { |
602 return PreParserExpression(kUnknownStringLiteral); | 644 return PreParserExpression(kUnknownStringLiteral); |
603 } | 645 } |
604 | 646 |
605 static PreParserExpression UseStrictStringLiteral() { | 647 static PreParserExpression UseStrictStringLiteral() { |
606 return PreParserExpression(kUseStrictString); | 648 return PreParserExpression(kUseStrictString); |
607 } | 649 } |
608 | 650 |
609 static PreParserExpression This() { | 651 static PreParserExpression This() { |
610 return PreParserExpression(kThisExpression); | 652 return PreParserExpression(kThisExpression); |
611 } | 653 } |
612 | 654 |
613 static PreParserExpression ThisProperty() { | 655 static PreParserExpression ThisProperty() { |
614 return PreParserExpression(kThisPropertyExpression); | 656 return PreParserExpression(kThisPropertyExpression); |
615 } | 657 } |
616 | 658 |
617 static PreParserExpression Property() { | 659 static PreParserExpression Property() { |
618 return PreParserExpression(kPropertyExpression); | 660 return PreParserExpression(kPropertyExpression); |
619 } | 661 } |
620 | 662 |
621 static PreParserExpression Call() { | 663 static PreParserExpression Call() { |
622 return PreParserExpression(kCallExpression); | 664 return PreParserExpression(kCallExpression); |
623 } | 665 } |
624 | 666 |
625 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } | 667 bool IsIdentifier() const { return (code_ & kTypeMask) == kTypeIdentifier; } |
626 | 668 |
627 PreParserIdentifier AsIdentifier() { | 669 PreParserIdentifier AsIdentifier() const { |
628 ASSERT(IsIdentifier()); | 670 ASSERT(IsIdentifier()); |
629 return PreParserIdentifier( | 671 return PreParserIdentifier( |
630 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); | 672 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); |
631 } | 673 } |
632 | 674 |
633 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } | 675 bool IsStringLiteral() const { |
| 676 return (code_ & kTypeMask) == kTypeStringLiteral; |
| 677 } |
634 | 678 |
635 bool IsUseStrictLiteral() { | 679 bool IsUseStrictLiteral() { |
636 return (code_ & kStringLiteralMask) == kUseStrictString; | 680 return (code_ & kUseStrictString) == kUseStrictString; |
637 } | 681 } |
638 | 682 |
639 bool IsThis() { return code_ == kThisExpression; } | 683 bool IsThis() { return code_ == kThisExpression; } |
640 | 684 |
641 bool IsThisProperty() { return code_ == kThisPropertyExpression; } | 685 bool IsThisProperty() { return code_ == kThisPropertyExpression; } |
642 | 686 |
643 bool IsProperty() { | 687 bool IsProperty() { |
644 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; | 688 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; |
645 } | 689 } |
646 | 690 |
647 bool IsCall() { return code_ == kCallExpression; } | 691 bool IsCall() { return code_ == kCallExpression; } |
648 | 692 |
649 bool IsValidReferenceExpression() { | 693 bool IsValidReferenceExpression() { |
650 return IsIdentifier() || IsProperty(); | 694 return IsIdentifier() || IsProperty(); |
651 } | 695 } |
652 | 696 |
| 697 bool IsValidArrowParamList() const { |
| 698 return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0 && |
| 699 (code_ & kMultiParenthesizedExpression) == 0; |
| 700 } |
| 701 |
653 // At the moment PreParser doesn't track these expression types. | 702 // At the moment PreParser doesn't track these expression types. |
654 bool IsFunctionLiteral() const { return false; } | 703 bool IsFunctionLiteral() const { return false; } |
655 bool IsCallNew() const { return false; } | 704 bool IsCallNew() const { return false; } |
656 | 705 |
657 PreParserExpression AsFunctionLiteral() { return *this; } | 706 PreParserExpression AsFunctionLiteral() { return *this; } |
658 | 707 |
| 708 bool IsBinaryOperation() const { |
| 709 return (code_ & kTypeMask) == kTypeBinaryOperation; |
| 710 } |
| 711 |
| 712 bool is_parenthesized() const { |
| 713 return (code_ & kParenthesizedExpression) != 0; |
| 714 } |
| 715 |
| 716 void increase_parenthesization_level() { |
| 717 code_ |= is_parenthesized() ? kMultiParenthesizedExpression |
| 718 : kParenthesizedExpression; |
| 719 } |
| 720 |
659 // Dummy implementation for making expression->somefunc() work in both Parser | 721 // Dummy implementation for making expression->somefunc() work in both Parser |
660 // and PreParser. | 722 // and PreParser. |
661 PreParserExpression* operator->() { return this; } | 723 PreParserExpression* operator->() { return this; } |
662 | 724 |
663 // More dummy implementations of things PreParser doesn't need to track: | 725 // More dummy implementations of things PreParser doesn't need to track: |
664 void set_index(int index) {} // For YieldExpressions | 726 void set_index(int index) {} // For YieldExpressions |
665 void set_parenthesized() {} | 727 void set_parenthesized() {} |
666 | 728 |
| 729 int position() const { return RelocInfo::kNoPosition; } |
| 730 void set_function_token_position(int position) {} |
| 731 void set_ast_properties(int* ast_properties) {} |
| 732 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {} |
| 733 |
| 734 bool operator==(const PreParserExpression& other) const { |
| 735 return code_ == other.code_; |
| 736 } |
| 737 bool operator!=(const PreParserExpression& other) const { |
| 738 return code_ != other.code_; |
| 739 } |
| 740 |
667 private: | 741 private: |
668 // Least significant 2 bits are used as flags. Bits 0 and 1 represent | 742 // Least significant 2 bits are used as expression type. The third least |
669 // identifiers or strings literals, and are mutually exclusive, but can both | 743 // significant bit tracks whether an expression is parenthesized. If the |
670 // be absent. If the expression is an identifier or a string literal, the | 744 // expression is an identifier or a string literal, the other bits |
671 // other bits describe the type (see PreParserIdentifier::Type and string | 745 // describe the type/ (see PreParserIdentifier::Type and string literal |
672 // literal constants below). | 746 // constants below). For binary operations, the other bits are flags |
| 747 // which further describe the contents of the expression. |
673 enum { | 748 enum { |
674 kUnknownExpression = 0, | 749 kUnknownExpression = 0, |
| 750 kTypeMask = 1 | 2, |
| 751 kParenthesizedExpression = (1 << 2), |
| 752 kMultiParenthesizedExpression = (1 << 3), |
| 753 |
675 // Identifiers | 754 // Identifiers |
676 kIdentifierFlag = 1, // Used to detect labels. | 755 kTypeIdentifier = 1, // Used to detect labels. |
677 kIdentifierShift = 3, | 756 kIdentifierShift = 5, |
| 757 kTypeStringLiteral = 2, // Used to detect directive prologue. |
| 758 kUnknownStringLiteral = kTypeStringLiteral, |
| 759 kUseStrictString = kTypeStringLiteral | 32, |
| 760 kStringLiteralMask = kUseStrictString, |
678 | 761 |
679 kStringLiteralFlag = 2, // Used to detect directive prologue. | 762 // Binary operations. Those are needed to detect certain keywords and |
680 kUnknownStringLiteral = kStringLiteralFlag, | 763 // duplicated identifier in parameter lists for arrow functions, because |
681 kUseStrictString = kStringLiteralFlag | 8, | 764 // they are initially parsed as comma-separated expressions. |
682 kStringLiteralMask = kUseStrictString, | 765 kTypeBinaryOperation = 3, |
| 766 kBinaryOperationArrowParamList = (1 << 4), |
683 | 767 |
684 // Below here applies if neither identifier nor string literal. Reserve the | 768 // Below here applies if neither identifier nor string literal. Reserve the |
685 // 2 least significant bits for flags. | 769 // 2 least significant bits for flags. |
686 kThisExpression = 1 << 2, | 770 kThisExpression = (1 << 4), |
687 kThisPropertyExpression = 2 << 2, | 771 kThisPropertyExpression = (2 << 4), |
688 kPropertyExpression = 3 << 2, | 772 kPropertyExpression = (3 << 4), |
689 kCallExpression = 4 << 2 | 773 kCallExpression = (4 << 4) |
690 }; | 774 }; |
691 | 775 |
692 explicit PreParserExpression(int expression_code) : code_(expression_code) {} | 776 explicit PreParserExpression(int expression_code) : code_(expression_code) {} |
693 | 777 |
| 778 V8_INLINE int ArrowParamListBit() const { |
| 779 if (IsBinaryOperation()) return code_ & kBinaryOperationArrowParamList; |
| 780 if (IsIdentifier()) { |
| 781 const PreParserIdentifier ident = AsIdentifier(); |
| 782 // A valid identifier can be an arrow function parameter list |
| 783 // except for eval, arguments, yield, and reserved keywords. |
| 784 if (ident.IsEval() || ident.IsArguments() || ident.IsYield() || |
| 785 ident.IsFutureStrictReserved()) |
| 786 return 0; |
| 787 return kBinaryOperationArrowParamList; |
| 788 } |
| 789 return 0; |
| 790 } |
| 791 |
694 int code_; | 792 int code_; |
695 }; | 793 }; |
696 | 794 |
697 | 795 |
698 // PreParserExpressionList doesn't actually store the expressions because | 796 // PreParserExpressionList doesn't actually store the expressions because |
699 // PreParser doesn't need to. | 797 // PreParser doesn't need to. |
700 class PreParserExpressionList { | 798 class PreParserExpressionList { |
701 public: | 799 public: |
702 // These functions make list->Add(some_expression) work (and do nothing). | 800 // These functions make list->Add(some_expression) work (and do nothing). |
703 PreParserExpressionList() : length_(0) {} | 801 PreParserExpressionList() : length_(0) {} |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 public: | 863 public: |
766 // These functions make list->Add(some_expression) work as no-ops. | 864 // These functions make list->Add(some_expression) work as no-ops. |
767 PreParserStatementList() {} | 865 PreParserStatementList() {} |
768 PreParserStatementList* operator->() { return this; } | 866 PreParserStatementList* operator->() { return this; } |
769 void Add(PreParserStatement, void*) {} | 867 void Add(PreParserStatement, void*) {} |
770 }; | 868 }; |
771 | 869 |
772 | 870 |
773 class PreParserScope { | 871 class PreParserScope { |
774 public: | 872 public: |
775 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) | 873 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type, |
| 874 void* = NULL) |
776 : scope_type_(scope_type) { | 875 : scope_type_(scope_type) { |
777 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; | 876 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; |
778 } | 877 } |
779 | 878 |
780 ScopeType type() { return scope_type_; } | 879 ScopeType type() { return scope_type_; } |
781 StrictMode strict_mode() const { return strict_mode_; } | 880 StrictMode strict_mode() const { return strict_mode_; } |
782 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } | 881 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } |
783 | 882 |
| 883 // When PreParser is in use, lazy compilation is already being done, |
| 884 // things cannot get lazier than that. |
| 885 bool AllowsLazyCompilation() const { return false; } |
| 886 |
| 887 void set_start_position(int position) {} |
| 888 void set_end_position(int position) {} |
| 889 |
| 890 bool IsDeclared(const PreParserIdentifier& identifier) const { return false; } |
| 891 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) {} |
| 892 |
| 893 // Allow scope->Foo() to work. |
| 894 PreParserScope* operator->() { return this; } |
| 895 |
784 private: | 896 private: |
785 ScopeType scope_type_; | 897 ScopeType scope_type_; |
786 StrictMode strict_mode_; | 898 StrictMode strict_mode_; |
787 }; | 899 }; |
788 | 900 |
789 | 901 |
790 class PreParserFactory { | 902 class PreParserFactory { |
791 public: | 903 public: |
792 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} | 904 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} |
793 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, | 905 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 return PreParserExpression::Property(); | 949 return PreParserExpression::Property(); |
838 } | 950 } |
839 PreParserExpression NewUnaryOperation(Token::Value op, | 951 PreParserExpression NewUnaryOperation(Token::Value op, |
840 PreParserExpression expression, | 952 PreParserExpression expression, |
841 int pos) { | 953 int pos) { |
842 return PreParserExpression::Default(); | 954 return PreParserExpression::Default(); |
843 } | 955 } |
844 PreParserExpression NewBinaryOperation(Token::Value op, | 956 PreParserExpression NewBinaryOperation(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::BinaryOperation(left, op, right); |
848 } | 960 } |
849 PreParserExpression NewCompareOperation(Token::Value op, | 961 PreParserExpression NewCompareOperation(Token::Value op, |
850 PreParserExpression left, | 962 PreParserExpression left, |
851 PreParserExpression right, int pos) { | 963 PreParserExpression right, int pos) { |
852 return PreParserExpression::Default(); | 964 return PreParserExpression::Default(); |
853 } | 965 } |
854 PreParserExpression NewAssignment(Token::Value op, | 966 PreParserExpression NewAssignment(Token::Value op, |
855 PreParserExpression left, | 967 PreParserExpression left, |
856 PreParserExpression right, | 968 PreParserExpression right, |
857 int pos) { | 969 int pos) { |
(...skipping 20 matching lines...) Expand all Loading... |
878 PreParserExpression NewCall(PreParserExpression expression, | 990 PreParserExpression NewCall(PreParserExpression expression, |
879 PreParserExpressionList arguments, | 991 PreParserExpressionList arguments, |
880 int pos) { | 992 int pos) { |
881 return PreParserExpression::Call(); | 993 return PreParserExpression::Call(); |
882 } | 994 } |
883 PreParserExpression NewCallNew(PreParserExpression expression, | 995 PreParserExpression NewCallNew(PreParserExpression expression, |
884 PreParserExpressionList arguments, | 996 PreParserExpressionList arguments, |
885 int pos) { | 997 int pos) { |
886 return PreParserExpression::Default(); | 998 return PreParserExpression::Default(); |
887 } | 999 } |
| 1000 PreParserStatement NewReturnStatement(PreParserExpression expression, |
| 1001 int pos) { |
| 1002 return PreParserStatement::Default(); |
| 1003 } |
| 1004 PreParserExpression NewFunctionLiteral( |
| 1005 PreParserIdentifier name, AstValueFactory* ast_value_factory, |
| 1006 const PreParserScope& scope, PreParserStatementList body, |
| 1007 int materialized_literal_count, int expected_property_count, |
| 1008 int handler_count, int parameter_count, |
| 1009 FunctionLiteral::ParameterFlag has_duplicate_parameters, |
| 1010 FunctionLiteral::FunctionType function_type, |
| 1011 FunctionLiteral::IsFunctionFlag is_function, |
| 1012 FunctionLiteral::IsParenthesizedFlag is_parenthesized, |
| 1013 FunctionLiteral::IsGeneratorFlag is_generator, int position) { |
| 1014 return PreParserExpression::Default(); |
| 1015 } |
| 1016 |
| 1017 // Return the object itself as AstVisitor and implement the needed |
| 1018 // dummy method right in this class. |
| 1019 PreParserFactory* visitor() { return this; } |
| 1020 BailoutReason dont_optimize_reason() { return kNoReason; } |
| 1021 int* ast_properties() { |
| 1022 static int dummy = 42; |
| 1023 return &dummy; |
| 1024 } |
888 }; | 1025 }; |
889 | 1026 |
890 | 1027 |
891 class PreParser; | 1028 class PreParser; |
892 | 1029 |
893 class PreParserTraits { | 1030 class PreParserTraits { |
894 public: | 1031 public: |
895 struct Type { | 1032 struct Type { |
896 // TODO(marja): To be removed. The Traits object should contain all the data | 1033 // TODO(marja): To be removed. The Traits object should contain all the data |
897 // it needs. | 1034 // it needs. |
898 typedef PreParser* Parser; | 1035 typedef PreParser* Parser; |
899 | 1036 |
900 // Used by FunctionState and BlockState. | 1037 // Used by FunctionState and BlockState. |
901 typedef PreParserScope Scope; | 1038 typedef PreParserScope Scope; |
| 1039 typedef PreParserScope ScopePtr; |
| 1040 |
902 // PreParser doesn't need to store generator variables. | 1041 // PreParser doesn't need to store generator variables. |
903 typedef void GeneratorVariable; | 1042 typedef void GeneratorVariable; |
904 // No interaction with Zones. | 1043 // No interaction with Zones. |
905 typedef void Zone; | 1044 typedef void Zone; |
906 | 1045 |
| 1046 typedef int AstProperties; |
| 1047 typedef Vector<PreParserIdentifier> ParameterIdentifierVector; |
| 1048 |
907 // Return types for traversing functions. | 1049 // Return types for traversing functions. |
908 typedef PreParserIdentifier Identifier; | 1050 typedef PreParserIdentifier Identifier; |
909 typedef PreParserExpression Expression; | 1051 typedef PreParserExpression Expression; |
910 typedef PreParserExpression YieldExpression; | 1052 typedef PreParserExpression YieldExpression; |
911 typedef PreParserExpression FunctionLiteral; | 1053 typedef PreParserExpression FunctionLiteral; |
912 typedef PreParserExpression ObjectLiteralProperty; | 1054 typedef PreParserExpression ObjectLiteralProperty; |
913 typedef PreParserExpression Literal; | 1055 typedef PreParserExpression Literal; |
914 typedef PreParserExpressionList ExpressionList; | 1056 typedef PreParserExpressionList ExpressionList; |
915 typedef PreParserExpressionList PropertyList; | 1057 typedef PreParserExpressionList PropertyList; |
916 typedef PreParserStatementList StatementList; | 1058 typedef PreParserStatementList StatementList; |
(...skipping 22 matching lines...) Expand all Loading... |
939 } | 1081 } |
940 | 1082 |
941 static bool IsIdentifier(PreParserExpression expression) { | 1083 static bool IsIdentifier(PreParserExpression expression) { |
942 return expression.IsIdentifier(); | 1084 return expression.IsIdentifier(); |
943 } | 1085 } |
944 | 1086 |
945 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { | 1087 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { |
946 return expression.AsIdentifier(); | 1088 return expression.AsIdentifier(); |
947 } | 1089 } |
948 | 1090 |
| 1091 static bool IsFutureStrictReserved(PreParserIdentifier identifier) { |
| 1092 return identifier.IsYield() || identifier.IsFutureStrictReserved(); |
| 1093 } |
| 1094 |
949 static bool IsBoilerplateProperty(PreParserExpression property) { | 1095 static bool IsBoilerplateProperty(PreParserExpression property) { |
950 // PreParser doesn't count boilerplate properties. | 1096 // PreParser doesn't count boilerplate properties. |
951 return false; | 1097 return false; |
952 } | 1098 } |
953 | 1099 |
954 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { | 1100 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { |
955 return false; | 1101 return false; |
956 } | 1102 } |
957 | 1103 |
958 // Functions for encapsulating the differences between parsing and preparsing; | 1104 // Functions for encapsulating the differences between parsing and preparsing; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 return PreParserExpression::Default(); | 1148 return PreParserExpression::Default(); |
1003 } | 1149 } |
1004 PreParserExpression NewThrowSyntaxError( | 1150 PreParserExpression NewThrowSyntaxError( |
1005 const char* type, Handle<Object> arg, int pos) { | 1151 const char* type, Handle<Object> arg, int pos) { |
1006 return PreParserExpression::Default(); | 1152 return PreParserExpression::Default(); |
1007 } | 1153 } |
1008 PreParserExpression NewThrowTypeError( | 1154 PreParserExpression NewThrowTypeError( |
1009 const char* type, Handle<Object> arg, int pos) { | 1155 const char* type, Handle<Object> arg, int pos) { |
1010 return PreParserExpression::Default(); | 1156 return PreParserExpression::Default(); |
1011 } | 1157 } |
| 1158 PreParserScope NewScope(PreParserScope* outer_scope, ScopeType scope_type) { |
| 1159 return PreParserScope(outer_scope, scope_type); |
| 1160 } |
1012 | 1161 |
1013 // Reporting errors. | 1162 // Reporting errors. |
1014 void ReportMessageAt(Scanner::Location location, | 1163 void ReportMessageAt(Scanner::Location location, |
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 void ReportMessageAt(int start_pos, | 1167 void ReportMessageAt(int start_pos, |
1019 int end_pos, | 1168 int end_pos, |
1020 const char* message, | 1169 const char* message, |
1021 const char* arg = NULL, | 1170 const char* arg = NULL, |
1022 bool is_reference_error = false); | 1171 bool is_reference_error = false); |
1023 | 1172 |
1024 // "null" return type creators. | 1173 // "null" return type creators. |
1025 static PreParserIdentifier EmptyIdentifier() { | 1174 static PreParserIdentifier EmptyIdentifier() { |
1026 return PreParserIdentifier::Default(); | 1175 return PreParserIdentifier::Default(); |
1027 } | 1176 } |
| 1177 static PreParserIdentifier EmptyIdentifierString() { |
| 1178 return PreParserIdentifier::Default(); |
| 1179 } |
1028 static PreParserExpression EmptyExpression() { | 1180 static PreParserExpression EmptyExpression() { |
1029 return PreParserExpression::Default(); | 1181 return PreParserExpression::Default(); |
1030 } | 1182 } |
| 1183 static PreParserExpression EmptyArrowParamList() { |
| 1184 return PreParserExpression::EmptyArrowParamList(); |
| 1185 } |
1031 static PreParserExpression EmptyLiteral() { | 1186 static PreParserExpression EmptyLiteral() { |
1032 return PreParserExpression::Default(); | 1187 return PreParserExpression::Default(); |
1033 } | 1188 } |
1034 static PreParserExpressionList NullExpressionList() { | 1189 static PreParserExpressionList NullExpressionList() { |
1035 return PreParserExpressionList(); | 1190 return PreParserExpressionList(); |
1036 } | 1191 } |
1037 | 1192 |
1038 // Odd-ball literal creators. | 1193 // Odd-ball literal creators. |
1039 static PreParserExpression GetLiteralTheHole(int position, | 1194 static PreParserExpression GetLiteralTheHole(int position, |
1040 PreParserFactory* factory) { | 1195 PreParserFactory* factory) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 } | 1229 } |
1075 | 1230 |
1076 static PreParserStatementList NewStatementList(int size, void* zone) { | 1231 static PreParserStatementList NewStatementList(int size, void* zone) { |
1077 return PreParserStatementList(); | 1232 return PreParserStatementList(); |
1078 } | 1233 } |
1079 | 1234 |
1080 static PreParserExpressionList NewPropertyList(int size, void* zone) { | 1235 static PreParserExpressionList NewPropertyList(int size, void* zone) { |
1081 return PreParserExpressionList(); | 1236 return PreParserExpressionList(); |
1082 } | 1237 } |
1083 | 1238 |
| 1239 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, |
| 1240 int* materialized_literal_count, |
| 1241 int* expected_property_count, bool* ok) { |
| 1242 UNREACHABLE(); |
| 1243 } |
| 1244 |
| 1245 V8_INLINE PreParserStatementList |
| 1246 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
| 1247 Variable* fvar, Token::Value fvar_init_op, |
| 1248 bool is_generator, bool* ok); |
| 1249 |
| 1250 // Utility functions |
| 1251 Vector<PreParserIdentifier> ParameterListFromExpression( |
| 1252 PreParserExpression expression, bool* ok) { |
| 1253 // TODO(aperez): Detect duplicated identifiers in paramlists. |
| 1254 *ok = expression.IsValidArrowParamList(); |
| 1255 return Vector<PreParserIdentifier>::empty(); |
| 1256 } |
| 1257 |
| 1258 static AstValueFactory* ast_value_factory() { return NULL; } |
| 1259 |
| 1260 void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {} |
| 1261 |
1084 // Temporary glue; these functions will move to ParserBase. | 1262 // Temporary glue; these functions will move to ParserBase. |
1085 PreParserExpression ParseV8Intrinsic(bool* ok); | 1263 PreParserExpression ParseV8Intrinsic(bool* ok); |
1086 PreParserExpression ParseFunctionLiteral( | 1264 PreParserExpression ParseFunctionLiteral( |
1087 PreParserIdentifier name, | 1265 PreParserIdentifier name, |
1088 Scanner::Location function_name_location, | 1266 Scanner::Location function_name_location, |
1089 bool name_is_strict_reserved, | 1267 bool name_is_strict_reserved, |
1090 bool is_generator, | 1268 bool is_generator, |
1091 int function_token_position, | 1269 int function_token_position, |
1092 FunctionLiteral::FunctionType type, | 1270 FunctionLiteral::FunctionType type, |
1093 FunctionLiteral::ArityRestriction arity_restriction, | 1271 FunctionLiteral::ArityRestriction arity_restriction, |
(...skipping 30 matching lines...) Expand all Loading... |
1124 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) | 1302 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) |
1125 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, | 1303 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, |
1126 this) {} | 1304 this) {} |
1127 | 1305 |
1128 // Pre-parse the program from the character stream; returns true on | 1306 // Pre-parse the program from the character stream; returns true on |
1129 // success (even if parsing failed, the pre-parse data successfully | 1307 // success (even if parsing failed, the pre-parse data successfully |
1130 // captured the syntax error), and false if a stack-overflow happened | 1308 // captured the syntax error), and false if a stack-overflow happened |
1131 // during parsing. | 1309 // during parsing. |
1132 PreParseResult PreParseProgram() { | 1310 PreParseResult PreParseProgram() { |
1133 PreParserScope scope(scope_, GLOBAL_SCOPE); | 1311 PreParserScope scope(scope_, GLOBAL_SCOPE); |
1134 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); | 1312 FunctionState top_scope(&function_state_, &scope_, &scope); |
1135 bool ok = true; | 1313 bool ok = true; |
1136 int start_position = scanner()->peek_location().beg_pos; | 1314 int start_position = scanner()->peek_location().beg_pos; |
1137 ParseSourceElements(Token::EOS, &ok); | 1315 ParseSourceElements(Token::EOS, &ok); |
1138 if (stack_overflow()) return kPreParseStackOverflow; | 1316 if (stack_overflow()) return kPreParseStackOverflow; |
1139 if (!ok) { | 1317 if (!ok) { |
1140 ReportUnexpectedToken(scanner()->current_token()); | 1318 ReportUnexpectedToken(scanner()->current_token()); |
1141 } else if (scope_->strict_mode() == STRICT) { | 1319 } else if (scope_->strict_mode() == STRICT) { |
1142 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); | 1320 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); |
1143 } | 1321 } |
1144 return kPreParseSuccess; | 1322 return kPreParseSuccess; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 Statement ParseDoWhileStatement(bool* ok); | 1384 Statement ParseDoWhileStatement(bool* ok); |
1207 Statement ParseWhileStatement(bool* ok); | 1385 Statement ParseWhileStatement(bool* ok); |
1208 Statement ParseForStatement(bool* ok); | 1386 Statement ParseForStatement(bool* ok); |
1209 Statement ParseThrowStatement(bool* ok); | 1387 Statement ParseThrowStatement(bool* ok); |
1210 Statement ParseTryStatement(bool* ok); | 1388 Statement ParseTryStatement(bool* ok); |
1211 Statement ParseDebuggerStatement(bool* ok); | 1389 Statement ParseDebuggerStatement(bool* ok); |
1212 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 1390 Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
1213 Expression ParseObjectLiteral(bool* ok); | 1391 Expression ParseObjectLiteral(bool* ok); |
1214 Expression ParseV8Intrinsic(bool* ok); | 1392 Expression ParseV8Intrinsic(bool* ok); |
1215 | 1393 |
| 1394 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, |
| 1395 int* materialized_literal_count, |
| 1396 int* expected_property_count, bool* ok); |
| 1397 V8_INLINE PreParserStatementList |
| 1398 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
| 1399 Variable* fvar, Token::Value fvar_init_op, |
| 1400 bool is_generator, bool* ok); |
| 1401 |
1216 Expression ParseFunctionLiteral( | 1402 Expression ParseFunctionLiteral( |
1217 Identifier name, | 1403 Identifier name, |
1218 Scanner::Location function_name_location, | 1404 Scanner::Location function_name_location, |
1219 bool name_is_strict_reserved, | 1405 bool name_is_strict_reserved, |
1220 bool is_generator, | 1406 bool is_generator, |
1221 int function_token_pos, | 1407 int function_token_pos, |
1222 FunctionLiteral::FunctionType function_type, | 1408 FunctionLiteral::FunctionType function_type, |
1223 FunctionLiteral::ArityRestriction arity_restriction, | 1409 FunctionLiteral::ArityRestriction arity_restriction, |
1224 bool* ok); | 1410 bool* ok); |
1225 void ParseLazyFunctionLiteralBody(bool* ok); | 1411 void ParseLazyFunctionLiteralBody(bool* ok); |
1226 | 1412 |
1227 bool CheckInOrOf(bool accept_OF); | 1413 bool CheckInOrOf(bool accept_OF); |
1228 }; | 1414 }; |
1229 | 1415 |
| 1416 |
| 1417 PreParserStatementList PreParser::ParseEagerFunctionBody( |
| 1418 PreParserIdentifier function_name, int pos, Variable* fvar, |
| 1419 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
| 1420 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 1421 |
| 1422 ParseSourceElements(Token::RBRACE, ok); |
| 1423 if (!*ok) return PreParserStatementList(); |
| 1424 |
| 1425 Expect(Token::RBRACE, ok); |
| 1426 return PreParserStatementList(); |
| 1427 } |
| 1428 |
| 1429 |
| 1430 PreParserStatementList PreParserTraits::ParseEagerFunctionBody( |
| 1431 PreParserIdentifier function_name, int pos, Variable* fvar, |
| 1432 Token::Value fvar_init_op, bool is_generator, bool* ok) { |
| 1433 return pre_parser_->ParseEagerFunctionBody(function_name, pos, fvar, |
| 1434 fvar_init_op, is_generator, ok); |
| 1435 } |
| 1436 |
| 1437 |
1230 template<class Traits> | 1438 template<class Traits> |
1231 ParserBase<Traits>::FunctionState::FunctionState( | 1439 ParserBase<Traits>::FunctionState::FunctionState( |
1232 FunctionState** function_state_stack, | 1440 FunctionState** function_state_stack, |
1233 typename Traits::Type::Scope** scope_stack, | 1441 typename Traits::Type::Scope** scope_stack, |
1234 typename Traits::Type::Scope* scope, | 1442 typename Traits::Type::Scope* scope, |
1235 typename Traits::Type::Zone* extra_param, | 1443 typename Traits::Type::Zone* extra_param, |
1236 AstValueFactory* ast_value_factory) | 1444 AstValueFactory* ast_value_factory) |
1237 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | 1445 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
1238 next_handler_index_(0), | 1446 next_handler_index_(0), |
1239 expected_property_count_(0), | 1447 expected_property_count_(0), |
1240 is_generator_(false), | 1448 is_generator_(false), |
1241 generator_object_variable_(NULL), | 1449 generator_object_variable_(NULL), |
1242 function_state_stack_(function_state_stack), | 1450 function_state_stack_(function_state_stack), |
1243 outer_function_state_(*function_state_stack), | 1451 outer_function_state_(*function_state_stack), |
1244 scope_stack_(scope_stack), | 1452 scope_stack_(scope_stack), |
1245 outer_scope_(*scope_stack), | 1453 outer_scope_(*scope_stack), |
1246 saved_ast_node_id_(0), | 1454 saved_ast_node_id_(0), |
1247 extra_param_(extra_param), | 1455 extra_param_(extra_param), |
1248 factory_(extra_param, ast_value_factory) { | 1456 factory_(extra_param, ast_value_factory) { |
1249 *scope_stack_ = scope; | 1457 *scope_stack_ = scope; |
1250 *function_state_stack = this; | 1458 *function_state_stack = this; |
1251 Traits::SetUpFunctionState(this, extra_param); | 1459 Traits::SetUpFunctionState(this, extra_param); |
1252 } | 1460 } |
1253 | 1461 |
1254 | 1462 |
1255 template<class Traits> | 1463 template <class Traits> |
| 1464 ParserBase<Traits>::FunctionState::FunctionState( |
| 1465 FunctionState** function_state_stack, |
| 1466 typename Traits::Type::Scope** scope_stack, |
| 1467 typename Traits::Type::Scope** scope, |
| 1468 typename Traits::Type::Zone* extra_param, |
| 1469 AstValueFactory* ast_value_factory) |
| 1470 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
| 1471 next_handler_index_(0), |
| 1472 expected_property_count_(0), |
| 1473 is_generator_(false), |
| 1474 generator_object_variable_(NULL), |
| 1475 function_state_stack_(function_state_stack), |
| 1476 outer_function_state_(*function_state_stack), |
| 1477 scope_stack_(scope_stack), |
| 1478 outer_scope_(*scope_stack), |
| 1479 saved_ast_node_id_(0), |
| 1480 extra_param_(extra_param), |
| 1481 factory_(extra_param, ast_value_factory) { |
| 1482 *scope_stack_ = *scope; |
| 1483 *function_state_stack = this; |
| 1484 Traits::SetUpFunctionState(this, extra_param); |
| 1485 } |
| 1486 |
| 1487 |
| 1488 template <class Traits> |
1256 ParserBase<Traits>::FunctionState::~FunctionState() { | 1489 ParserBase<Traits>::FunctionState::~FunctionState() { |
1257 *scope_stack_ = outer_scope_; | 1490 *scope_stack_ = outer_scope_; |
1258 *function_state_stack_ = outer_function_state_; | 1491 *function_state_stack_ = outer_function_state_; |
1259 Traits::TearDownFunctionState(this, extra_param_); | 1492 Traits::TearDownFunctionState(this, extra_param_); |
1260 } | 1493 } |
1261 | 1494 |
1262 | 1495 |
1263 template<class Traits> | 1496 template<class Traits> |
1264 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { | 1497 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { |
1265 Scanner::Location source_location = scanner()->location(); | 1498 Scanner::Location source_location = scanner()->location(); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1462 case Token::LBRACK: | 1695 case Token::LBRACK: |
1463 result = this->ParseArrayLiteral(CHECK_OK); | 1696 result = this->ParseArrayLiteral(CHECK_OK); |
1464 break; | 1697 break; |
1465 | 1698 |
1466 case Token::LBRACE: | 1699 case Token::LBRACE: |
1467 result = this->ParseObjectLiteral(CHECK_OK); | 1700 result = this->ParseObjectLiteral(CHECK_OK); |
1468 break; | 1701 break; |
1469 | 1702 |
1470 case Token::LPAREN: | 1703 case Token::LPAREN: |
1471 Consume(Token::LPAREN); | 1704 Consume(Token::LPAREN); |
1472 // Heuristically try to detect immediately called functions before | 1705 if (allow_arrow_functions() && peek() == Token::RPAREN) { |
1473 // seeing the call parentheses. | 1706 // Arrow functions are the only expression type constructions |
1474 parenthesized_function_ = (peek() == Token::FUNCTION); | 1707 // for which an empty parameter list "()" is valid input. |
1475 result = this->ParseExpression(true, CHECK_OK); | 1708 Consume(Token::RPAREN); |
1476 Expect(Token::RPAREN, CHECK_OK); | 1709 return this->ParseArrowFunctionLiteral(pos, this->EmptyArrowParamList(), |
| 1710 CHECK_OK); |
| 1711 } else { |
| 1712 // Heuristically try to detect immediately called functions before |
| 1713 // seeing the call parentheses. |
| 1714 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 1715 result = this->ParseExpression(true, CHECK_OK); |
| 1716 result->increase_parenthesization_level(); |
| 1717 Expect(Token::RPAREN, CHECK_OK); |
| 1718 } |
1477 break; | 1719 break; |
1478 | 1720 |
1479 case Token::MOD: | 1721 case Token::MOD: |
1480 if (allow_natives_syntax() || extension_ != NULL) { | 1722 if (allow_natives_syntax() || extension_ != NULL) { |
1481 result = this->ParseV8Intrinsic(CHECK_OK); | 1723 result = this->ParseV8Intrinsic(CHECK_OK); |
1482 break; | 1724 break; |
1483 } | 1725 } |
1484 // If we're not allowing special syntax we fall-through to the | 1726 // If we're not allowing special syntax we fall-through to the |
1485 // default case. | 1727 // default case. |
1486 | 1728 |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1738 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 1980 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
1739 return result; | 1981 return result; |
1740 } | 1982 } |
1741 | 1983 |
1742 // Precedence = 2 | 1984 // Precedence = 2 |
1743 template <class Traits> | 1985 template <class Traits> |
1744 typename ParserBase<Traits>::ExpressionT | 1986 typename ParserBase<Traits>::ExpressionT |
1745 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 1987 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
1746 // AssignmentExpression :: | 1988 // AssignmentExpression :: |
1747 // ConditionalExpression | 1989 // ConditionalExpression |
| 1990 // ArrowFunction |
1748 // YieldExpression | 1991 // YieldExpression |
1749 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 1992 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
1750 | 1993 |
1751 Scanner::Location lhs_location = scanner()->peek_location(); | 1994 Scanner::Location lhs_location = scanner()->peek_location(); |
1752 | 1995 |
1753 if (peek() == Token::YIELD && is_generator()) { | 1996 if (peek() == Token::YIELD && is_generator()) { |
1754 return this->ParseYieldExpression(ok); | 1997 return this->ParseYieldExpression(ok); |
1755 } | 1998 } |
1756 | 1999 |
1757 if (fni_ != NULL) fni_->Enter(); | 2000 if (fni_ != NULL) fni_->Enter(); |
1758 ExpressionT expression = | 2001 ExpressionT expression = |
1759 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2002 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
1760 | 2003 |
| 2004 if (allow_arrow_functions() && peek() == Token::ARROW) |
| 2005 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos, expression, |
| 2006 CHECK_OK); |
| 2007 |
1761 if (!Token::IsAssignmentOp(peek())) { | 2008 if (!Token::IsAssignmentOp(peek())) { |
1762 if (fni_ != NULL) fni_->Leave(); | 2009 if (fni_ != NULL) fni_->Leave(); |
1763 // Parsed conditional expression only (no assignment). | 2010 // Parsed conditional expression only (no assignment). |
1764 return expression; | 2011 return expression; |
1765 } | 2012 } |
1766 | 2013 |
1767 expression = this->CheckAndRewriteReferenceExpression( | 2014 expression = this->CheckAndRewriteReferenceExpression( |
1768 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 2015 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); |
1769 expression = this->MarkExpressionAsAssigned(expression); | 2016 expression = this->MarkExpressionAsAssigned(expression); |
1770 | 2017 |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2177 } | 2424 } |
2178 default: | 2425 default: |
2179 return expression; | 2426 return expression; |
2180 } | 2427 } |
2181 } | 2428 } |
2182 ASSERT(false); | 2429 ASSERT(false); |
2183 return this->EmptyExpression(); | 2430 return this->EmptyExpression(); |
2184 } | 2431 } |
2185 | 2432 |
2186 | 2433 |
| 2434 template <class Traits> |
| 2435 typename ParserBase<Traits>::ExpressionT ParserBase< |
| 2436 Traits>::ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
| 2437 bool* ok) { |
| 2438 typename Traits::Type::ParameterIdentifierVector params = |
| 2439 Traits::ParameterListFromExpression(params_ast, ok); |
| 2440 |
| 2441 if (!*ok) { |
| 2442 ReportMessageAt(Scanner::Location(start_pos, scanner()->location().beg_pos), |
| 2443 "malformed_arrow_function_parameter_list"); |
| 2444 params.Dispose(); |
| 2445 return this->EmptyExpression(); |
| 2446 } |
| 2447 |
| 2448 // TODO(aperez): Change this to use ARROW_SCOPE |
| 2449 typename Traits::Type::ScopePtr scope = |
| 2450 this->NewScope(scope_, FUNCTION_SCOPE); |
| 2451 |
| 2452 FunctionState function_state(&function_state_, &scope_, &scope, zone(), |
| 2453 this->ast_value_factory()); |
| 2454 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
| 2455 |
| 2456 if (params.length() > Code::kMaxArguments) { |
| 2457 ReportMessageAt(Scanner::Location(params_ast->position(), position()), |
| 2458 "too_many_parameters"); |
| 2459 *ok = false; |
| 2460 params.Dispose(); |
| 2461 return this->EmptyExpression(); |
| 2462 } |
| 2463 |
| 2464 for (int i = 0; i < params.length(); ++i) { |
| 2465 const IdentifierT param_name = params.at(i)->raw_name(); |
| 2466 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { |
| 2467 int param_pos = params.at(i)->position(); |
| 2468 dupe_error_loc = |
| 2469 Scanner::Location(param_pos, param_pos + param_name->length()); |
| 2470 } |
| 2471 scope_->DeclareParameter(param_name, VAR); |
| 2472 } |
| 2473 |
| 2474 ExpressionT expression = ParseArrowFunctionLiteralBody( |
| 2475 &function_state, scope, params.length(), Scanner::Location::invalid(), |
| 2476 dupe_error_loc, Scanner::Location::invalid(), |
| 2477 FunctionLiteral::kNotParenthesized, start_pos, CHECK_OK); |
| 2478 params.Dispose(); |
| 2479 return expression; |
| 2480 } |
| 2481 |
| 2482 |
| 2483 template <class Traits> |
| 2484 typename ParserBase<Traits>::ExpressionT |
| 2485 ParserBase<Traits>::ParseArrowFunctionLiteralBody( |
| 2486 FunctionState* function_state, typename Traits::Type::ScopePtr scope, |
| 2487 int num_parameters, const Scanner::Location& eval_args_error_loc, |
| 2488 const Scanner::Location& dupe_error_loc, |
| 2489 const Scanner::Location& reserved_loc, |
| 2490 FunctionLiteral::IsParenthesizedFlag parenthesized, int start_pos, |
| 2491 bool* ok) { |
| 2492 int materialized_literal_count = -1; |
| 2493 int expected_property_count = -1; |
| 2494 |
| 2495 Expect(Token::ARROW, CHECK_OK); |
| 2496 |
| 2497 if (peek() == Token::LBRACE) { |
| 2498 // Multiple statemente body |
| 2499 Consume(Token::LBRACE); |
| 2500 bool is_lazily_parsed = |
| 2501 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
| 2502 if (is_lazily_parsed) { |
| 2503 this->SkipLazyFunctionBody(this->EmptyIdentifier(), |
| 2504 &materialized_literal_count, |
| 2505 &expected_property_count, CHECK_OK); |
| 2506 } else { |
| 2507 this->ParseEagerFunctionBody(this->EmptyIdentifier(), |
| 2508 RelocInfo::kNoPosition, NULL, |
| 2509 Token::INIT_VAR, false, // Not a generator. |
| 2510 CHECK_OK); |
| 2511 } |
| 2512 } else { |
| 2513 // Single-expression body |
| 2514 ParseAssignmentExpression(true, CHECK_OK); |
| 2515 } |
| 2516 |
| 2517 scope->set_start_position(start_pos); |
| 2518 scope->set_end_position(scanner()->location().end_pos); |
| 2519 |
| 2520 // Arrow function *parameter lists* are always checked as in strict mode. |
| 2521 this->CheckStrictFunctionNameAndParameters( |
| 2522 this->EmptyIdentifier(), false, Scanner::Location::invalid(), |
| 2523 Scanner::Location::invalid(), dupe_error_loc, |
| 2524 Scanner::Location::invalid(), CHECK_OK); |
| 2525 |
| 2526 // Validate strict mode. |
| 2527 if (strict_mode() == STRICT) { |
| 2528 CheckOctalLiteral(start_pos, scanner()->location().end_pos, CHECK_OK); |
| 2529 } |
| 2530 |
| 2531 if (allow_harmony_scoping() && strict_mode() == STRICT) |
| 2532 this->CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 2533 |
| 2534 // TODO(aperez): Generate a proper FunctionLiteral instead of |
| 2535 // returning a dummy value. |
| 2536 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| 2537 this->EmptyIdentifierString(), this->ast_value_factory(), scope, |
| 2538 this->NewStatementList(0, zone()), 0, 0, 0, num_parameters, |
| 2539 FunctionLiteral::kNoDuplicateParameters, |
| 2540 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, |
| 2541 FunctionLiteral::kNotParenthesized, FunctionLiteral::kNotGenerator, |
| 2542 start_pos); |
| 2543 function_literal->set_function_token_position(start_pos); |
| 2544 return function_literal; |
| 2545 } |
| 2546 |
| 2547 |
2187 template <typename Traits> | 2548 template <typename Traits> |
2188 typename ParserBase<Traits>::ExpressionT | 2549 typename ParserBase<Traits>::ExpressionT |
2189 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 2550 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
2190 ExpressionT expression, | 2551 ExpressionT expression, |
2191 Scanner::Location location, const char* message, bool* ok) { | 2552 Scanner::Location location, const char* message, bool* ok) { |
2192 if (strict_mode() == STRICT && this->IsIdentifier(expression) && | 2553 if (strict_mode() == STRICT && this->IsIdentifier(expression) && |
2193 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 2554 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
2194 this->ReportMessageAt(location, "strict_eval_arguments", false); | 2555 this->ReportMessageAt(location, "strict_eval_arguments", false); |
2195 *ok = false; | 2556 *ok = false; |
2196 return this->EmptyExpression(); | 2557 return this->EmptyExpression(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2240 parser()->ReportMessage("accessor_get_set"); | 2601 parser()->ReportMessage("accessor_get_set"); |
2241 } | 2602 } |
2242 *ok = false; | 2603 *ok = false; |
2243 } | 2604 } |
2244 } | 2605 } |
2245 | 2606 |
2246 | 2607 |
2247 } } // v8::internal | 2608 } } // v8::internal |
2248 | 2609 |
2249 #endif // V8_PREPARSER_H | 2610 #endif // V8_PREPARSER_H |
OLD | NEW |