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