OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/func-name-inferrer.h" | 10 #include "src/func-name-inferrer.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 // }; | 55 // }; |
56 // // ... | 56 // // ... |
57 // }; | 57 // }; |
58 | 58 |
59 template <typename Traits> | 59 template <typename Traits> |
60 class ParserBase : public Traits { | 60 class ParserBase : public Traits { |
61 public: | 61 public: |
62 // Shorten type names defined by Traits. | 62 // Shorten type names defined by Traits. |
63 typedef typename Traits::Type::Expression ExpressionT; | 63 typedef typename Traits::Type::Expression ExpressionT; |
64 typedef typename Traits::Type::Identifier IdentifierT; | 64 typedef typename Traits::Type::Identifier IdentifierT; |
65 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; | |
65 | 66 |
66 ParserBase(Scanner* scanner, uintptr_t stack_limit, | 67 ParserBase(Scanner* scanner, uintptr_t stack_limit, |
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...) Expand all 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 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
434 ExpressionT ParseYieldExpression(bool* ok); | 444 ExpressionT ParseYieldExpression(bool* ok); |
435 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 445 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
436 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 446 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
437 ExpressionT ParseUnaryExpression(bool* ok); | 447 ExpressionT ParseUnaryExpression(bool* ok); |
438 ExpressionT ParsePostfixExpression(bool* ok); | 448 ExpressionT ParsePostfixExpression(bool* ok); |
439 ExpressionT ParseLeftHandSideExpression(bool* ok); | 449 ExpressionT ParseLeftHandSideExpression(bool* ok); |
440 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 450 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
441 ExpressionT ParseMemberExpression(bool* ok); | 451 ExpressionT ParseMemberExpression(bool* ok); |
442 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 452 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
443 bool* ok); | 453 bool* ok); |
454 ExpressionT ParseArrowFunctionLiteral(int start_pos, | |
455 ExpressionT params_ast, | |
456 bool* ok); | |
457 ExpressionT ParseArrowFunctionLiteralBody( | |
458 FunctionState* function_state, | |
459 typename Traits::Type::ScopePtr scope, | |
460 int num_parameters, | |
461 const Scanner::Location& eval_args_error_loc, | |
462 const Scanner::Location& dupe_error_loc, | |
463 const Scanner::Location& reserved_loc, | |
464 FunctionLiteral::IsParenthesizedFlag parenthesized, | |
465 int start_pos, | |
466 bool* ok); | |
444 | 467 |
445 // Checks if the expression is a valid reference expression (e.g., on the | 468 // Checks if the expression is a valid reference expression (e.g., on the |
446 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 469 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
447 // we allow calls for web compatibility and rewrite them to a runtime throw. | 470 // we allow calls for web compatibility and rewrite them to a runtime throw. |
448 ExpressionT CheckAndRewriteReferenceExpression( | 471 ExpressionT CheckAndRewriteReferenceExpression( |
449 ExpressionT expression, | 472 ExpressionT expression, |
450 Scanner::Location location, const char* message, bool* ok); | 473 Scanner::Location location, const char* message, bool* ok); |
451 | 474 |
452 // Used to detect duplicates in object literals. Each of the values | 475 // Used to detect duplicates in object literals. Each of the values |
453 // kGetterProperty, kSetterProperty and kValueProperty represents | 476 // kGetterProperty, kSetterProperty and kValueProperty represents |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
518 | 541 |
519 private: | 542 private: |
520 Scanner* scanner_; | 543 Scanner* scanner_; |
521 uintptr_t stack_limit_; | 544 uintptr_t stack_limit_; |
522 bool stack_overflow_; | 545 bool stack_overflow_; |
523 | 546 |
524 bool allow_lazy_; | 547 bool allow_lazy_; |
525 bool allow_natives_syntax_; | 548 bool allow_natives_syntax_; |
526 bool allow_generators_; | 549 bool allow_generators_; |
527 bool allow_for_of_; | 550 bool allow_for_of_; |
551 bool allow_arrow_functions_; | |
528 | 552 |
529 typename Traits::Type::Zone* zone_; // Only used by Parser. | 553 typename Traits::Type::Zone* zone_; // Only used by Parser. |
530 }; | 554 }; |
531 | 555 |
532 | 556 |
533 class PreParserIdentifier { | 557 class PreParserIdentifier { |
534 public: | 558 public: |
535 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 559 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
536 static PreParserIdentifier Default() { | 560 static PreParserIdentifier Default() { |
537 return PreParserIdentifier(kUnknownIdentifier); | 561 return PreParserIdentifier(kUnknownIdentifier); |
538 } | 562 } |
539 static PreParserIdentifier Eval() { | 563 static PreParserIdentifier Eval() { |
540 return PreParserIdentifier(kEvalIdentifier); | 564 return PreParserIdentifier(kEvalIdentifier); |
541 } | 565 } |
542 static PreParserIdentifier Arguments() { | 566 static PreParserIdentifier Arguments() { |
543 return PreParserIdentifier(kArgumentsIdentifier); | 567 return PreParserIdentifier(kArgumentsIdentifier); |
544 } | 568 } |
545 static PreParserIdentifier FutureReserved() { | 569 static PreParserIdentifier FutureReserved() { |
546 return PreParserIdentifier(kFutureReservedIdentifier); | 570 return PreParserIdentifier(kFutureReservedIdentifier); |
547 } | 571 } |
548 static PreParserIdentifier FutureStrictReserved() { | 572 static PreParserIdentifier FutureStrictReserved() { |
549 return PreParserIdentifier(kFutureStrictReservedIdentifier); | 573 return PreParserIdentifier(kFutureStrictReservedIdentifier); |
550 } | 574 } |
551 static PreParserIdentifier Yield() { | 575 static PreParserIdentifier Yield() { |
552 return PreParserIdentifier(kYieldIdentifier); | 576 return PreParserIdentifier(kYieldIdentifier); |
553 } | 577 } |
554 bool IsEval() { return type_ == kEvalIdentifier; } | 578 bool IsEval() const { return type_ == kEvalIdentifier; } |
555 bool IsArguments() { return type_ == kArgumentsIdentifier; } | 579 bool IsArguments() const { return type_ == kArgumentsIdentifier; } |
556 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } | 580 bool IsEvalOrArguments() const { return type_ >= kEvalIdentifier; } |
557 bool IsYield() { return type_ == kYieldIdentifier; } | 581 bool IsYield() const { return type_ == kYieldIdentifier; } |
558 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } | 582 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } |
559 bool IsFutureStrictReserved() { | 583 bool IsFutureStrictReserved() const { |
560 return type_ == kFutureStrictReservedIdentifier; | 584 return type_ == kFutureStrictReservedIdentifier; |
561 } | 585 } |
562 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } | 586 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; } |
587 | |
588 // Allow identifier->name()[->length()] to work. The preparser | |
589 // does not need the actual positions/lengths of the identifiers. | |
590 const PreParserIdentifier* operator->() const { return this; } | |
591 const PreParserIdentifier raw_name() const { return *this; } | |
592 | |
593 int position() const { return 0; } | |
594 int length() const { return 0; } | |
563 | 595 |
564 private: | 596 private: |
565 enum Type { | 597 enum Type { |
566 kUnknownIdentifier, | 598 kUnknownIdentifier, |
567 kFutureReservedIdentifier, | 599 kFutureReservedIdentifier, |
568 kFutureStrictReservedIdentifier, | 600 kFutureStrictReservedIdentifier, |
569 kYieldIdentifier, | 601 kYieldIdentifier, |
570 kEvalIdentifier, | 602 kEvalIdentifier, |
571 kArgumentsIdentifier | 603 kArgumentsIdentifier |
572 }; | 604 }; |
573 explicit PreParserIdentifier(Type type) : type_(type) {} | 605 explicit PreParserIdentifier(Type type) : type_(type) {} |
574 Type type_; | 606 Type type_; |
575 | 607 |
576 friend class PreParserExpression; | 608 friend class PreParserExpression; |
609 friend class PreParserScope; | |
577 }; | 610 }; |
578 | 611 |
579 | 612 |
580 // Bits 0 and 1 are used to identify the type of expression: | 613 // Bits 0 and 1 are used to identify the type of expression: |
581 // If bit 0 is set, it's an identifier. | 614 // If bit 0 is set, it's an identifier. |
582 // if bit 1 is set, it's a string literal. | 615 // if bit 1 is set, it's a string literal. |
583 // If neither is set, it's no particular type, and both set isn't | 616 // If neither is set, it's no particular type, and both set isn't |
584 // use yet. | 617 // use yet. |
585 class PreParserExpression { | 618 class PreParserExpression { |
586 public: | 619 public: |
587 static PreParserExpression Default() { | 620 static PreParserExpression Default() { |
588 return PreParserExpression(kUnknownExpression); | 621 return PreParserExpression(kUnknownExpression); |
589 } | 622 } |
590 | 623 |
591 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 624 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
592 return PreParserExpression(kIdentifierFlag | | 625 return PreParserExpression(kTypeIdentifier | |
593 (id.type_ << kIdentifierShift)); | 626 (id.type_ << kIdentifierShift)); |
594 } | 627 } |
595 | 628 |
629 static PreParserExpression BinaryOperation(PreParserExpression left, | |
630 Token::Value op, | |
631 PreParserExpression right) { | |
632 int code = ((op == Token::COMMA) && | |
633 !left.is_parenthesized() && | |
634 !right.is_parenthesized()) | |
635 ? left.ArrowParamListBit() & right.ArrowParamListBit() : 0; | |
636 return PreParserExpression(kTypeBinaryOperation | code); | |
637 } | |
638 | |
639 static PreParserExpression EmptyArrowParamList() { | |
640 // Any expression for which IsValidArrowParamList() returns true | |
641 // will work here. | |
642 return FromIdentifier(PreParserIdentifier::Default()); | |
643 } | |
644 | |
596 static PreParserExpression StringLiteral() { | 645 static PreParserExpression StringLiteral() { |
597 return PreParserExpression(kUnknownStringLiteral); | 646 return PreParserExpression(kUnknownStringLiteral); |
598 } | 647 } |
599 | 648 |
600 static PreParserExpression UseStrictStringLiteral() { | 649 static PreParserExpression UseStrictStringLiteral() { |
601 return PreParserExpression(kUseStrictString); | 650 return PreParserExpression(kUseStrictString); |
602 } | 651 } |
603 | 652 |
604 static PreParserExpression This() { | 653 static PreParserExpression This() { |
605 return PreParserExpression(kThisExpression); | 654 return PreParserExpression(kThisExpression); |
606 } | 655 } |
607 | 656 |
608 static PreParserExpression ThisProperty() { | 657 static PreParserExpression ThisProperty() { |
609 return PreParserExpression(kThisPropertyExpression); | 658 return PreParserExpression(kThisPropertyExpression); |
610 } | 659 } |
611 | 660 |
612 static PreParserExpression Property() { | 661 static PreParserExpression Property() { |
613 return PreParserExpression(kPropertyExpression); | 662 return PreParserExpression(kPropertyExpression); |
614 } | 663 } |
615 | 664 |
616 static PreParserExpression Call() { | 665 static PreParserExpression Call() { |
617 return PreParserExpression(kCallExpression); | 666 return PreParserExpression(kCallExpression); |
618 } | 667 } |
619 | 668 |
620 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } | 669 bool IsIdentifier() const { |
670 return (code_ & kTypeMask) == kTypeIdentifier; | |
671 } | |
621 | 672 |
622 PreParserIdentifier AsIdentifier() { | 673 PreParserIdentifier AsIdentifier() const { |
623 ASSERT(IsIdentifier()); | 674 ASSERT(IsIdentifier()); |
624 return PreParserIdentifier( | 675 return PreParserIdentifier( |
625 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); | 676 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); |
626 } | 677 } |
627 | 678 |
628 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } | 679 bool IsStringLiteral() const { |
680 return (code_ & kTypeMask) == kTypeStringLiteral; | |
681 } | |
629 | 682 |
630 bool IsUseStrictLiteral() { | 683 bool IsUseStrictLiteral() { |
631 return (code_ & kStringLiteralMask) == kUseStrictString; | 684 return (code_ & kUseStrictString) == kUseStrictString; |
632 } | 685 } |
633 | 686 |
634 bool IsThis() { return code_ == kThisExpression; } | 687 bool IsThis() { return code_ == kThisExpression; } |
635 | 688 |
636 bool IsThisProperty() { return code_ == kThisPropertyExpression; } | 689 bool IsThisProperty() { return code_ == kThisPropertyExpression; } |
637 | 690 |
638 bool IsProperty() { | 691 bool IsProperty() { |
639 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; | 692 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; |
640 } | 693 } |
641 | 694 |
642 bool IsCall() { return code_ == kCallExpression; } | 695 bool IsCall() { return code_ == kCallExpression; } |
643 | 696 |
644 bool IsValidReferenceExpression() { | 697 bool IsValidReferenceExpression() { |
645 return IsIdentifier() || IsProperty(); | 698 return IsIdentifier() || IsProperty(); |
646 } | 699 } |
647 | 700 |
701 bool IsValidArrowParamList() const { | |
702 return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0 | |
703 && (code_ & kMultiParenthesizedExpression) == 0; | |
704 } | |
705 | |
648 // At the moment PreParser doesn't track these expression types. | 706 // At the moment PreParser doesn't track these expression types. |
649 bool IsFunctionLiteral() const { return false; } | 707 bool IsFunctionLiteral() const { return false; } |
650 bool IsCallNew() const { return false; } | 708 bool IsCallNew() const { return false; } |
651 | 709 |
652 PreParserExpression AsFunctionLiteral() { return *this; } | 710 PreParserExpression AsFunctionLiteral() { return *this; } |
653 | 711 |
712 bool IsBinaryOperation() const { | |
713 return (code_ & kTypeMask) == kTypeBinaryOperation; | |
714 } | |
715 | |
716 bool is_parenthesized() const { | |
717 return (code_ & kParenthesizedExpression) != 0; | |
718 } | |
719 | |
720 void increase_parenthesization_level() { | |
721 code_ |= is_parenthesized() | |
722 ? kMultiParenthesizedExpression | |
marja
2014/07/04 08:21:13
This is not very readable. Pls clang-format.
Afai
| |
723 : kParenthesizedExpression; | |
724 } | |
725 | |
654 // Dummy implementation for making expression->somefunc() work in both Parser | 726 // Dummy implementation for making expression->somefunc() work in both Parser |
655 // and PreParser. | 727 // and PreParser. |
656 PreParserExpression* operator->() { return this; } | 728 PreParserExpression* operator->() { return this; } |
657 | 729 |
658 // More dummy implementations of things PreParser doesn't need to track: | 730 // More dummy implementations of things PreParser doesn't need to track: |
659 void set_index(int index) {} // For YieldExpressions | 731 void set_index(int index) {} // For YieldExpressions |
660 void set_parenthesized() {} | 732 void set_parenthesized() {} |
661 | 733 |
734 int position() const { return RelocInfo::kNoPosition; } | |
735 void set_function_token_position(int position) {} | |
736 void set_ast_properties(int* ast_properties) {} | |
737 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {} | |
738 | |
739 bool operator==(const PreParserExpression& other) const { | |
740 return code_ == other.code_; | |
741 } | |
742 bool operator!=(const PreParserExpression& other) const { | |
743 return code_ != other.code_; | |
744 } | |
745 | |
662 private: | 746 private: |
663 // Least significant 2 bits are used as flags. Bits 0 and 1 represent | 747 // Least significant 2 bits are used as expression type. The third least |
664 // identifiers or strings literals, and are mutually exclusive, but can both | 748 // significant bit tracks whether an expression is parenthesized. If the |
665 // be absent. If the expression is an identifier or a string literal, the | 749 // expression is an identifier or a string literal, the other bits |
666 // other bits describe the type (see PreParserIdentifier::Type and string | 750 // describe the type/ (see PreParserIdentifier::Type and string literal |
667 // literal constants below). | 751 // constants below). For binary operations, the other bits are flags |
752 // which further describe the contents of the expression. | |
668 enum { | 753 enum { |
669 kUnknownExpression = 0, | 754 kUnknownExpression = 0, |
755 | |
756 kTypeMask = 1 | 2, | |
757 kParenthesizedExpression = (1 << 2), | |
758 kMultiParenthesizedExpression = (1 << 3), | |
759 | |
670 // Identifiers | 760 // Identifiers |
671 kIdentifierFlag = 1, // Used to detect labels. | 761 kTypeIdentifier = 1, // Used to detect labels. |
672 kIdentifierShift = 3, | 762 kIdentifierShift = 5, |
673 | 763 |
674 kStringLiteralFlag = 2, // Used to detect directive prologue. | 764 kTypeStringLiteral = 2, // Used to detect directive prologue. |
675 kUnknownStringLiteral = kStringLiteralFlag, | 765 kUnknownStringLiteral = kTypeStringLiteral, |
676 kUseStrictString = kStringLiteralFlag | 8, | 766 kUseStrictString = kTypeStringLiteral | 32, |
677 kStringLiteralMask = kUseStrictString, | 767 kStringLiteralMask = kUseStrictString, |
678 | 768 |
769 // Binary operations. Those are needed to detect certain keywords and | |
770 // duplicated identifier in parameter lists for arrow functions, because | |
771 // they are initially parsed as comma-separated expressions. | |
772 kTypeBinaryOperation = 3, | |
773 kBinaryOperationArrowParamList = (1 << 4), | |
774 | |
679 // Below here applies if neither identifier nor string literal. Reserve the | 775 // Below here applies if neither identifier nor string literal. Reserve the |
680 // 2 least significant bits for flags. | 776 // 2 least significant bits for flags. |
681 kThisExpression = 1 << 2, | 777 kThisExpression = (1 << 4), |
682 kThisPropertyExpression = 2 << 2, | 778 kThisPropertyExpression = (2 << 4), |
683 kPropertyExpression = 3 << 2, | 779 kPropertyExpression = (3 << 4), |
684 kCallExpression = 4 << 2 | 780 kCallExpression = (4 << 4) |
685 }; | 781 }; |
686 | 782 |
687 explicit PreParserExpression(int expression_code) : code_(expression_code) {} | 783 explicit PreParserExpression(int expression_code) : code_(expression_code) {} |
688 | 784 |
785 V8_INLINE int ArrowParamListBit() const { | |
786 if (IsBinaryOperation()) | |
787 return code_ & kBinaryOperationArrowParamList; | |
788 if (IsIdentifier()) { | |
789 const PreParserIdentifier ident = AsIdentifier(); | |
790 // A valid identifier can be an arrow function parameter list | |
791 // except for eval, arguments, yield, and reserved keywords. | |
792 if (ident.IsEval() || ident.IsArguments() || ident.IsYield() | |
793 || ident.IsFutureStrictReserved()) | |
794 return 0; | |
795 return kBinaryOperationArrowParamList; | |
796 } | |
797 return 0; | |
798 } | |
799 | |
689 int code_; | 800 int code_; |
690 }; | 801 }; |
691 | 802 |
692 | 803 |
693 // PreParserExpressionList doesn't actually store the expressions because | 804 // PreParserExpressionList doesn't actually store the expressions because |
694 // PreParser doesn't need to. | 805 // PreParser doesn't need to. |
695 class PreParserExpressionList { | 806 class PreParserExpressionList { |
696 public: | 807 public: |
697 // These functions make list->Add(some_expression) work (and do nothing). | 808 // These functions make list->Add(some_expression) work (and do nothing). |
698 PreParserExpressionList() : length_(0) {} | 809 PreParserExpressionList() : length_(0) {} |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
760 public: | 871 public: |
761 // These functions make list->Add(some_expression) work as no-ops. | 872 // These functions make list->Add(some_expression) work as no-ops. |
762 PreParserStatementList() {} | 873 PreParserStatementList() {} |
763 PreParserStatementList* operator->() { return this; } | 874 PreParserStatementList* operator->() { return this; } |
764 void Add(PreParserStatement, void*) {} | 875 void Add(PreParserStatement, void*) {} |
765 }; | 876 }; |
766 | 877 |
767 | 878 |
768 class PreParserScope { | 879 class PreParserScope { |
769 public: | 880 public: |
770 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) | 881 explicit PreParserScope(PreParserScope* outer_scope, |
882 ScopeType scope_type, | |
883 void* = NULL) | |
771 : scope_type_(scope_type) { | 884 : scope_type_(scope_type) { |
772 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; | 885 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; |
773 } | 886 } |
774 | 887 |
775 ScopeType type() { return scope_type_; } | 888 ScopeType type() { return scope_type_; } |
776 StrictMode strict_mode() const { return strict_mode_; } | 889 StrictMode strict_mode() const { return strict_mode_; } |
777 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } | 890 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } |
778 | 891 |
892 // When PreParser is in use, lazy compilation is already being done, | |
893 // things cannot get lazier than that. | |
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 { return false; } | |
900 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) { } | |
901 | |
902 // Allow scope->Foo() to work. | |
903 PreParserScope* operator->() { return this; } | |
904 | |
779 private: | 905 private: |
780 ScopeType scope_type_; | 906 ScopeType scope_type_; |
781 StrictMode strict_mode_; | 907 StrictMode strict_mode_; |
782 }; | 908 }; |
783 | 909 |
784 | 910 |
785 class PreParserFactory { | 911 class PreParserFactory { |
786 public: | 912 public: |
787 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} | 913 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} |
788 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, | 914 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
832 return PreParserExpression::Property(); | 958 return PreParserExpression::Property(); |
833 } | 959 } |
834 PreParserExpression NewUnaryOperation(Token::Value op, | 960 PreParserExpression NewUnaryOperation(Token::Value op, |
835 PreParserExpression expression, | 961 PreParserExpression expression, |
836 int pos) { | 962 int pos) { |
837 return PreParserExpression::Default(); | 963 return PreParserExpression::Default(); |
838 } | 964 } |
839 PreParserExpression NewBinaryOperation(Token::Value op, | 965 PreParserExpression NewBinaryOperation(Token::Value op, |
840 PreParserExpression left, | 966 PreParserExpression left, |
841 PreParserExpression right, int pos) { | 967 PreParserExpression right, int pos) { |
842 return PreParserExpression::Default(); | 968 return PreParserExpression::BinaryOperation(left, op, right); |
843 } | 969 } |
844 PreParserExpression NewCompareOperation(Token::Value op, | 970 PreParserExpression NewCompareOperation(Token::Value op, |
845 PreParserExpression left, | 971 PreParserExpression left, |
846 PreParserExpression right, int pos) { | 972 PreParserExpression right, int pos) { |
847 return PreParserExpression::Default(); | 973 return PreParserExpression::Default(); |
848 } | 974 } |
849 PreParserExpression NewAssignment(Token::Value op, | 975 PreParserExpression NewAssignment(Token::Value op, |
850 PreParserExpression left, | 976 PreParserExpression left, |
851 PreParserExpression right, | 977 PreParserExpression right, |
852 int pos) { | 978 int pos) { |
(...skipping 20 matching lines...) Expand all Loading... | |
873 PreParserExpression NewCall(PreParserExpression expression, | 999 PreParserExpression NewCall(PreParserExpression expression, |
874 PreParserExpressionList arguments, | 1000 PreParserExpressionList arguments, |
875 int pos) { | 1001 int pos) { |
876 return PreParserExpression::Call(); | 1002 return PreParserExpression::Call(); |
877 } | 1003 } |
878 PreParserExpression NewCallNew(PreParserExpression expression, | 1004 PreParserExpression NewCallNew(PreParserExpression expression, |
879 PreParserExpressionList arguments, | 1005 PreParserExpressionList arguments, |
880 int pos) { | 1006 int pos) { |
881 return PreParserExpression::Default(); | 1007 return PreParserExpression::Default(); |
882 } | 1008 } |
1009 PreParserStatement NewReturnStatement(PreParserExpression expression, | |
1010 int pos) { | |
1011 return PreParserStatement::Default(); | |
1012 } | |
1013 PreParserExpression | |
1014 NewFunctionLiteral(PreParserIdentifier name, | |
1015 AstValueFactory* ast_value_factory, | |
1016 PreParserScope& scope, | |
1017 PreParserStatementList body, | |
1018 int materialized_literal_count, | |
1019 int expected_property_count, | |
1020 int handler_count, | |
1021 int parameter_count, | |
1022 FunctionLiteral::ParameterFlag has_duplicate_parameters, | |
1023 FunctionLiteral::FunctionType function_type, | |
1024 FunctionLiteral::IsFunctionFlag is_function, | |
1025 FunctionLiteral::IsParenthesizedFlag is_parenthesized, | |
1026 FunctionLiteral::IsGeneratorFlag is_generator, | |
1027 int position) { | |
1028 return PreParserExpression::Default(); | |
1029 } | |
1030 | |
1031 // Return the object itself as AstVisitor and implement the needed | |
1032 // dummy method right in this class. | |
1033 PreParserFactory* visitor() { return this; } | |
1034 BailoutReason dont_optimize_reason() { return kNoReason; } | |
1035 int* ast_properties() { static int dummy = 42; return &dummy; } | |
883 }; | 1036 }; |
884 | 1037 |
885 | 1038 |
886 class PreParser; | 1039 class PreParser; |
887 | 1040 |
888 class PreParserTraits { | 1041 class PreParserTraits { |
889 public: | 1042 public: |
890 struct Type { | 1043 struct Type { |
891 // TODO(marja): To be removed. The Traits object should contain all the data | 1044 // TODO(marja): To be removed. The Traits object should contain all the data |
892 // it needs. | 1045 // it needs. |
893 typedef PreParser* Parser; | 1046 typedef PreParser* Parser; |
894 | 1047 |
895 // Used by FunctionState and BlockState. | 1048 // Used by FunctionState and BlockState. |
896 typedef PreParserScope Scope; | 1049 typedef PreParserScope Scope; |
1050 typedef PreParserScope ScopePtr; | |
1051 | |
897 // PreParser doesn't need to store generator variables. | 1052 // PreParser doesn't need to store generator variables. |
898 typedef void GeneratorVariable; | 1053 typedef void GeneratorVariable; |
899 // No interaction with Zones. | 1054 // No interaction with Zones. |
900 typedef void Zone; | 1055 typedef void Zone; |
901 | 1056 |
1057 typedef int AstProperties; | |
1058 typedef Vector<PreParserIdentifier> ParameterIdentifierVector; | |
1059 | |
902 // Return types for traversing functions. | 1060 // Return types for traversing functions. |
903 typedef PreParserIdentifier Identifier; | 1061 typedef PreParserIdentifier Identifier; |
904 typedef PreParserExpression Expression; | 1062 typedef PreParserExpression Expression; |
905 typedef PreParserExpression YieldExpression; | 1063 typedef PreParserExpression YieldExpression; |
906 typedef PreParserExpression FunctionLiteral; | 1064 typedef PreParserExpression FunctionLiteral; |
907 typedef PreParserExpression ObjectLiteralProperty; | 1065 typedef PreParserExpression ObjectLiteralProperty; |
908 typedef PreParserExpression Literal; | 1066 typedef PreParserExpression Literal; |
909 typedef PreParserExpressionList ExpressionList; | 1067 typedef PreParserExpressionList ExpressionList; |
910 typedef PreParserExpressionList PropertyList; | 1068 typedef PreParserExpressionList PropertyList; |
911 typedef PreParserStatementList StatementList; | 1069 typedef PreParserStatementList StatementList; |
(...skipping 22 matching lines...) Expand all Loading... | |
934 } | 1092 } |
935 | 1093 |
936 static bool IsIdentifier(PreParserExpression expression) { | 1094 static bool IsIdentifier(PreParserExpression expression) { |
937 return expression.IsIdentifier(); | 1095 return expression.IsIdentifier(); |
938 } | 1096 } |
939 | 1097 |
940 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { | 1098 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { |
941 return expression.AsIdentifier(); | 1099 return expression.AsIdentifier(); |
942 } | 1100 } |
943 | 1101 |
1102 static bool IsFutureStrictReserved(PreParserIdentifier identifier) { | |
1103 return identifier.IsYield() || identifier.IsFutureStrictReserved(); | |
1104 } | |
1105 | |
944 static bool IsBoilerplateProperty(PreParserExpression property) { | 1106 static bool IsBoilerplateProperty(PreParserExpression property) { |
945 // PreParser doesn't count boilerplate properties. | 1107 // PreParser doesn't count boilerplate properties. |
946 return false; | 1108 return false; |
947 } | 1109 } |
948 | 1110 |
949 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { | 1111 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { |
950 return false; | 1112 return false; |
951 } | 1113 } |
952 | 1114 |
953 // Functions for encapsulating the differences between parsing and preparsing; | 1115 // Functions for encapsulating the differences between parsing and preparsing; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
997 return PreParserExpression::Default(); | 1159 return PreParserExpression::Default(); |
998 } | 1160 } |
999 PreParserExpression NewThrowSyntaxError( | 1161 PreParserExpression NewThrowSyntaxError( |
1000 const char* type, Handle<Object> arg, int pos) { | 1162 const char* type, Handle<Object> arg, int pos) { |
1001 return PreParserExpression::Default(); | 1163 return PreParserExpression::Default(); |
1002 } | 1164 } |
1003 PreParserExpression NewThrowTypeError( | 1165 PreParserExpression NewThrowTypeError( |
1004 const char* type, Handle<Object> arg, int pos) { | 1166 const char* type, Handle<Object> arg, int pos) { |
1005 return PreParserExpression::Default(); | 1167 return PreParserExpression::Default(); |
1006 } | 1168 } |
1169 PreParserScope NewScope(PreParserScope* outer_scope, | |
1170 ScopeType scope_type) { | |
1171 return PreParserScope(outer_scope, scope_type); | |
1172 } | |
1007 | 1173 |
1008 // Reporting errors. | 1174 // Reporting errors. |
1009 void ReportMessageAt(Scanner::Location location, | 1175 void ReportMessageAt(Scanner::Location location, |
1010 const char* message, | 1176 const char* message, |
1011 const char* arg = NULL, | 1177 const char* arg = NULL, |
1012 bool is_reference_error = false); | 1178 bool is_reference_error = false); |
1013 void ReportMessageAt(int start_pos, | 1179 void ReportMessageAt(int start_pos, |
1014 int end_pos, | 1180 int end_pos, |
1015 const char* message, | 1181 const char* message, |
1016 const char* arg = NULL, | 1182 const char* arg = NULL, |
1017 bool is_reference_error = false); | 1183 bool is_reference_error = false); |
1018 | 1184 |
1019 // "null" return type creators. | 1185 // "null" return type creators. |
1020 static PreParserIdentifier EmptyIdentifier() { | 1186 static PreParserIdentifier EmptyIdentifier() { |
1021 return PreParserIdentifier::Default(); | 1187 return PreParserIdentifier::Default(); |
1022 } | 1188 } |
1189 static PreParserIdentifier EmptyIdentifierString() { | |
1190 return PreParserIdentifier::Default(); | |
1191 } | |
1023 static PreParserExpression EmptyExpression() { | 1192 static PreParserExpression EmptyExpression() { |
1024 return PreParserExpression::Default(); | 1193 return PreParserExpression::Default(); |
1025 } | 1194 } |
1195 static PreParserExpression EmptyArrowParamList() { | |
1196 return PreParserExpression::EmptyArrowParamList(); | |
1197 } | |
1026 static PreParserExpression EmptyLiteral() { | 1198 static PreParserExpression EmptyLiteral() { |
1027 return PreParserExpression::Default(); | 1199 return PreParserExpression::Default(); |
1028 } | 1200 } |
1029 static PreParserExpressionList NullExpressionList() { | 1201 static PreParserExpressionList NullExpressionList() { |
1030 return PreParserExpressionList(); | 1202 return PreParserExpressionList(); |
1031 } | 1203 } |
1032 | 1204 |
1033 // Odd-ball literal creators. | 1205 // Odd-ball literal creators. |
1034 static PreParserExpression GetLiteralTheHole(int position, | 1206 static PreParserExpression GetLiteralTheHole(int position, |
1035 PreParserFactory* factory) { | 1207 PreParserFactory* factory) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1069 } | 1241 } |
1070 | 1242 |
1071 static PreParserStatementList NewStatementList(int size, void* zone) { | 1243 static PreParserStatementList NewStatementList(int size, void* zone) { |
1072 return PreParserStatementList(); | 1244 return PreParserStatementList(); |
1073 } | 1245 } |
1074 | 1246 |
1075 static PreParserExpressionList NewPropertyList(int size, void* zone) { | 1247 static PreParserExpressionList NewPropertyList(int size, void* zone) { |
1076 return PreParserExpressionList(); | 1248 return PreParserExpressionList(); |
1077 } | 1249 } |
1078 | 1250 |
1251 V8_INLINE void SkipLazyFunctionBody( | |
1252 PreParserIdentifier function_name, | |
1253 int* materialized_literal_count, | |
1254 int* expected_property_count, | |
1255 bool* ok) { | |
1256 UNREACHABLE(); | |
1257 } | |
1258 | |
1259 V8_INLINE PreParserStatementList ParseEagerFunctionBody( | |
1260 PreParserIdentifier function_name, | |
1261 int pos, | |
1262 Variable* fvar, | |
1263 Token::Value fvar_init_op, | |
1264 bool is_generator, | |
1265 bool* ok); | |
1266 | |
1267 // Utility functions | |
1268 Vector<PreParserIdentifier> ParameterListFromExpression( | |
1269 PreParserExpression expression, bool* ok) { | |
1270 // TODO(aperez): Detect duplicated identifiers in paramlists. | |
1271 *ok = expression.IsValidArrowParamList(); | |
1272 return Vector<PreParserIdentifier>::empty(); | |
1273 } | |
1274 | |
1275 static AstValueFactory* ast_value_factory() { return NULL; } | |
1276 | |
1277 void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {} | |
1278 | |
1079 // Temporary glue; these functions will move to ParserBase. | 1279 // Temporary glue; these functions will move to ParserBase. |
1080 PreParserExpression ParseV8Intrinsic(bool* ok); | 1280 PreParserExpression ParseV8Intrinsic(bool* ok); |
1081 PreParserExpression ParseFunctionLiteral( | 1281 PreParserExpression ParseFunctionLiteral( |
1082 PreParserIdentifier name, | 1282 PreParserIdentifier name, |
1083 Scanner::Location function_name_location, | 1283 Scanner::Location function_name_location, |
1084 bool name_is_strict_reserved, | 1284 bool name_is_strict_reserved, |
1085 bool is_generator, | 1285 bool is_generator, |
1086 int function_token_position, | 1286 int function_token_position, |
1087 FunctionLiteral::FunctionType type, | 1287 FunctionLiteral::FunctionType type, |
1088 FunctionLiteral::ArityRestriction arity_restriction, | 1288 FunctionLiteral::ArityRestriction arity_restriction, |
(...skipping 30 matching lines...) Expand all Loading... | |
1119 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) | 1319 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) |
1120 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, | 1320 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, |
1121 this) {} | 1321 this) {} |
1122 | 1322 |
1123 // Pre-parse the program from the character stream; returns true on | 1323 // Pre-parse the program from the character stream; returns true on |
1124 // success (even if parsing failed, the pre-parse data successfully | 1324 // success (even if parsing failed, the pre-parse data successfully |
1125 // captured the syntax error), and false if a stack-overflow happened | 1325 // captured the syntax error), and false if a stack-overflow happened |
1126 // during parsing. | 1326 // during parsing. |
1127 PreParseResult PreParseProgram() { | 1327 PreParseResult PreParseProgram() { |
1128 PreParserScope scope(scope_, GLOBAL_SCOPE); | 1328 PreParserScope scope(scope_, GLOBAL_SCOPE); |
1129 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); | 1329 FunctionState top_scope(&function_state_, &scope_, &scope); |
1130 bool ok = true; | 1330 bool ok = true; |
1131 int start_position = scanner()->peek_location().beg_pos; | 1331 int start_position = scanner()->peek_location().beg_pos; |
1132 ParseSourceElements(Token::EOS, &ok); | 1332 ParseSourceElements(Token::EOS, &ok); |
1133 if (stack_overflow()) return kPreParseStackOverflow; | 1333 if (stack_overflow()) return kPreParseStackOverflow; |
1134 if (!ok) { | 1334 if (!ok) { |
1135 ReportUnexpectedToken(scanner()->current_token()); | 1335 ReportUnexpectedToken(scanner()->current_token()); |
1136 } else if (scope_->strict_mode() == STRICT) { | 1336 } else if (scope_->strict_mode() == STRICT) { |
1137 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); | 1337 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); |
1138 } | 1338 } |
1139 return kPreParseSuccess; | 1339 return kPreParseSuccess; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1201 Statement ParseDoWhileStatement(bool* ok); | 1401 Statement ParseDoWhileStatement(bool* ok); |
1202 Statement ParseWhileStatement(bool* ok); | 1402 Statement ParseWhileStatement(bool* ok); |
1203 Statement ParseForStatement(bool* ok); | 1403 Statement ParseForStatement(bool* ok); |
1204 Statement ParseThrowStatement(bool* ok); | 1404 Statement ParseThrowStatement(bool* ok); |
1205 Statement ParseTryStatement(bool* ok); | 1405 Statement ParseTryStatement(bool* ok); |
1206 Statement ParseDebuggerStatement(bool* ok); | 1406 Statement ParseDebuggerStatement(bool* ok); |
1207 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 1407 Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
1208 Expression ParseObjectLiteral(bool* ok); | 1408 Expression ParseObjectLiteral(bool* ok); |
1209 Expression ParseV8Intrinsic(bool* ok); | 1409 Expression ParseV8Intrinsic(bool* ok); |
1210 | 1410 |
1411 V8_INLINE void SkipLazyFunctionBody( | |
1412 PreParserIdentifier function_name, | |
1413 int* materialized_literal_count, | |
1414 int* expected_property_count, | |
1415 bool* ok); | |
1416 V8_INLINE PreParserStatementList ParseEagerFunctionBody( | |
1417 PreParserIdentifier function_name, | |
1418 int pos, | |
1419 Variable* fvar, | |
1420 Token::Value fvar_init_op, | |
1421 bool is_generator, | |
1422 bool* ok); | |
1423 | |
1211 Expression ParseFunctionLiteral( | 1424 Expression ParseFunctionLiteral( |
1212 Identifier name, | 1425 Identifier name, |
1213 Scanner::Location function_name_location, | 1426 Scanner::Location function_name_location, |
1214 bool name_is_strict_reserved, | 1427 bool name_is_strict_reserved, |
1215 bool is_generator, | 1428 bool is_generator, |
1216 int function_token_pos, | 1429 int function_token_pos, |
1217 FunctionLiteral::FunctionType function_type, | 1430 FunctionLiteral::FunctionType function_type, |
1218 FunctionLiteral::ArityRestriction arity_restriction, | 1431 FunctionLiteral::ArityRestriction arity_restriction, |
1219 bool* ok); | 1432 bool* ok); |
1220 void ParseLazyFunctionLiteralBody(bool* ok); | 1433 void ParseLazyFunctionLiteralBody(bool* ok); |
1221 | 1434 |
1222 bool CheckInOrOf(bool accept_OF); | 1435 bool CheckInOrOf(bool accept_OF); |
1223 }; | 1436 }; |
1224 | 1437 |
1438 | |
1439 PreParserStatementList PreParser::ParseEagerFunctionBody( | |
1440 PreParserIdentifier function_name, | |
1441 int pos, | |
1442 Variable* fvar, | |
1443 Token::Value fvar_init_op, | |
1444 bool is_generator, | |
1445 bool* ok) { | |
1446 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | |
1447 | |
1448 ParseSourceElements(Token::RBRACE, ok); | |
1449 if (!*ok) return PreParserStatementList(); | |
1450 | |
1451 Expect(Token::RBRACE, ok); | |
1452 return PreParserStatementList(); | |
1453 } | |
1454 | |
1455 | |
1456 PreParserStatementList PreParserTraits::ParseEagerFunctionBody( | |
1457 PreParserIdentifier function_name, | |
1458 int pos, | |
1459 Variable* fvar, | |
1460 Token::Value fvar_init_op, | |
1461 bool is_generator, | |
1462 bool* ok) { | |
1463 return pre_parser_->ParseEagerFunctionBody(function_name, | |
1464 pos, fvar, fvar_init_op, is_generator, ok); | |
1465 } | |
1466 | |
1467 | |
1225 template<class Traits> | 1468 template<class Traits> |
1226 ParserBase<Traits>::FunctionState::FunctionState( | 1469 ParserBase<Traits>::FunctionState::FunctionState( |
1227 FunctionState** function_state_stack, | 1470 FunctionState** function_state_stack, |
1228 typename Traits::Type::Scope** scope_stack, | 1471 typename Traits::Type::Scope** scope_stack, |
1229 typename Traits::Type::Scope* scope, | 1472 typename Traits::Type::Scope* scope, |
1230 typename Traits::Type::Zone* extra_param, | 1473 typename Traits::Type::Zone* extra_param, |
1231 AstValueFactory* ast_value_factory) | 1474 AstValueFactory* ast_value_factory) |
1232 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | 1475 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
1233 next_handler_index_(0), | 1476 next_handler_index_(0), |
1234 expected_property_count_(0), | 1477 expected_property_count_(0), |
1235 is_generator_(false), | 1478 is_generator_(false), |
1236 generator_object_variable_(NULL), | 1479 generator_object_variable_(NULL), |
1237 function_state_stack_(function_state_stack), | 1480 function_state_stack_(function_state_stack), |
1238 outer_function_state_(*function_state_stack), | 1481 outer_function_state_(*function_state_stack), |
1239 scope_stack_(scope_stack), | 1482 scope_stack_(scope_stack), |
1240 outer_scope_(*scope_stack), | 1483 outer_scope_(*scope_stack), |
1241 saved_ast_node_id_(0), | 1484 saved_ast_node_id_(0), |
1242 extra_param_(extra_param), | 1485 extra_param_(extra_param), |
1243 factory_(extra_param, ast_value_factory) { | 1486 factory_(extra_param, ast_value_factory) { |
1244 *scope_stack_ = scope; | 1487 *scope_stack_ = scope; |
1245 *function_state_stack = this; | 1488 *function_state_stack = this; |
1246 Traits::SetUpFunctionState(this, extra_param); | 1489 Traits::SetUpFunctionState(this, extra_param); |
1247 } | 1490 } |
1248 | 1491 |
1249 | 1492 |
1250 template<class Traits> | 1493 template<class Traits> |
1494 ParserBase<Traits>::FunctionState::FunctionState( | |
1495 FunctionState** function_state_stack, | |
1496 typename Traits::Type::Scope** scope_stack, | |
1497 typename Traits::Type::Scope** scope, | |
1498 typename Traits::Type::Zone* extra_param, | |
1499 AstValueFactory* ast_value_factory) | |
1500 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | |
1501 next_handler_index_(0), | |
1502 expected_property_count_(0), | |
1503 is_generator_(false), | |
1504 generator_object_variable_(NULL), | |
1505 function_state_stack_(function_state_stack), | |
1506 outer_function_state_(*function_state_stack), | |
1507 scope_stack_(scope_stack), | |
1508 outer_scope_(*scope_stack), | |
1509 saved_ast_node_id_(0), | |
1510 extra_param_(extra_param), | |
1511 factory_(extra_param, ast_value_factory) { | |
1512 *scope_stack_ = *scope; | |
1513 *function_state_stack = this; | |
1514 Traits::SetUpFunctionState(this, extra_param); | |
1515 } | |
1516 | |
1517 | |
1518 template<class Traits> | |
1251 ParserBase<Traits>::FunctionState::~FunctionState() { | 1519 ParserBase<Traits>::FunctionState::~FunctionState() { |
1252 *scope_stack_ = outer_scope_; | 1520 *scope_stack_ = outer_scope_; |
1253 *function_state_stack_ = outer_function_state_; | 1521 *function_state_stack_ = outer_function_state_; |
1254 Traits::TearDownFunctionState(this, extra_param_); | 1522 Traits::TearDownFunctionState(this, extra_param_); |
1255 } | 1523 } |
1256 | 1524 |
1257 | 1525 |
1258 template<class Traits> | 1526 template<class Traits> |
1259 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { | 1527 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { |
1260 Scanner::Location source_location = scanner()->location(); | 1528 Scanner::Location source_location = scanner()->location(); |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1452 case Token::LBRACK: | 1720 case Token::LBRACK: |
1453 result = this->ParseArrayLiteral(CHECK_OK); | 1721 result = this->ParseArrayLiteral(CHECK_OK); |
1454 break; | 1722 break; |
1455 | 1723 |
1456 case Token::LBRACE: | 1724 case Token::LBRACE: |
1457 result = this->ParseObjectLiteral(CHECK_OK); | 1725 result = this->ParseObjectLiteral(CHECK_OK); |
1458 break; | 1726 break; |
1459 | 1727 |
1460 case Token::LPAREN: | 1728 case Token::LPAREN: |
1461 Consume(Token::LPAREN); | 1729 Consume(Token::LPAREN); |
1462 // Heuristically try to detect immediately called functions before | 1730 if (allow_arrow_functions() && peek() == Token::RPAREN) { |
1463 // seeing the call parentheses. | 1731 // Arrow functions are the only expression type constructions |
1464 parenthesized_function_ = (peek() == Token::FUNCTION); | 1732 // for which an empty parameter list "()" is valid input. |
1465 result = this->ParseExpression(true, CHECK_OK); | 1733 Consume(Token::RPAREN); |
1466 Expect(Token::RPAREN, CHECK_OK); | 1734 return this->ParseArrowFunctionLiteral(pos, |
1735 this->EmptyArrowParamList(), | |
1736 CHECK_OK); | |
1737 } else { | |
1738 // Heuristically try to detect immediately called functions before | |
1739 // seeing the call parentheses. | |
1740 parenthesized_function_ = (peek() == Token::FUNCTION); | |
1741 result = this->ParseExpression(true, CHECK_OK); | |
1742 result->increase_parenthesization_level(); | |
1743 Expect(Token::RPAREN, CHECK_OK); | |
1744 } | |
1467 break; | 1745 break; |
1468 | 1746 |
1469 case Token::MOD: | 1747 case Token::MOD: |
1470 if (allow_natives_syntax() || extension_ != NULL) { | 1748 if (allow_natives_syntax() || extension_ != NULL) { |
1471 result = this->ParseV8Intrinsic(CHECK_OK); | 1749 result = this->ParseV8Intrinsic(CHECK_OK); |
1472 break; | 1750 break; |
1473 } | 1751 } |
1474 // If we're not allowing special syntax we fall-through to the | 1752 // If we're not allowing special syntax we fall-through to the |
1475 // default case. | 1753 // default case. |
1476 | 1754 |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1724 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2002 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
1725 return result; | 2003 return result; |
1726 } | 2004 } |
1727 | 2005 |
1728 // Precedence = 2 | 2006 // Precedence = 2 |
1729 template <class Traits> | 2007 template <class Traits> |
1730 typename ParserBase<Traits>::ExpressionT | 2008 typename ParserBase<Traits>::ExpressionT |
1731 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2009 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
1732 // AssignmentExpression :: | 2010 // AssignmentExpression :: |
1733 // ConditionalExpression | 2011 // ConditionalExpression |
2012 // ArrowFunction | |
1734 // YieldExpression | 2013 // YieldExpression |
1735 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2014 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
1736 | 2015 |
1737 Scanner::Location lhs_location = scanner()->peek_location(); | 2016 Scanner::Location lhs_location = scanner()->peek_location(); |
1738 | 2017 |
1739 if (peek() == Token::YIELD && is_generator()) { | 2018 if (peek() == Token::YIELD && is_generator()) { |
1740 return this->ParseYieldExpression(ok); | 2019 return this->ParseYieldExpression(ok); |
1741 } | 2020 } |
1742 | 2021 |
1743 if (fni_ != NULL) fni_->Enter(); | 2022 if (fni_ != NULL) fni_->Enter(); |
1744 ExpressionT expression = | 2023 ExpressionT expression = |
1745 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 2024 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
1746 | 2025 |
2026 if (allow_arrow_functions() && peek() == Token::ARROW) | |
2027 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos, | |
2028 expression, | |
2029 CHECK_OK); | |
2030 | |
1747 if (!Token::IsAssignmentOp(peek())) { | 2031 if (!Token::IsAssignmentOp(peek())) { |
1748 if (fni_ != NULL) fni_->Leave(); | 2032 if (fni_ != NULL) fni_->Leave(); |
1749 // Parsed conditional expression only (no assignment). | 2033 // Parsed conditional expression only (no assignment). |
1750 return expression; | 2034 return expression; |
1751 } | 2035 } |
1752 | 2036 |
1753 expression = this->CheckAndRewriteReferenceExpression( | 2037 expression = this->CheckAndRewriteReferenceExpression( |
1754 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 2038 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); |
1755 expression = this->MarkExpressionAsAssigned(expression); | 2039 expression = this->MarkExpressionAsAssigned(expression); |
1756 | 2040 |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2163 } | 2447 } |
2164 default: | 2448 default: |
2165 return expression; | 2449 return expression; |
2166 } | 2450 } |
2167 } | 2451 } |
2168 ASSERT(false); | 2452 ASSERT(false); |
2169 return this->EmptyExpression(); | 2453 return this->EmptyExpression(); |
2170 } | 2454 } |
2171 | 2455 |
2172 | 2456 |
2457 template <class Traits> | |
2458 typename ParserBase<Traits>::ExpressionT | |
2459 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, | |
2460 ExpressionT params_ast, | |
2461 bool* ok) { | |
2462 typename Traits::Type::ParameterIdentifierVector params = | |
2463 Traits::ParameterListFromExpression(params_ast, ok); | |
2464 | |
2465 if (!*ok) { | |
2466 ReportMessageAt( | |
2467 Scanner::Location(start_pos, scanner()->location().beg_pos), | |
2468 "malformed_arrow_function_parameter_list"); | |
2469 return this->EmptyExpression(); | |
2470 } | |
2471 | |
2472 // TODO(aperez): Change this to use ARROW_SCOPE | |
2473 typename Traits::Type::ScopePtr scope = | |
2474 this->NewScope(scope_, FUNCTION_SCOPE); | |
2475 | |
2476 FunctionState function_state(&function_state_, &scope_, &scope, | |
2477 zone(), this->ast_value_factory()); | |
2478 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | |
2479 | |
2480 if (params.length() > Code::kMaxArguments) { | |
2481 ReportMessageAt(Scanner::Location(params_ast->position(), position()), | |
2482 "too_many_parameters"); | |
2483 *ok = false; | |
2484 return this->EmptyExpression(); | |
2485 } | |
2486 | |
2487 // The vector has the items in reverse order. | |
marja
2014/07/04 08:21:13
Is it necessary to have the items in reverse order
| |
2488 for (int i = params.length() - 1; i >= 0; --i) { | |
2489 const IdentifierT param_name = params.at(i)->raw_name(); | |
2490 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | |
2491 int param_pos = params.at(i)->position(); | |
2492 dupe_error_loc = Scanner::Location(param_pos, | |
2493 param_pos + param_name->length()); | |
2494 } | |
2495 scope_->DeclareParameter(param_name, VAR); | |
2496 } | |
2497 | |
2498 return ParseArrowFunctionLiteralBody(&function_state, | |
2499 scope, | |
2500 params.length(), | |
2501 Scanner::Location::invalid(), | |
2502 dupe_error_loc, | |
2503 Scanner::Location::invalid(), | |
2504 FunctionLiteral::kNotParenthesized, | |
2505 start_pos, | |
2506 CHECK_OK); | |
marja
2014/07/04 08:21:13
I don't think it makes sense to put CHECK_OK insid
| |
2507 } | |
2508 | |
2509 | |
2510 template <class Traits> | |
2511 typename ParserBase<Traits>::ExpressionT | |
2512 ParserBase<Traits>::ParseArrowFunctionLiteralBody( | |
2513 FunctionState* function_state, | |
2514 typename Traits::Type::ScopePtr scope, | |
2515 int num_parameters, | |
2516 const Scanner::Location& eval_args_error_loc, | |
2517 const Scanner::Location& dupe_error_loc, | |
2518 const Scanner::Location& reserved_loc, | |
2519 FunctionLiteral::IsParenthesizedFlag parenthesized, | |
2520 int start_pos, | |
2521 bool* ok) { | |
2522 | |
2523 typename Traits::Type::StatementList body; | |
2524 int materialized_literal_count = -1; | |
2525 int expected_property_count = -1; | |
2526 | |
2527 Expect(Token::ARROW, CHECK_OK); | |
2528 | |
2529 if (peek() == Token::LBRACE) { | |
2530 // Multiple statemente body | |
2531 Consume(Token::LBRACE); | |
2532 bool is_lazily_parsed = (mode() == PARSE_LAZILY && | |
2533 scope_->AllowsLazyCompilation()); | |
2534 if (is_lazily_parsed) { | |
2535 this->SkipLazyFunctionBody(this->EmptyIdentifier(), | |
2536 &materialized_literal_count, | |
2537 &expected_property_count, | |
2538 CHECK_OK); | |
2539 } else { | |
2540 body = this->ParseEagerFunctionBody(this->EmptyIdentifier(), | |
2541 RelocInfo::kNoPosition, | |
2542 NULL, | |
2543 Token::INIT_VAR, | |
2544 false, // Not a generator. | |
2545 CHECK_OK); | |
2546 } | |
2547 } else { | |
2548 // Single-expression body | |
2549 ParseAssignmentExpression(true, CHECK_OK); | |
2550 } | |
2551 | |
2552 scope->set_start_position(start_pos); | |
2553 scope->set_end_position(scanner()->location().end_pos); | |
2554 | |
2555 // Arrow function *parameter lists* are always checked as in strict mode. | |
2556 this->CheckStrictFunctionNameAndParameters(this->EmptyIdentifier(), | |
2557 false, | |
2558 Scanner::Location::invalid(), | |
2559 Scanner::Location::invalid(), | |
2560 dupe_error_loc, | |
2561 Scanner::Location::invalid(), | |
2562 CHECK_OK); | |
2563 | |
2564 // Validate strict mode. | |
2565 if (strict_mode() == STRICT) { | |
2566 CheckOctalLiteral(start_pos, | |
2567 scanner()->location().end_pos, | |
2568 CHECK_OK); | |
2569 } | |
2570 | |
2571 if (allow_harmony_scoping() && strict_mode() == STRICT) | |
2572 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | |
2573 | |
2574 // TODO(aperez): Generate a proper FunctionLiteral instead of | |
2575 // returning a dummy value. | |
2576 FunctionLiteralT function_literal = | |
2577 factory()->NewFunctionLiteral(this->EmptyIdentifierString(), | |
2578 this->ast_value_factory(), | |
2579 scope, | |
2580 this->NewStatementList(0, zone()), | |
2581 0, | |
2582 0, | |
2583 0, | |
2584 num_parameters, | |
2585 FunctionLiteral::kNoDuplicateParameters, | |
2586 FunctionLiteral::ANONYMOUS_EXPRESSION, | |
2587 FunctionLiteral::kIsFunction, | |
2588 FunctionLiteral::kNotParenthesized, | |
2589 FunctionLiteral::kNotGenerator, | |
2590 start_pos); | |
2591 function_literal->set_function_token_position(start_pos); | |
2592 return function_literal; | |
2593 } | |
2594 | |
2595 | |
2173 template <typename Traits> | 2596 template <typename Traits> |
2174 typename ParserBase<Traits>::ExpressionT | 2597 typename ParserBase<Traits>::ExpressionT |
2175 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 2598 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
2176 ExpressionT expression, | 2599 ExpressionT expression, |
2177 Scanner::Location location, const char* message, bool* ok) { | 2600 Scanner::Location location, const char* message, bool* ok) { |
2178 if (strict_mode() == STRICT && this->IsIdentifier(expression) && | 2601 if (strict_mode() == STRICT && this->IsIdentifier(expression) && |
2179 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 2602 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
2180 this->ReportMessageAt(location, "strict_eval_arguments", false); | 2603 this->ReportMessageAt(location, "strict_eval_arguments", false); |
2181 *ok = false; | 2604 *ok = false; |
2182 return this->EmptyExpression(); | 2605 return this->EmptyExpression(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2226 parser()->ReportMessage("accessor_get_set"); | 2649 parser()->ReportMessage("accessor_get_set"); |
2227 } | 2650 } |
2228 *ok = false; | 2651 *ok = false; |
2229 } | 2652 } |
2230 } | 2653 } |
2231 | 2654 |
2232 | 2655 |
2233 } } // v8::internal | 2656 } } // v8::internal |
2234 | 2657 |
2235 #endif // V8_PREPARSER_H | 2658 #endif // V8_PREPARSER_H |
OLD | NEW |