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...) 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, |
67 v8::Extension* extension, | 68 v8::Extension* extension, |
68 ParserRecorder* log, | 69 ParserRecorder* log, |
69 typename Traits::Type::Zone* zone, | 70 typename Traits::Type::Zone* zone, |
70 typename Traits::Type::Parser this_object) | 71 typename Traits::Type::Parser this_object) |
71 : Traits(this_object), | 72 : Traits(this_object), |
72 parenthesized_function_(false), | 73 parenthesized_function_(false), |
73 scope_(NULL), | 74 scope_(NULL), |
74 function_state_(NULL), | 75 function_state_(NULL), |
75 extension_(extension), | 76 extension_(extension), |
76 fni_(NULL), | 77 fni_(NULL), |
77 log_(log), | 78 log_(log), |
78 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 79 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
79 scanner_(scanner), | 80 scanner_(scanner), |
80 stack_limit_(stack_limit), | 81 stack_limit_(stack_limit), |
81 stack_overflow_(false), | 82 stack_overflow_(false), |
82 allow_lazy_(false), | 83 allow_lazy_(false), |
83 allow_natives_syntax_(false), | 84 allow_natives_syntax_(false), |
84 allow_generators_(false), | 85 allow_generators_(false), |
85 allow_for_of_(false), | 86 allow_for_of_(false), |
87 allow_arrow_functions_(false), | |
86 zone_(zone) { } | 88 zone_(zone) { } |
87 | 89 |
88 // Getters that indicate whether certain syntactical constructs are | 90 // Getters that indicate whether certain syntactical constructs are |
89 // allowed to be parsed by this instance of the parser. | 91 // allowed to be parsed by this instance of the parser. |
90 bool allow_lazy() const { return allow_lazy_; } | 92 bool allow_lazy() const { return allow_lazy_; } |
91 bool allow_natives_syntax() const { return allow_natives_syntax_; } | 93 bool allow_natives_syntax() const { return allow_natives_syntax_; } |
92 bool allow_generators() const { return allow_generators_; } | 94 bool allow_generators() const { return allow_generators_; } |
93 bool allow_for_of() const { return allow_for_of_; } | 95 bool allow_for_of() const { return allow_for_of_; } |
96 bool allow_arrow_functions() const { return allow_arrow_functions_; } | |
94 bool allow_modules() const { return scanner()->HarmonyModules(); } | 97 bool allow_modules() const { return scanner()->HarmonyModules(); } |
95 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } | 98 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } |
96 bool allow_harmony_numeric_literals() const { | 99 bool allow_harmony_numeric_literals() const { |
97 return scanner()->HarmonyNumericLiterals(); | 100 return scanner()->HarmonyNumericLiterals(); |
98 } | 101 } |
99 | 102 |
100 // Setters that determine whether certain syntactical constructs are | 103 // Setters that determine whether certain syntactical constructs are |
101 // allowed to be parsed by this instance of the parser. | 104 // allowed to be parsed by this instance of the parser. |
102 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 105 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
103 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } | 106 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } |
104 void set_allow_generators(bool allow) { allow_generators_ = allow; } | 107 void set_allow_generators(bool allow) { allow_generators_ = allow; } |
105 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } | 108 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } |
109 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; } | |
106 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } | 110 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } |
107 void set_allow_harmony_scoping(bool allow) { | 111 void set_allow_harmony_scoping(bool allow) { |
108 scanner()->SetHarmonyScoping(allow); | 112 scanner()->SetHarmonyScoping(allow); |
109 } | 113 } |
110 void set_allow_harmony_numeric_literals(bool allow) { | 114 void set_allow_harmony_numeric_literals(bool allow) { |
111 scanner()->SetHarmonyNumericLiterals(allow); | 115 scanner()->SetHarmonyNumericLiterals(allow); |
112 } | 116 } |
113 | 117 |
114 protected: | 118 protected: |
115 enum AllowEvalOrArgumentsAsIdentifier { | 119 enum AllowEvalOrArgumentsAsIdentifier { |
(...skipping 29 matching lines...) Loading... | |
145 }; | 149 }; |
146 | 150 |
147 class FunctionState BASE_EMBEDDED { | 151 class FunctionState BASE_EMBEDDED { |
148 public: | 152 public: |
149 FunctionState( | 153 FunctionState( |
150 FunctionState** function_state_stack, | 154 FunctionState** function_state_stack, |
151 typename Traits::Type::Scope** scope_stack, | 155 typename Traits::Type::Scope** scope_stack, |
152 typename Traits::Type::Scope* scope, | 156 typename Traits::Type::Scope* scope, |
153 typename Traits::Type::Zone* zone = NULL, | 157 typename Traits::Type::Zone* zone = NULL, |
154 AstValueFactory* ast_value_factory = NULL); | 158 AstValueFactory* ast_value_factory = NULL); |
159 FunctionState( | |
160 FunctionState** function_state_stack, | |
161 typename Traits::Type::Scope** scope_stack, | |
162 typename Traits::Type::Scope** scope, | |
163 typename Traits::Type::Zone* zone = NULL, | |
164 AstValueFactory* ast_value_factory = NULL); | |
155 ~FunctionState(); | 165 ~FunctionState(); |
156 | 166 |
157 int NextMaterializedLiteralIndex() { | 167 int NextMaterializedLiteralIndex() { |
158 return next_materialized_literal_index_++; | 168 return next_materialized_literal_index_++; |
159 } | 169 } |
160 int materialized_literal_count() { | 170 int materialized_literal_count() { |
161 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; | 171 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; |
162 } | 172 } |
163 | 173 |
164 int NextHandlerIndex() { return next_handler_index_++; } | 174 int NextHandlerIndex() { return next_handler_index_++; } |
(...skipping 270 matching lines...) Loading... | |
435 ExpressionT ParseYieldExpression(bool* ok); | 445 ExpressionT ParseYieldExpression(bool* ok); |
436 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 446 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
437 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 447 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
438 ExpressionT ParseUnaryExpression(bool* ok); | 448 ExpressionT ParseUnaryExpression(bool* ok); |
439 ExpressionT ParsePostfixExpression(bool* ok); | 449 ExpressionT ParsePostfixExpression(bool* ok); |
440 ExpressionT ParseLeftHandSideExpression(bool* ok); | 450 ExpressionT ParseLeftHandSideExpression(bool* ok); |
441 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 451 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
442 ExpressionT ParseMemberExpression(bool* ok); | 452 ExpressionT ParseMemberExpression(bool* ok); |
443 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 453 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
444 bool* ok); | 454 bool* ok); |
455 ExpressionT ParseArrowFunctionLiteral(int start_pos, | |
456 ExpressionT params_ast, | |
457 bool* ok); | |
458 ExpressionT ParseArrowFunctionLiteralBody( | |
459 FunctionState* function_state, | |
460 typename Traits::Type::ScopePtr scope, | |
461 int num_parameters, | |
462 const Scanner::Location& eval_args_error_loc, | |
463 const Scanner::Location& dupe_error_loc, | |
464 const Scanner::Location& reserved_loc, | |
465 FunctionLiteral::IsParenthesizedFlag parenthesized, | |
466 int start_pos, | |
467 bool* ok); | |
445 | 468 |
446 // Checks if the expression is a valid reference expression (e.g., on the | 469 // 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, | 470 // 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. | 471 // we allow calls for web compatibility and rewrite them to a runtime throw. |
449 ExpressionT CheckAndRewriteReferenceExpression( | 472 ExpressionT CheckAndRewriteReferenceExpression( |
450 ExpressionT expression, | 473 ExpressionT expression, |
451 Scanner::Location location, const char* message, bool* ok); | 474 Scanner::Location location, const char* message, bool* ok); |
452 | 475 |
453 // Used to detect duplicates in object literals. Each of the values | 476 // Used to detect duplicates in object literals. Each of the values |
454 // kGetterProperty, kSetterProperty and kValueProperty represents | 477 // kGetterProperty, kSetterProperty and kValueProperty represents |
(...skipping 64 matching lines...) Loading... | |
519 | 542 |
520 private: | 543 private: |
521 Scanner* scanner_; | 544 Scanner* scanner_; |
522 uintptr_t stack_limit_; | 545 uintptr_t stack_limit_; |
523 bool stack_overflow_; | 546 bool stack_overflow_; |
524 | 547 |
525 bool allow_lazy_; | 548 bool allow_lazy_; |
526 bool allow_natives_syntax_; | 549 bool allow_natives_syntax_; |
527 bool allow_generators_; | 550 bool allow_generators_; |
528 bool allow_for_of_; | 551 bool allow_for_of_; |
552 bool allow_arrow_functions_; | |
529 | 553 |
530 typename Traits::Type::Zone* zone_; // Only used by Parser. | 554 typename Traits::Type::Zone* zone_; // Only used by Parser. |
531 }; | 555 }; |
532 | 556 |
533 | 557 |
534 class PreParserIdentifier { | 558 class PreParserIdentifier { |
535 public: | 559 public: |
536 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 560 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
537 static PreParserIdentifier Default() { | 561 static PreParserIdentifier Default() { |
538 return PreParserIdentifier(kUnknownIdentifier); | 562 return PreParserIdentifier(kUnknownIdentifier); |
539 } | 563 } |
540 static PreParserIdentifier Eval() { | 564 static PreParserIdentifier Eval() { |
541 return PreParserIdentifier(kEvalIdentifier); | 565 return PreParserIdentifier(kEvalIdentifier); |
542 } | 566 } |
543 static PreParserIdentifier Arguments() { | 567 static PreParserIdentifier Arguments() { |
544 return PreParserIdentifier(kArgumentsIdentifier); | 568 return PreParserIdentifier(kArgumentsIdentifier); |
545 } | 569 } |
546 static PreParserIdentifier FutureReserved() { | 570 static PreParserIdentifier FutureReserved() { |
547 return PreParserIdentifier(kFutureReservedIdentifier); | 571 return PreParserIdentifier(kFutureReservedIdentifier); |
548 } | 572 } |
549 static PreParserIdentifier FutureStrictReserved() { | 573 static PreParserIdentifier FutureStrictReserved() { |
550 return PreParserIdentifier(kFutureStrictReservedIdentifier); | 574 return PreParserIdentifier(kFutureStrictReservedIdentifier); |
551 } | 575 } |
552 static PreParserIdentifier Yield() { | 576 static PreParserIdentifier Yield() { |
553 return PreParserIdentifier(kYieldIdentifier); | 577 return PreParserIdentifier(kYieldIdentifier); |
554 } | 578 } |
555 bool IsEval() { return type_ == kEvalIdentifier; } | 579 bool IsEval() const { return type_ == kEvalIdentifier; } |
556 bool IsArguments() { return type_ == kArgumentsIdentifier; } | 580 bool IsArguments() const { return type_ == kArgumentsIdentifier; } |
557 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } | 581 bool IsEvalOrArguments() const { return type_ >= kEvalIdentifier; } |
558 bool IsYield() { return type_ == kYieldIdentifier; } | 582 bool IsYield() const { return type_ == kYieldIdentifier; } |
559 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } | 583 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } |
560 bool IsFutureStrictReserved() { | 584 bool IsFutureStrictReserved() const { |
561 return type_ == kFutureStrictReservedIdentifier; | 585 return type_ == kFutureStrictReservedIdentifier; |
562 } | 586 } |
563 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } | 587 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; } |
588 | |
589 // Allow identifier->name()[->length()] to work. The preparser | |
590 // does not need the actual positions/lengths of the identifiers. | |
591 const PreParserIdentifier* operator->() const { return this; } | |
592 const PreParserIdentifier raw_name() const { return *this; } | |
593 | |
594 int position() const { return 0; } | |
595 int length() const { return 0; } | |
564 | 596 |
565 private: | 597 private: |
566 enum Type { | 598 enum Type { |
567 kUnknownIdentifier, | 599 kUnknownIdentifier, |
568 kFutureReservedIdentifier, | 600 kFutureReservedIdentifier, |
569 kFutureStrictReservedIdentifier, | 601 kFutureStrictReservedIdentifier, |
570 kYieldIdentifier, | 602 kYieldIdentifier, |
571 kEvalIdentifier, | 603 kEvalIdentifier, |
572 kArgumentsIdentifier | 604 kArgumentsIdentifier |
573 }; | 605 }; |
574 explicit PreParserIdentifier(Type type) : type_(type) {} | 606 explicit PreParserIdentifier(Type type) : type_(type) {} |
575 Type type_; | 607 Type type_; |
576 | 608 |
577 friend class PreParserExpression; | 609 friend class PreParserExpression; |
610 friend class PreParserScope; | |
578 }; | 611 }; |
579 | 612 |
580 | 613 |
581 // Bits 0 and 1 are used to identify the type of expression: | 614 // Bits 0 and 1 are used to identify the type of expression: |
582 // If bit 0 is set, it's an identifier. | 615 // If bit 0 is set, it's an identifier. |
583 // if bit 1 is set, it's a string literal. | 616 // if bit 1 is set, it's a string literal. |
584 // If neither is set, it's no particular type, and both set isn't | 617 // If neither is set, it's no particular type, and both set isn't |
585 // use yet. | 618 // use yet. |
586 class PreParserExpression { | 619 class PreParserExpression { |
587 public: | 620 public: |
588 static PreParserExpression Default() { | 621 static PreParserExpression Default() { |
589 return PreParserExpression(kUnknownExpression); | 622 return PreParserExpression(kUnknownExpression); |
590 } | 623 } |
591 | 624 |
592 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 625 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
593 return PreParserExpression(kIdentifierFlag | | 626 return PreParserExpression(kTypeIdentifier | |
594 (id.type_ << kIdentifierShift)); | 627 (id.type_ << kIdentifierShift)); |
595 } | 628 } |
596 | 629 |
630 static PreParserExpression BinaryOperation(PreParserExpression left, | |
631 Token::Value op, | |
632 PreParserExpression right) { | |
633 int code = ((op == Token::COMMA) && | |
634 !left.is_parenthesized() && | |
635 !right.is_parenthesized()) | |
636 ? left.ArrowParamListBit() & right.ArrowParamListBit() : 0; | |
637 return PreParserExpression(kTypeBinaryOperation | code); | |
638 } | |
639 | |
640 static PreParserExpression EmptyArrowParamList() { | |
641 // Any expression for which IsValidArrowParamList() returns true | |
642 // will work here. | |
643 return FromIdentifier(PreParserIdentifier::Default()); | |
644 } | |
645 | |
597 static PreParserExpression StringLiteral() { | 646 static PreParserExpression StringLiteral() { |
598 return PreParserExpression(kUnknownStringLiteral); | 647 return PreParserExpression(kUnknownStringLiteral); |
599 } | 648 } |
600 | 649 |
601 static PreParserExpression UseStrictStringLiteral() { | 650 static PreParserExpression UseStrictStringLiteral() { |
602 return PreParserExpression(kUseStrictString); | 651 return PreParserExpression(kUseStrictString); |
603 } | 652 } |
604 | 653 |
605 static PreParserExpression This() { | 654 static PreParserExpression This() { |
606 return PreParserExpression(kThisExpression); | 655 return PreParserExpression(kThisExpression); |
607 } | 656 } |
608 | 657 |
609 static PreParserExpression ThisProperty() { | 658 static PreParserExpression ThisProperty() { |
610 return PreParserExpression(kThisPropertyExpression); | 659 return PreParserExpression(kThisPropertyExpression); |
611 } | 660 } |
612 | 661 |
613 static PreParserExpression Property() { | 662 static PreParserExpression Property() { |
614 return PreParserExpression(kPropertyExpression); | 663 return PreParserExpression(kPropertyExpression); |
615 } | 664 } |
616 | 665 |
617 static PreParserExpression Call() { | 666 static PreParserExpression Call() { |
618 return PreParserExpression(kCallExpression); | 667 return PreParserExpression(kCallExpression); |
619 } | 668 } |
620 | 669 |
621 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } | 670 bool IsIdentifier() const { |
671 return (code_ & kTypeMask) == kTypeIdentifier; | |
672 } | |
622 | 673 |
623 PreParserIdentifier AsIdentifier() { | 674 PreParserIdentifier AsIdentifier() const { |
624 ASSERT(IsIdentifier()); | 675 ASSERT(IsIdentifier()); |
625 return PreParserIdentifier( | 676 return PreParserIdentifier( |
626 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); | 677 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); |
627 } | 678 } |
628 | 679 |
629 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } | 680 bool IsStringLiteral() const { |
681 return (code_ & kTypeMask) == kTypeStringLiteral; | |
682 } | |
630 | 683 |
631 bool IsUseStrictLiteral() { | 684 bool IsUseStrictLiteral() { |
632 return (code_ & kStringLiteralMask) == kUseStrictString; | 685 return (code_ & kUseStrictString) == kUseStrictString; |
633 } | 686 } |
634 | 687 |
635 bool IsThis() { return code_ == kThisExpression; } | 688 bool IsThis() { return code_ == kThisExpression; } |
636 | 689 |
637 bool IsThisProperty() { return code_ == kThisPropertyExpression; } | 690 bool IsThisProperty() { return code_ == kThisPropertyExpression; } |
638 | 691 |
639 bool IsProperty() { | 692 bool IsProperty() { |
640 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; | 693 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; |
641 } | 694 } |
642 | 695 |
643 bool IsCall() { return code_ == kCallExpression; } | 696 bool IsCall() { return code_ == kCallExpression; } |
644 | 697 |
645 bool IsValidReferenceExpression() { | 698 bool IsValidReferenceExpression() { |
646 return IsIdentifier() || IsProperty(); | 699 return IsIdentifier() || IsProperty(); |
647 } | 700 } |
648 | 701 |
702 bool IsValidArrowParamList() const { | |
703 return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0 | |
704 && (code_ & kMultiParenthesizedExpression) == 0; | |
705 } | |
706 | |
649 // At the moment PreParser doesn't track these expression types. | 707 // At the moment PreParser doesn't track these expression types. |
650 bool IsFunctionLiteral() const { return false; } | 708 bool IsFunctionLiteral() const { return false; } |
651 bool IsCallNew() const { return false; } | 709 bool IsCallNew() const { return false; } |
652 | 710 |
653 PreParserExpression AsFunctionLiteral() { return *this; } | 711 PreParserExpression AsFunctionLiteral() { return *this; } |
654 | 712 |
713 bool IsBinaryOperation() const { | |
714 return (code_ & kTypeMask) == kTypeBinaryOperation; | |
715 } | |
716 | |
717 bool is_parenthesized() const { | |
718 return (code_ & kParenthesizedExpression) != 0; | |
719 } | |
720 | |
721 void increase_parenthesization_level() { | |
722 code_ |= is_parenthesized() | |
723 ? kMultiParenthesizedExpression | |
724 : kParenthesizedExpression; | |
725 } | |
726 | |
655 // Dummy implementation for making expression->somefunc() work in both Parser | 727 // Dummy implementation for making expression->somefunc() work in both Parser |
656 // and PreParser. | 728 // and PreParser. |
657 PreParserExpression* operator->() { return this; } | 729 PreParserExpression* operator->() { return this; } |
658 | 730 |
659 // More dummy implementations of things PreParser doesn't need to track: | 731 // More dummy implementations of things PreParser doesn't need to track: |
660 void set_index(int index) {} // For YieldExpressions | 732 void set_index(int index) {} // For YieldExpressions |
661 void set_parenthesized() {} | 733 void set_parenthesized() {} |
662 | 734 |
735 int position() const { return RelocInfo::kNoPosition; } | |
736 void set_function_token_position(int position) {} | |
737 void set_ast_properties(int* ast_properties) {} | |
738 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {} | |
739 | |
740 bool operator==(const PreParserExpression& other) const { | |
741 return code_ == other.code_; | |
742 } | |
743 bool operator!=(const PreParserExpression& other) const { | |
744 return code_ != other.code_; | |
745 } | |
746 | |
663 private: | 747 private: |
664 // Least significant 2 bits are used as flags. Bits 0 and 1 represent | 748 // Least significant 2 bits are used as expression type. The third least |
665 // identifiers or strings literals, and are mutually exclusive, but can both | 749 // significant bit tracks whether an expression is parenthesized. If the |
666 // be absent. If the expression is an identifier or a string literal, the | 750 // expression is an identifier or a string literal, the other bits |
667 // other bits describe the type (see PreParserIdentifier::Type and string | 751 // describe the type/ (see PreParserIdentifier::Type and string literal |
668 // literal constants below). | 752 // constants below). For binary operations, the other bits are flags |
753 // which further describe the contents of the expression. | |
669 enum { | 754 enum { |
670 kUnknownExpression = 0, | 755 kUnknownExpression = 0, |
756 | |
757 kTypeMask = 1 | 2, | |
758 kParenthesizedExpression = (1 << 2), | |
759 kMultiParenthesizedExpression = (1 << 3), | |
760 | |
671 // Identifiers | 761 // Identifiers |
672 kIdentifierFlag = 1, // Used to detect labels. | 762 kTypeIdentifier = 1, // Used to detect labels. |
673 kIdentifierShift = 3, | 763 kIdentifierShift = 5, |
674 | 764 |
675 kStringLiteralFlag = 2, // Used to detect directive prologue. | 765 kTypeStringLiteral = 2, // Used to detect directive prologue. |
676 kUnknownStringLiteral = kStringLiteralFlag, | 766 kUnknownStringLiteral = kTypeStringLiteral, |
677 kUseStrictString = kStringLiteralFlag | 8, | 767 kUseStrictString = kTypeStringLiteral | 32, |
678 kStringLiteralMask = kUseStrictString, | 768 kStringLiteralMask = kUseStrictString, |
679 | 769 |
770 // Binary operations. Those are needed to detect certain keywords and | |
771 // duplicated identifier in parameter lists for arrow functions, because | |
772 // they are initially parsed as comma-separated expressions. | |
773 kTypeBinaryOperation = 3, | |
774 kBinaryOperationArrowParamList = (1 << 4), | |
775 | |
680 // Below here applies if neither identifier nor string literal. Reserve the | 776 // Below here applies if neither identifier nor string literal. Reserve the |
681 // 2 least significant bits for flags. | 777 // 2 least significant bits for flags. |
682 kThisExpression = 1 << 2, | 778 kThisExpression = (1 << 4), |
683 kThisPropertyExpression = 2 << 2, | 779 kThisPropertyExpression = (2 << 4), |
684 kPropertyExpression = 3 << 2, | 780 kPropertyExpression = (3 << 4), |
685 kCallExpression = 4 << 2 | 781 kCallExpression = (4 << 4) |
686 }; | 782 }; |
687 | 783 |
688 explicit PreParserExpression(int expression_code) : code_(expression_code) {} | 784 explicit PreParserExpression(int expression_code) : code_(expression_code) {} |
689 | 785 |
786 V8_INLINE int ArrowParamListBit() const { | |
787 if (IsBinaryOperation()) | |
788 return code_ & kBinaryOperationArrowParamList; | |
789 if (IsIdentifier()) { | |
790 const PreParserIdentifier ident = AsIdentifier(); | |
791 // A valid identifier can be an arrow function parameter list | |
792 // except for eval, arguments, yield, and reserved keywords. | |
793 if (ident.IsEval() || ident.IsArguments() || ident.IsYield() | |
794 || ident.IsFutureStrictReserved()) | |
795 return 0; | |
796 return kBinaryOperationArrowParamList; | |
797 } | |
798 return 0; | |
799 } | |
800 | |
690 int code_; | 801 int code_; |
691 }; | 802 }; |
692 | 803 |
693 | 804 |
694 // PreParserExpressionList doesn't actually store the expressions because | 805 // PreParserExpressionList doesn't actually store the expressions because |
695 // PreParser doesn't need to. | 806 // PreParser doesn't need to. |
696 class PreParserExpressionList { | 807 class PreParserExpressionList { |
697 public: | 808 public: |
698 // These functions make list->Add(some_expression) work (and do nothing). | 809 // These functions make list->Add(some_expression) work (and do nothing). |
699 PreParserExpressionList() : length_(0) {} | 810 PreParserExpressionList() : length_(0) {} |
(...skipping 61 matching lines...) Loading... | |
761 public: | 872 public: |
762 // These functions make list->Add(some_expression) work as no-ops. | 873 // These functions make list->Add(some_expression) work as no-ops. |
763 PreParserStatementList() {} | 874 PreParserStatementList() {} |
764 PreParserStatementList* operator->() { return this; } | 875 PreParserStatementList* operator->() { return this; } |
765 void Add(PreParserStatement, void*) {} | 876 void Add(PreParserStatement, void*) {} |
766 }; | 877 }; |
767 | 878 |
768 | 879 |
769 class PreParserScope { | 880 class PreParserScope { |
770 public: | 881 public: |
771 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) | 882 explicit PreParserScope(PreParserScope* outer_scope, |
772 : scope_type_(scope_type) { | 883 ScopeType scope_type, |
884 void* = NULL) | |
885 : scope_type_(scope_type), declared_parameters_(0) { | |
773 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; | 886 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; |
774 } | 887 } |
775 | 888 |
776 ScopeType type() { return scope_type_; } | 889 ScopeType type() { return scope_type_; } |
777 StrictMode strict_mode() const { return strict_mode_; } | 890 StrictMode strict_mode() const { return strict_mode_; } |
778 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } | 891 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } |
779 | 892 |
893 // TODO(aperezdc): Would allowing lazy compilation in preparser make sense? | |
marja
2014/07/01 07:23:40
Doesn't seem very sensemaking to me, when we are i
| |
894 bool AllowsLazyCompilation() const { return false; } | |
895 | |
896 void set_start_position(int position) {} | |
897 void set_end_position(int position) {} | |
898 | |
899 bool IsDeclared(const PreParserIdentifier& identifier) const { | |
marja
2014/07/01 07:23:40
What cases does this IsDeclared actually detect? P
| |
900 return (declared_parameters_ & (1 << identifier.type_)) != 0; | |
901 } | |
902 | |
903 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) { | |
904 declared_parameters_ |= (1 << identifier.type_); | |
905 } | |
906 | |
907 // Allow scope->Foo() to work. | |
908 PreParserScope* operator->() { return this; } | |
909 | |
780 private: | 910 private: |
781 ScopeType scope_type_; | 911 ScopeType scope_type_; |
782 StrictMode strict_mode_; | 912 StrictMode strict_mode_; |
913 int declared_parameters_; | |
783 }; | 914 }; |
784 | 915 |
785 | 916 |
786 class PreParserFactory { | 917 class PreParserFactory { |
787 public: | 918 public: |
788 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} | 919 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} |
789 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, | 920 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, |
790 int pos) { | 921 int pos) { |
791 return PreParserExpression::Default(); | 922 return PreParserExpression::Default(); |
792 } | 923 } |
(...skipping 40 matching lines...) Loading... | |
833 return PreParserExpression::Property(); | 964 return PreParserExpression::Property(); |
834 } | 965 } |
835 PreParserExpression NewUnaryOperation(Token::Value op, | 966 PreParserExpression NewUnaryOperation(Token::Value op, |
836 PreParserExpression expression, | 967 PreParserExpression expression, |
837 int pos) { | 968 int pos) { |
838 return PreParserExpression::Default(); | 969 return PreParserExpression::Default(); |
839 } | 970 } |
840 PreParserExpression NewBinaryOperation(Token::Value op, | 971 PreParserExpression NewBinaryOperation(Token::Value op, |
841 PreParserExpression left, | 972 PreParserExpression left, |
842 PreParserExpression right, int pos) { | 973 PreParserExpression right, int pos) { |
843 return PreParserExpression::Default(); | 974 return PreParserExpression::BinaryOperation(left, op, right); |
844 } | 975 } |
845 PreParserExpression NewCompareOperation(Token::Value op, | 976 PreParserExpression NewCompareOperation(Token::Value op, |
846 PreParserExpression left, | 977 PreParserExpression left, |
847 PreParserExpression right, int pos) { | 978 PreParserExpression right, int pos) { |
848 return PreParserExpression::Default(); | 979 return PreParserExpression::Default(); |
849 } | 980 } |
850 PreParserExpression NewAssignment(Token::Value op, | 981 PreParserExpression NewAssignment(Token::Value op, |
851 PreParserExpression left, | 982 PreParserExpression left, |
852 PreParserExpression right, | 983 PreParserExpression right, |
853 int pos) { | 984 int pos) { |
(...skipping 20 matching lines...) Loading... | |
874 PreParserExpression NewCall(PreParserExpression expression, | 1005 PreParserExpression NewCall(PreParserExpression expression, |
875 PreParserExpressionList arguments, | 1006 PreParserExpressionList arguments, |
876 int pos) { | 1007 int pos) { |
877 return PreParserExpression::Call(); | 1008 return PreParserExpression::Call(); |
878 } | 1009 } |
879 PreParserExpression NewCallNew(PreParserExpression expression, | 1010 PreParserExpression NewCallNew(PreParserExpression expression, |
880 PreParserExpressionList arguments, | 1011 PreParserExpressionList arguments, |
881 int pos) { | 1012 int pos) { |
882 return PreParserExpression::Default(); | 1013 return PreParserExpression::Default(); |
883 } | 1014 } |
1015 PreParserStatement NewReturnStatement(PreParserExpression expression, | |
1016 int pos) { | |
1017 return PreParserStatement::Default(); | |
1018 } | |
1019 PreParserExpression | |
1020 NewFunctionLiteral(PreParserIdentifier name, | |
1021 PreParserScope& scope, | |
1022 PreParserStatementList body, | |
1023 int materialized_literal_count, | |
1024 int expected_property_count, | |
1025 int handler_count, | |
1026 int parameter_count, | |
1027 FunctionLiteral::ParameterFlag has_duplicate_parameters, | |
1028 FunctionLiteral::FunctionType function_type, | |
1029 FunctionLiteral::IsFunctionFlag is_function, | |
1030 FunctionLiteral::IsParenthesizedFlag is_parenthesized, | |
1031 FunctionLiteral::IsGeneratorFlag is_generator, | |
1032 int position) { | |
1033 return PreParserExpression::Default(); | |
1034 } | |
1035 | |
1036 // Return the object itself as AstVisitor and implement the needed | |
1037 // dummy method right in this class. | |
1038 PreParserFactory* visitor() { return this; } | |
1039 BailoutReason dont_optimize_reason() { return kNoReason; } | |
1040 int* ast_properties() { static int dummy = 42; return &dummy; } | |
884 }; | 1041 }; |
885 | 1042 |
886 | 1043 |
887 class PreParser; | 1044 class PreParser; |
888 | 1045 |
889 class PreParserTraits { | 1046 class PreParserTraits { |
890 public: | 1047 public: |
891 struct Type { | 1048 struct Type { |
892 // TODO(marja): To be removed. The Traits object should contain all the data | 1049 // TODO(marja): To be removed. The Traits object should contain all the data |
893 // it needs. | 1050 // it needs. |
894 typedef PreParser* Parser; | 1051 typedef PreParser* Parser; |
895 | 1052 |
896 // Used by FunctionState and BlockState. | 1053 // Used by FunctionState and BlockState. |
897 typedef PreParserScope Scope; | 1054 typedef PreParserScope Scope; |
1055 typedef PreParserScope ScopePtr; | |
1056 | |
898 // PreParser doesn't need to store generator variables. | 1057 // PreParser doesn't need to store generator variables. |
899 typedef void GeneratorVariable; | 1058 typedef void GeneratorVariable; |
900 // No interaction with Zones. | 1059 // No interaction with Zones. |
901 typedef void Zone; | 1060 typedef void Zone; |
902 | 1061 |
1062 typedef int AstProperties; | |
1063 typedef Vector<PreParserIdentifier> ParameterIdentifierVector; | |
1064 | |
903 // Return types for traversing functions. | 1065 // Return types for traversing functions. |
904 typedef PreParserIdentifier Identifier; | 1066 typedef PreParserIdentifier Identifier; |
905 typedef PreParserExpression Expression; | 1067 typedef PreParserExpression Expression; |
906 typedef PreParserExpression YieldExpression; | 1068 typedef PreParserExpression YieldExpression; |
907 typedef PreParserExpression FunctionLiteral; | 1069 typedef PreParserExpression FunctionLiteral; |
908 typedef PreParserExpression ObjectLiteralProperty; | 1070 typedef PreParserExpression ObjectLiteralProperty; |
909 typedef PreParserExpression Literal; | 1071 typedef PreParserExpression Literal; |
910 typedef PreParserExpressionList ExpressionList; | 1072 typedef PreParserExpressionList ExpressionList; |
911 typedef PreParserExpressionList PropertyList; | 1073 typedef PreParserExpressionList PropertyList; |
912 typedef PreParserStatementList StatementList; | 1074 typedef PreParserStatementList StatementList; |
(...skipping 22 matching lines...) Loading... | |
935 } | 1097 } |
936 | 1098 |
937 static bool IsIdentifier(PreParserExpression expression) { | 1099 static bool IsIdentifier(PreParserExpression expression) { |
938 return expression.IsIdentifier(); | 1100 return expression.IsIdentifier(); |
939 } | 1101 } |
940 | 1102 |
941 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { | 1103 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { |
942 return expression.AsIdentifier(); | 1104 return expression.AsIdentifier(); |
943 } | 1105 } |
944 | 1106 |
1107 static bool IsFutureStrictReserved(PreParserIdentifier identifier) { | |
1108 return identifier.IsYield() || identifier.IsFutureStrictReserved(); | |
1109 } | |
1110 | |
945 static bool IsBoilerplateProperty(PreParserExpression property) { | 1111 static bool IsBoilerplateProperty(PreParserExpression property) { |
946 // PreParser doesn't count boilerplate properties. | 1112 // PreParser doesn't count boilerplate properties. |
947 return false; | 1113 return false; |
948 } | 1114 } |
949 | 1115 |
950 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { | 1116 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { |
951 return false; | 1117 return false; |
952 } | 1118 } |
953 | 1119 |
954 // Functions for encapsulating the differences between parsing and preparsing; | 1120 // Functions for encapsulating the differences between parsing and preparsing; |
(...skipping 43 matching lines...) Loading... | |
998 return PreParserExpression::Default(); | 1164 return PreParserExpression::Default(); |
999 } | 1165 } |
1000 PreParserExpression NewThrowSyntaxError( | 1166 PreParserExpression NewThrowSyntaxError( |
1001 const char* type, Handle<Object> arg, int pos) { | 1167 const char* type, Handle<Object> arg, int pos) { |
1002 return PreParserExpression::Default(); | 1168 return PreParserExpression::Default(); |
1003 } | 1169 } |
1004 PreParserExpression NewThrowTypeError( | 1170 PreParserExpression NewThrowTypeError( |
1005 const char* type, Handle<Object> arg, int pos) { | 1171 const char* type, Handle<Object> arg, int pos) { |
1006 return PreParserExpression::Default(); | 1172 return PreParserExpression::Default(); |
1007 } | 1173 } |
1174 PreParserScope NewScope(PreParserScope* outer_scope, | |
1175 ScopeType scope_type) { | |
1176 return PreParserScope(outer_scope, scope_type); | |
1177 } | |
1008 | 1178 |
1009 // Reporting errors. | 1179 // Reporting errors. |
1010 void ReportMessageAt(Scanner::Location location, | 1180 void ReportMessageAt(Scanner::Location location, |
1011 const char* message, | 1181 const char* message, |
1012 const char* arg = NULL, | 1182 const char* arg = NULL, |
1013 bool is_reference_error = false); | 1183 bool is_reference_error = false); |
1014 void ReportMessageAt(int start_pos, | 1184 void ReportMessageAt(int start_pos, |
1015 int end_pos, | 1185 int end_pos, |
1016 const char* message, | 1186 const char* message, |
1017 const char* arg = NULL, | 1187 const char* arg = NULL, |
1018 bool is_reference_error = false); | 1188 bool is_reference_error = false); |
1019 | 1189 |
1020 // "null" return type creators. | 1190 // "null" return type creators. |
1021 static PreParserIdentifier EmptyIdentifier() { | 1191 static PreParserIdentifier EmptyIdentifier() { |
1022 return PreParserIdentifier::Default(); | 1192 return PreParserIdentifier::Default(); |
1023 } | 1193 } |
1024 static PreParserExpression EmptyExpression() { | 1194 static PreParserExpression EmptyExpression() { |
1025 return PreParserExpression::Default(); | 1195 return PreParserExpression::Default(); |
1026 } | 1196 } |
1197 static PreParserExpression EmptyArrowParamList() { | |
1198 return PreParserExpression::EmptyArrowParamList(); | |
1199 } | |
1027 static PreParserExpression EmptyLiteral() { | 1200 static PreParserExpression EmptyLiteral() { |
1028 return PreParserExpression::Default(); | 1201 return PreParserExpression::Default(); |
1029 } | 1202 } |
1030 static PreParserExpressionList NullExpressionList() { | 1203 static PreParserExpressionList NullExpressionList() { |
1031 return PreParserExpressionList(); | 1204 return PreParserExpressionList(); |
1032 } | 1205 } |
1033 | 1206 |
1034 // Odd-ball literal creators. | 1207 // Odd-ball literal creators. |
1035 static PreParserExpression GetLiteralTheHole(int position, | 1208 static PreParserExpression GetLiteralTheHole(int position, |
1036 PreParserFactory* factory) { | 1209 PreParserFactory* factory) { |
(...skipping 33 matching lines...) Loading... | |
1070 } | 1243 } |
1071 | 1244 |
1072 static PreParserStatementList NewStatementList(int size, void* zone) { | 1245 static PreParserStatementList NewStatementList(int size, void* zone) { |
1073 return PreParserStatementList(); | 1246 return PreParserStatementList(); |
1074 } | 1247 } |
1075 | 1248 |
1076 static PreParserExpressionList NewPropertyList(int size, void* zone) { | 1249 static PreParserExpressionList NewPropertyList(int size, void* zone) { |
1077 return PreParserExpressionList(); | 1250 return PreParserExpressionList(); |
1078 } | 1251 } |
1079 | 1252 |
1253 V8_INLINE void SkipLazyFunctionBody( | |
1254 PreParserIdentifier function_name, | |
1255 int* materialized_literal_count, | |
1256 int* expected_property_count, | |
1257 bool* ok) { | |
1258 UNREACHABLE(); | |
1259 } | |
1260 | |
1261 V8_INLINE PreParserStatementList ParseEagerFunctionBody( | |
1262 PreParserIdentifier function_name, | |
1263 int pos, | |
1264 Variable* fvar, | |
1265 Token::Value fvar_init_op, | |
1266 bool is_generator, | |
1267 bool* ok); | |
1268 | |
1269 // Utility functions | |
1270 Vector<PreParserIdentifier> ParameterListFromExpression( | |
1271 PreParserExpression expression) { | |
1272 return Vector<PreParserIdentifier>::empty(); | |
1273 } | |
1274 bool IsValidArrowFunctionParameterList(PreParserExpression expression) { | |
marja
2014/07/01 07:23:40
Pls reorder these functions so that they're in the
| |
1275 // TODO(aperez): Detect duplicated identifiers in paramlists. | |
1276 return expression.IsValidArrowParamList(); | |
1277 } | |
1278 static AstValueFactory* ast_value_factory() { return NULL; } | |
1279 | |
1280 void CheckConflictingVarDeclarations( | |
marja
2014/07/01 07:23:40
Nit: formatting.
You'd probably want to have a lo
| |
1281 PreParserScope scope, | |
1282 bool* ok) {} | |
1283 | |
1080 // Temporary glue; these functions will move to ParserBase. | 1284 // Temporary glue; these functions will move to ParserBase. |
1081 PreParserExpression ParseV8Intrinsic(bool* ok); | 1285 PreParserExpression ParseV8Intrinsic(bool* ok); |
1082 PreParserExpression ParseFunctionLiteral( | 1286 PreParserExpression ParseFunctionLiteral( |
1083 PreParserIdentifier name, | 1287 PreParserIdentifier name, |
1084 Scanner::Location function_name_location, | 1288 Scanner::Location function_name_location, |
1085 bool name_is_strict_reserved, | 1289 bool name_is_strict_reserved, |
1086 bool is_generator, | 1290 bool is_generator, |
1087 int function_token_position, | 1291 int function_token_position, |
1088 FunctionLiteral::FunctionType type, | 1292 FunctionLiteral::FunctionType type, |
1089 FunctionLiteral::ArityRestriction arity_restriction, | 1293 FunctionLiteral::ArityRestriction arity_restriction, |
(...skipping 30 matching lines...) Loading... | |
1120 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) | 1324 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) |
1121 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, | 1325 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, |
1122 this) {} | 1326 this) {} |
1123 | 1327 |
1124 // Pre-parse the program from the character stream; returns true on | 1328 // Pre-parse the program from the character stream; returns true on |
1125 // success (even if parsing failed, the pre-parse data successfully | 1329 // success (even if parsing failed, the pre-parse data successfully |
1126 // captured the syntax error), and false if a stack-overflow happened | 1330 // captured the syntax error), and false if a stack-overflow happened |
1127 // during parsing. | 1331 // during parsing. |
1128 PreParseResult PreParseProgram() { | 1332 PreParseResult PreParseProgram() { |
1129 PreParserScope scope(scope_, GLOBAL_SCOPE); | 1333 PreParserScope scope(scope_, GLOBAL_SCOPE); |
1130 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); | 1334 FunctionState top_scope(&function_state_, &scope_, &scope); |
1131 bool ok = true; | 1335 bool ok = true; |
1132 int start_position = scanner()->peek_location().beg_pos; | 1336 int start_position = scanner()->peek_location().beg_pos; |
1133 ParseSourceElements(Token::EOS, &ok); | 1337 ParseSourceElements(Token::EOS, &ok); |
1134 if (stack_overflow()) return kPreParseStackOverflow; | 1338 if (stack_overflow()) return kPreParseStackOverflow; |
1135 if (!ok) { | 1339 if (!ok) { |
1136 ReportUnexpectedToken(scanner()->current_token()); | 1340 ReportUnexpectedToken(scanner()->current_token()); |
1137 } else if (scope_->strict_mode() == STRICT) { | 1341 } else if (scope_->strict_mode() == STRICT) { |
1138 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); | 1342 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); |
1139 } | 1343 } |
1140 return kPreParseSuccess; | 1344 return kPreParseSuccess; |
(...skipping 61 matching lines...) Loading... | |
1202 Statement ParseDoWhileStatement(bool* ok); | 1406 Statement ParseDoWhileStatement(bool* ok); |
1203 Statement ParseWhileStatement(bool* ok); | 1407 Statement ParseWhileStatement(bool* ok); |
1204 Statement ParseForStatement(bool* ok); | 1408 Statement ParseForStatement(bool* ok); |
1205 Statement ParseThrowStatement(bool* ok); | 1409 Statement ParseThrowStatement(bool* ok); |
1206 Statement ParseTryStatement(bool* ok); | 1410 Statement ParseTryStatement(bool* ok); |
1207 Statement ParseDebuggerStatement(bool* ok); | 1411 Statement ParseDebuggerStatement(bool* ok); |
1208 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 1412 Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
1209 Expression ParseObjectLiteral(bool* ok); | 1413 Expression ParseObjectLiteral(bool* ok); |
1210 Expression ParseV8Intrinsic(bool* ok); | 1414 Expression ParseV8Intrinsic(bool* ok); |
1211 | 1415 |
1416 V8_INLINE void SkipLazyFunctionBody( | |
1417 PreParserIdentifier function_name, | |
1418 int* materialized_literal_count, | |
1419 int* expected_property_count, | |
1420 bool* ok); | |
1421 V8_INLINE PreParserStatementList ParseEagerFunctionBody( | |
1422 PreParserIdentifier function_name, | |
1423 int pos, | |
1424 Variable* fvar, | |
1425 Token::Value fvar_init_op, | |
1426 bool is_generator, | |
1427 bool* ok); | |
1428 | |
1212 Expression ParseFunctionLiteral( | 1429 Expression ParseFunctionLiteral( |
1213 Identifier name, | 1430 Identifier name, |
1214 Scanner::Location function_name_location, | 1431 Scanner::Location function_name_location, |
1215 bool name_is_strict_reserved, | 1432 bool name_is_strict_reserved, |
1216 bool is_generator, | 1433 bool is_generator, |
1217 int function_token_pos, | 1434 int function_token_pos, |
1218 FunctionLiteral::FunctionType function_type, | 1435 FunctionLiteral::FunctionType function_type, |
1219 FunctionLiteral::ArityRestriction arity_restriction, | 1436 FunctionLiteral::ArityRestriction arity_restriction, |
1220 bool* ok); | 1437 bool* ok); |
1221 void ParseLazyFunctionLiteralBody(bool* ok); | 1438 void ParseLazyFunctionLiteralBody(bool* ok); |
1222 | 1439 |
1223 bool CheckInOrOf(bool accept_OF); | 1440 bool CheckInOrOf(bool accept_OF); |
1224 }; | 1441 }; |
1225 | 1442 |
1443 | |
1444 PreParserStatementList PreParser::ParseEagerFunctionBody( | |
1445 PreParserIdentifier function_name, | |
1446 int pos, | |
1447 Variable* fvar, | |
1448 Token::Value fvar_init_op, | |
1449 bool is_generator, | |
1450 bool* ok) { | |
1451 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | |
1452 | |
1453 ParseSourceElements(Token::RBRACE, ok); | |
1454 if (!*ok) return PreParserStatementList(); | |
1455 | |
1456 Expect(Token::RBRACE, ok); | |
1457 return PreParserStatementList(); | |
1458 } | |
1459 | |
1460 | |
1461 PreParserStatementList PreParserTraits::ParseEagerFunctionBody( | |
1462 PreParserIdentifier function_name, | |
1463 int pos, | |
1464 Variable* fvar, | |
1465 Token::Value fvar_init_op, | |
1466 bool is_generator, | |
1467 bool* ok) { | |
1468 return pre_parser_->ParseEagerFunctionBody(function_name, | |
1469 pos, fvar, fvar_init_op, is_generator, ok); | |
1470 } | |
1471 | |
1472 | |
1226 template<class Traits> | 1473 template<class Traits> |
1227 ParserBase<Traits>::FunctionState::FunctionState( | 1474 ParserBase<Traits>::FunctionState::FunctionState( |
1228 FunctionState** function_state_stack, | 1475 FunctionState** function_state_stack, |
1229 typename Traits::Type::Scope** scope_stack, | 1476 typename Traits::Type::Scope** scope_stack, |
1230 typename Traits::Type::Scope* scope, | 1477 typename Traits::Type::Scope* scope, |
1231 typename Traits::Type::Zone* extra_param, | 1478 typename Traits::Type::Zone* extra_param, |
1232 AstValueFactory* ast_value_factory) | 1479 AstValueFactory* ast_value_factory) |
1233 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | 1480 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
1234 next_handler_index_(0), | 1481 next_handler_index_(0), |
1235 expected_property_count_(0), | 1482 expected_property_count_(0), |
1236 is_generator_(false), | 1483 is_generator_(false), |
1237 generator_object_variable_(NULL), | 1484 generator_object_variable_(NULL), |
1238 function_state_stack_(function_state_stack), | 1485 function_state_stack_(function_state_stack), |
1239 outer_function_state_(*function_state_stack), | 1486 outer_function_state_(*function_state_stack), |
1240 scope_stack_(scope_stack), | 1487 scope_stack_(scope_stack), |
1241 outer_scope_(*scope_stack), | 1488 outer_scope_(*scope_stack), |
1242 saved_ast_node_id_(0), | 1489 saved_ast_node_id_(0), |
1243 extra_param_(extra_param), | 1490 extra_param_(extra_param), |
1244 factory_(extra_param, ast_value_factory) { | 1491 factory_(extra_param, ast_value_factory) { |
1245 *scope_stack_ = scope; | 1492 *scope_stack_ = scope; |
1246 *function_state_stack = this; | 1493 *function_state_stack = this; |
1247 Traits::SetUpFunctionState(this, extra_param); | 1494 Traits::SetUpFunctionState(this, extra_param); |
1248 } | 1495 } |
1249 | 1496 |
1250 | 1497 |
1251 template<class Traits> | 1498 template<class Traits> |
1499 ParserBase<Traits>::FunctionState::FunctionState( | |
1500 FunctionState** function_state_stack, | |
1501 typename Traits::Type::Scope** scope_stack, | |
1502 typename Traits::Type::Scope** scope, | |
1503 typename Traits::Type::Zone* extra_param, | |
1504 AstValueFactory* ast_value_factory) | |
1505 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | |
1506 next_handler_index_(0), | |
1507 expected_property_count_(0), | |
1508 is_generator_(false), | |
1509 generator_object_variable_(NULL), | |
1510 function_state_stack_(function_state_stack), | |
1511 outer_function_state_(*function_state_stack), | |
1512 scope_stack_(scope_stack), | |
1513 outer_scope_(*scope_stack), | |
1514 saved_ast_node_id_(0), | |
1515 extra_param_(extra_param), | |
1516 factory_(extra_param, ast_value_factory) { | |
1517 *scope_stack_ = *scope; | |
1518 *function_state_stack = this; | |
1519 Traits::SetUpFunctionState(this, extra_param); | |
1520 } | |
1521 | |
1522 | |
1523 template<class Traits> | |
1252 ParserBase<Traits>::FunctionState::~FunctionState() { | 1524 ParserBase<Traits>::FunctionState::~FunctionState() { |
1253 *scope_stack_ = outer_scope_; | 1525 *scope_stack_ = outer_scope_; |
1254 *function_state_stack_ = outer_function_state_; | 1526 *function_state_stack_ = outer_function_state_; |
1255 Traits::TearDownFunctionState(this, extra_param_); | 1527 Traits::TearDownFunctionState(this, extra_param_); |
1256 } | 1528 } |
1257 | 1529 |
1258 | 1530 |
1259 template<class Traits> | 1531 template<class Traits> |
1260 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { | 1532 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { |
1261 Scanner::Location source_location = scanner()->location(); | 1533 Scanner::Location source_location = scanner()->location(); |
(...skipping 191 matching lines...) Loading... | |
1453 case Token::LBRACK: | 1725 case Token::LBRACK: |
1454 result = this->ParseArrayLiteral(CHECK_OK); | 1726 result = this->ParseArrayLiteral(CHECK_OK); |
1455 break; | 1727 break; |
1456 | 1728 |
1457 case Token::LBRACE: | 1729 case Token::LBRACE: |
1458 result = this->ParseObjectLiteral(CHECK_OK); | 1730 result = this->ParseObjectLiteral(CHECK_OK); |
1459 break; | 1731 break; |
1460 | 1732 |
1461 case Token::LPAREN: | 1733 case Token::LPAREN: |
1462 Consume(Token::LPAREN); | 1734 Consume(Token::LPAREN); |
1463 // Heuristically try to detect immediately called functions before | 1735 if (allow_arrow_functions() && peek() == Token::RPAREN) { |
1464 // seeing the call parentheses. | 1736 // Arrow functions are the only expression type constructions |
1465 parenthesized_function_ = (peek() == Token::FUNCTION); | 1737 // for which an empty parameter list "()" is valid input. |
1466 result = this->ParseExpression(true, CHECK_OK); | 1738 Consume(Token::RPAREN); |
1467 Expect(Token::RPAREN, CHECK_OK); | 1739 return this->ParseArrowFunctionLiteral(pos, |
1740 this->EmptyArrowParamList(), | |
1741 CHECK_OK); | |
1742 } else { | |
1743 // Heuristically try to detect immediately called functions before | |
1744 // seeing the call parentheses. | |
1745 parenthesized_function_ = (peek() == Token::FUNCTION); | |
1746 result = this->ParseExpression(true, CHECK_OK); | |
1747 result->increase_parenthesization_level(); | |
1748 Expect(Token::RPAREN, CHECK_OK); | |
1749 } | |
1468 break; | 1750 break; |
1469 | 1751 |
1470 case Token::MOD: | 1752 case Token::MOD: |
1471 if (allow_natives_syntax() || extension_ != NULL) { | 1753 if (allow_natives_syntax() || extension_ != NULL) { |
1472 result = this->ParseV8Intrinsic(CHECK_OK); | 1754 result = this->ParseV8Intrinsic(CHECK_OK); |
1473 break; | 1755 break; |
1474 } | 1756 } |
1475 // If we're not allowing special syntax we fall-through to the | 1757 // If we're not allowing special syntax we fall-through to the |
1476 // default case. | 1758 // default case. |
1477 | 1759 |
(...skipping 247 matching lines...) Loading... | |
1725 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2007 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
1726 return result; | 2008 return result; |
1727 } | 2009 } |
1728 | 2010 |
1729 // Precedence = 2 | 2011 // Precedence = 2 |
1730 template <class Traits> | 2012 template <class Traits> |
1731 typename ParserBase<Traits>::ExpressionT | 2013 typename ParserBase<Traits>::ExpressionT |
1732 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2014 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
1733 // AssignmentExpression :: | 2015 // AssignmentExpression :: |
1734 // ConditionalExpression | 2016 // ConditionalExpression |
2017 // ArrowFunction | |
1735 // YieldExpression | 2018 // YieldExpression |
1736 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2019 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
1737 | 2020 |
1738 Scanner::Location lhs_location = scanner()->peek_location(); | 2021 Scanner::Location lhs_location = scanner()->peek_location(); |
1739 | 2022 |
1740 if (peek() == Token::YIELD && is_generator()) { | 2023 if (peek() == Token::YIELD && is_generator()) { |
1741 return this->ParseYieldExpression(ok); | 2024 return this->ParseYieldExpression(ok); |
1742 } | 2025 } |
1743 | 2026 |
1744 if (fni_ != NULL) fni_->Enter(); | 2027 if (fni_ != NULL) fni_->Enter(); |
1745 ExpressionT expression = | 2028 ExpressionT expression = |
1746 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2029 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
1747 | 2030 |
2031 if (allow_arrow_functions() && peek() == Token::ARROW) | |
2032 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos, | |
2033 expression, | |
2034 CHECK_OK); | |
2035 | |
1748 if (!Token::IsAssignmentOp(peek())) { | 2036 if (!Token::IsAssignmentOp(peek())) { |
1749 if (fni_ != NULL) fni_->Leave(); | 2037 if (fni_ != NULL) fni_->Leave(); |
1750 // Parsed conditional expression only (no assignment). | 2038 // Parsed conditional expression only (no assignment). |
1751 return expression; | 2039 return expression; |
1752 } | 2040 } |
1753 | 2041 |
1754 expression = this->CheckAndRewriteReferenceExpression( | 2042 expression = this->CheckAndRewriteReferenceExpression( |
1755 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 2043 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); |
1756 expression = this->MarkExpressionAsAssigned(expression); | 2044 expression = this->MarkExpressionAsAssigned(expression); |
1757 | 2045 |
(...skipping 385 matching lines...) Loading... | |
2143 } | 2431 } |
2144 default: | 2432 default: |
2145 return expression; | 2433 return expression; |
2146 } | 2434 } |
2147 } | 2435 } |
2148 ASSERT(false); | 2436 ASSERT(false); |
2149 return this->EmptyExpression(); | 2437 return this->EmptyExpression(); |
2150 } | 2438 } |
2151 | 2439 |
2152 | 2440 |
2441 template <class Traits> | |
2442 typename ParserBase<Traits>::ExpressionT | |
2443 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, | |
2444 ExpressionT params_ast, | |
2445 bool* ok) { | |
2446 if (!this->IsValidArrowFunctionParameterList(params_ast)) { | |
2447 ReportMessageAt( | |
2448 Scanner::Location(start_pos, scanner()->location().beg_pos), | |
2449 "malformed_arrow_function_parameter_list"); | |
2450 *ok = false; | |
2451 return this->EmptyExpression(); | |
2452 } | |
2453 | |
2454 // TODO(aperez): Change this to use ARROW_SCOPE | |
2455 typename Traits::Type::ScopePtr scope = | |
2456 this->NewScope(scope_, FUNCTION_SCOPE); | |
2457 | |
2458 FunctionState function_state(&function_state_, &scope_, &scope, | |
2459 zone(), this->ast_value_factory()); | |
2460 typename Traits::Type::ParameterIdentifierVector params = | |
2461 Traits::ParameterListFromExpression(params_ast); | |
2462 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | |
2463 | |
2464 if (params.length() > Code::kMaxArguments) { | |
2465 ReportMessageAt(Scanner::Location(params_ast->position(), position()), | |
2466 "too_many_parameters"); | |
2467 *ok = false; | |
2468 return this->EmptyExpression(); | |
2469 } | |
2470 | |
2471 // The vector has the items in reverse order. | |
2472 for (int i = params.length() - 1; i >= 0; --i) { | |
2473 const IdentifierT param_name = params.at(i)->raw_name(); | |
2474 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | |
2475 int param_pos = params.at(i)->position(); | |
2476 dupe_error_loc = Scanner::Location(param_pos, | |
2477 param_pos + param_name->length()); | |
2478 } | |
2479 scope_->DeclareParameter(param_name, VAR); | |
2480 } | |
2481 | |
2482 return ParseArrowFunctionLiteralBody(&function_state, | |
2483 scope, | |
2484 params.length(), | |
2485 Scanner::Location::invalid(), | |
2486 dupe_error_loc, | |
2487 Scanner::Location::invalid(), | |
2488 FunctionLiteral::kNotParenthesized, | |
2489 start_pos, | |
2490 CHECK_OK); | |
2491 } | |
2492 | |
2493 | |
2494 template <class Traits> | |
2495 typename ParserBase<Traits>::ExpressionT | |
2496 ParserBase<Traits>::ParseArrowFunctionLiteralBody( | |
2497 FunctionState* function_state, | |
2498 typename Traits::Type::ScopePtr scope, | |
2499 int num_parameters, | |
2500 const Scanner::Location& eval_args_error_loc, | |
2501 const Scanner::Location& dupe_error_loc, | |
2502 const Scanner::Location& reserved_loc, | |
2503 FunctionLiteral::IsParenthesizedFlag parenthesized, | |
2504 int start_pos, | |
2505 bool* ok) { | |
2506 | |
2507 typename Traits::Type::StatementList body; | |
2508 int materialized_literal_count = -1; | |
2509 int expected_property_count = -1; | |
2510 | |
2511 Expect(Token::ARROW, CHECK_OK); | |
2512 | |
2513 if (peek() == Token::LBRACE) { | |
2514 // Multiple statemente body | |
2515 Consume(Token::LBRACE); | |
2516 bool is_lazily_parsed = (mode() == PARSE_LAZILY && | |
2517 scope_->AllowsLazyCompilation()); | |
2518 if (is_lazily_parsed) { | |
2519 this->SkipLazyFunctionBody(this->EmptyIdentifier(), | |
2520 &materialized_literal_count, | |
2521 &expected_property_count, | |
2522 CHECK_OK); | |
2523 } else { | |
2524 body = this->ParseEagerFunctionBody(this->EmptyIdentifier(), | |
2525 RelocInfo::kNoPosition, | |
2526 NULL, | |
2527 Token::INIT_VAR, | |
2528 false, // Not a generator. | |
2529 CHECK_OK); | |
2530 } | |
2531 } else { | |
2532 // Single-expression body | |
2533 ParseAssignmentExpression(true, CHECK_OK); | |
2534 } | |
2535 | |
2536 scope->set_start_position(start_pos); | |
2537 scope->set_end_position(scanner()->location().end_pos); | |
2538 | |
2539 this->CheckStrictFunctionNameAndParameters(this->EmptyIdentifier(), | |
marja
2014/07/01 07:23:40
This is not inside if (strict_mode() == STRICT) be
| |
2540 false, | |
2541 Scanner::Location::invalid(), | |
2542 Scanner::Location::invalid(), | |
2543 dupe_error_loc, | |
2544 Scanner::Location::invalid(), | |
2545 CHECK_OK); | |
2546 | |
2547 // Validate strict mode. | |
2548 if (strict_mode() == STRICT) { | |
2549 CheckOctalLiteral(start_pos, | |
2550 scanner()->location().end_pos, | |
2551 CHECK_OK); | |
2552 } | |
2553 | |
2554 if (allow_harmony_scoping() && strict_mode() == STRICT) | |
2555 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | |
2556 | |
2557 return this->EmptyExpression(); | |
marja
2014/07/01 07:23:40
This will change when you start generating the arr
| |
2558 } | |
2559 | |
2560 | |
2153 template <typename Traits> | 2561 template <typename Traits> |
2154 typename ParserBase<Traits>::ExpressionT | 2562 typename ParserBase<Traits>::ExpressionT |
2155 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 2563 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
2156 ExpressionT expression, | 2564 ExpressionT expression, |
2157 Scanner::Location location, const char* message, bool* ok) { | 2565 Scanner::Location location, const char* message, bool* ok) { |
2158 if (strict_mode() == STRICT && this->IsIdentifier(expression) && | 2566 if (strict_mode() == STRICT && this->IsIdentifier(expression) && |
2159 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 2567 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
2160 this->ReportMessageAt(location, "strict_eval_arguments", false); | 2568 this->ReportMessageAt(location, "strict_eval_arguments", false); |
2161 *ok = false; | 2569 *ok = false; |
2162 return this->EmptyExpression(); | 2570 return this->EmptyExpression(); |
(...skipping 43 matching lines...) Loading... | |
2206 parser()->ReportMessage("accessor_get_set"); | 2614 parser()->ReportMessage("accessor_get_set"); |
2207 } | 2615 } |
2208 *ok = false; | 2616 *ok = false; |
2209 } | 2617 } |
2210 } | 2618 } |
2211 | 2619 |
2212 | 2620 |
2213 } } // v8::internal | 2621 } } // v8::internal |
2214 | 2622 |
2215 #endif // V8_PREPARSER_H | 2623 #endif // V8_PREPARSER_H |
OLD | NEW |