Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(93)

Side by Side Diff: src/preparser.h

Issue 949763003: WIP: new.target (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/bailout-reason.h" 10 #include "src/bailout-reason.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 zone_(zone), 83 zone_(zone),
84 scanner_(scanner), 84 scanner_(scanner),
85 stack_overflow_(false), 85 stack_overflow_(false),
86 allow_lazy_(false), 86 allow_lazy_(false),
87 allow_natives_(false), 87 allow_natives_(false),
88 allow_harmony_arrow_functions_(false), 88 allow_harmony_arrow_functions_(false),
89 allow_harmony_object_literals_(false), 89 allow_harmony_object_literals_(false),
90 allow_harmony_sloppy_(false), 90 allow_harmony_sloppy_(false),
91 allow_harmony_computed_property_names_(false), 91 allow_harmony_computed_property_names_(false),
92 allow_harmony_rest_params_(false), 92 allow_harmony_rest_params_(false),
93 allow_harmony_new_target_(false),
93 allow_strong_mode_(false) {} 94 allow_strong_mode_(false) {}
94 95
95 // Getters that indicate whether certain syntactical constructs are 96 // Getters that indicate whether certain syntactical constructs are
96 // allowed to be parsed by this instance of the parser. 97 // allowed to be parsed by this instance of the parser.
97 bool allow_lazy() const { return allow_lazy_; } 98 bool allow_lazy() const { return allow_lazy_; }
98 bool allow_natives() const { return allow_natives_; } 99 bool allow_natives() const { return allow_natives_; }
99 bool allow_harmony_arrow_functions() const { 100 bool allow_harmony_arrow_functions() const {
100 return allow_harmony_arrow_functions_; 101 return allow_harmony_arrow_functions_;
101 } 102 }
102 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } 103 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); }
103 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } 104 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
104 bool allow_harmony_numeric_literals() const { 105 bool allow_harmony_numeric_literals() const {
105 return scanner()->HarmonyNumericLiterals(); 106 return scanner()->HarmonyNumericLiterals();
106 } 107 }
107 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } 108 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); }
108 bool allow_harmony_object_literals() const { 109 bool allow_harmony_object_literals() const {
109 return allow_harmony_object_literals_; 110 return allow_harmony_object_literals_;
110 } 111 }
111 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } 112 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); }
112 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } 113 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; }
113 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } 114 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); }
114 bool allow_harmony_computed_property_names() const { 115 bool allow_harmony_computed_property_names() const {
115 return allow_harmony_computed_property_names_; 116 return allow_harmony_computed_property_names_;
116 } 117 }
117 bool allow_harmony_rest_params() const { 118 bool allow_harmony_rest_params() const {
118 return allow_harmony_rest_params_; 119 return allow_harmony_rest_params_;
119 } 120 }
121 bool allow_harmony_new_target() const { return allow_harmony_new_target_; }
120 122
121 bool allow_strong_mode() const { return allow_strong_mode_; } 123 bool allow_strong_mode() const { return allow_strong_mode_; }
122 124
123 // Setters that determine whether certain syntactical constructs are 125 // Setters that determine whether certain syntactical constructs are
124 // allowed to be parsed by this instance of the parser. 126 // allowed to be parsed by this instance of the parser.
125 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } 127 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
126 void set_allow_natives(bool allow) { allow_natives_ = allow; } 128 void set_allow_natives(bool allow) { allow_natives_ = allow; }
127 void set_allow_harmony_arrow_functions(bool allow) { 129 void set_allow_harmony_arrow_functions(bool allow) {
128 allow_harmony_arrow_functions_ = allow; 130 allow_harmony_arrow_functions_ = allow;
129 } 131 }
(...skipping 20 matching lines...) Expand all
150 } 152 }
151 void set_allow_harmony_unicode(bool allow) { 153 void set_allow_harmony_unicode(bool allow) {
152 scanner()->SetHarmonyUnicode(allow); 154 scanner()->SetHarmonyUnicode(allow);
153 } 155 }
154 void set_allow_harmony_computed_property_names(bool allow) { 156 void set_allow_harmony_computed_property_names(bool allow) {
155 allow_harmony_computed_property_names_ = allow; 157 allow_harmony_computed_property_names_ = allow;
156 } 158 }
157 void set_allow_harmony_rest_params(bool allow) { 159 void set_allow_harmony_rest_params(bool allow) {
158 allow_harmony_rest_params_ = allow; 160 allow_harmony_rest_params_ = allow;
159 } 161 }
162 void set_allow_harmony_new_target(bool allow) {
163 allow_harmony_new_target_ = allow;
164 }
160 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } 165 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; }
161 166
162 protected: 167 protected:
163 enum AllowEvalOrArgumentsAsIdentifier { 168 enum AllowEvalOrArgumentsAsIdentifier {
164 kAllowEvalOrArguments, 169 kAllowEvalOrArguments,
165 kDontAllowEvalOrArguments 170 kDontAllowEvalOrArguments
166 }; 171 };
167 172
168 enum Mode { 173 enum Mode {
169 PARSE_LAZILY, 174 PARSE_LAZILY,
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 ExpressionT ParseLeftHandSideExpression(bool* ok); 589 ExpressionT ParseLeftHandSideExpression(bool* ok);
585 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); 590 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
586 ExpressionT ParseMemberExpression(bool* ok); 591 ExpressionT ParseMemberExpression(bool* ok);
587 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 592 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
588 bool* ok); 593 bool* ok);
589 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, 594 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
590 bool* ok); 595 bool* ok);
591 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); 596 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
592 void AddTemplateExpression(ExpressionT); 597 void AddTemplateExpression(ExpressionT);
593 ExpressionT ParseSuperExpression(bool is_new, bool* ok); 598 ExpressionT ParseSuperExpression(bool is_new, bool* ok);
599 ExpressionT ParseNewTargetExpression(bool* ok);
594 600
595 // Checks if the expression is a valid reference expression (e.g., on the 601 // Checks if the expression is a valid reference expression (e.g., on the
596 // left-hand side of assignments). Although ruled out by ECMA as early errors, 602 // left-hand side of assignments). Although ruled out by ECMA as early errors,
597 // we allow calls for web compatibility and rewrite them to a runtime throw. 603 // we allow calls for web compatibility and rewrite them to a runtime throw.
598 ExpressionT CheckAndRewriteReferenceExpression( 604 ExpressionT CheckAndRewriteReferenceExpression(
599 ExpressionT expression, 605 ExpressionT expression,
600 Scanner::Location location, const char* message, bool* ok); 606 Scanner::Location location, const char* message, bool* ok);
601 607
602 // Used to validate property names in object literals and class literals 608 // Used to validate property names in object literals and class literals
603 enum PropertyKind { 609 enum PropertyKind {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 Scanner* scanner_; 685 Scanner* scanner_;
680 bool stack_overflow_; 686 bool stack_overflow_;
681 687
682 bool allow_lazy_; 688 bool allow_lazy_;
683 bool allow_natives_; 689 bool allow_natives_;
684 bool allow_harmony_arrow_functions_; 690 bool allow_harmony_arrow_functions_;
685 bool allow_harmony_object_literals_; 691 bool allow_harmony_object_literals_;
686 bool allow_harmony_sloppy_; 692 bool allow_harmony_sloppy_;
687 bool allow_harmony_computed_property_names_; 693 bool allow_harmony_computed_property_names_;
688 bool allow_harmony_rest_params_; 694 bool allow_harmony_rest_params_;
695 bool allow_harmony_new_target_;
689 bool allow_strong_mode_; 696 bool allow_strong_mode_;
690 }; 697 };
691 698
692 699
693 class PreParserIdentifier { 700 class PreParserIdentifier {
694 public: 701 public:
695 PreParserIdentifier() : type_(kUnknownIdentifier) {} 702 PreParserIdentifier() : type_(kUnknownIdentifier) {}
696 static PreParserIdentifier Default() { 703 static PreParserIdentifier Default() {
697 return PreParserIdentifier(kUnknownIdentifier); 704 return PreParserIdentifier(kUnknownIdentifier);
698 } 705 }
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after
1390 static PreParserIdentifier GetNextSymbol(Scanner* scanner) { 1397 static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
1391 return PreParserIdentifier::Default(); 1398 return PreParserIdentifier::Default();
1392 } 1399 }
1393 1400
1394 static PreParserExpression ThisExpression(Scope* scope, 1401 static PreParserExpression ThisExpression(Scope* scope,
1395 PreParserFactory* factory, 1402 PreParserFactory* factory,
1396 int pos) { 1403 int pos) {
1397 return PreParserExpression::This(); 1404 return PreParserExpression::This();
1398 } 1405 }
1399 1406
1407 static PreParserExpression NewTargetExpression(Scope* scope,
1408 PreParserFactory* factory) {
1409 return PreParserExpression::Default();
1410 }
1411
1400 static PreParserExpression SuperReference(Scope* scope, 1412 static PreParserExpression SuperReference(Scope* scope,
1401 PreParserFactory* factory) { 1413 PreParserFactory* factory) {
1402 return PreParserExpression::Super(); 1414 return PreParserExpression::Super();
1403 } 1415 }
1404 1416
1405 static PreParserExpression DefaultConstructor(bool call_super, Scope* scope, 1417 static PreParserExpression DefaultConstructor(bool call_super, Scope* scope,
1406 int pos, int end_pos) { 1418 int pos, int end_pos) {
1407 return PreParserExpression::Default(); 1419 return PreParserExpression::Default();
1408 } 1420 }
1409 1421
(...skipping 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after
2671 } 2683 }
2672 } 2684 }
2673 2685
2674 2686
2675 template <class Traits> 2687 template <class Traits>
2676 typename ParserBase<Traits>::ExpressionT 2688 typename ParserBase<Traits>::ExpressionT
2677 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) { 2689 ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(bool* ok) {
2678 // NewExpression :: 2690 // NewExpression ::
2679 // ('new')+ MemberExpression 2691 // ('new')+ MemberExpression
2680 2692
2693 // NewTarget ::
2694 // 'new' '.' 'target'
2695
2681 // The grammar for new expressions is pretty warped. We can have several 'new' 2696 // The grammar for new expressions is pretty warped. We can have several 'new'
2682 // keywords following each other, and then a MemberExpression. When we see '(' 2697 // keywords following each other, and then a MemberExpression. When we see '('
2683 // after the MemberExpression, it's associated with the rightmost unassociated 2698 // after the MemberExpression, it's associated with the rightmost unassociated
2684 // 'new' to create a NewExpression with arguments. However, a NewExpression 2699 // 'new' to create a NewExpression with arguments. However, a NewExpression
2685 // can also occur without arguments. 2700 // can also occur without arguments.
2686 2701
2687 // Examples of new expression: 2702 // Examples of new expression:
2688 // new foo.bar().baz means (new (foo.bar)()).baz 2703 // new foo.bar().baz means (new (foo.bar)()).baz
2689 // new foo()() means (new foo())() 2704 // new foo()() means (new foo())()
2690 // new new foo()() means (new (new foo())()) 2705 // new new foo()() means (new (new foo())())
2691 // new new foo means new (new foo) 2706 // new new foo means new (new foo)
2692 // new new foo() means new (new foo()) 2707 // new new foo() means new (new foo())
2693 // new new foo().bar().baz means (new (new foo()).bar()).baz 2708 // new new foo().bar().baz means (new (new foo()).bar()).baz
2694 2709
2695 if (peek() == Token::NEW) { 2710 if (peek() == Token::NEW) {
2696 Consume(Token::NEW); 2711 Consume(Token::NEW);
2697 int new_pos = position(); 2712 int new_pos = position();
2698 ExpressionT result = this->EmptyExpression(); 2713 ExpressionT result = this->EmptyExpression();
2699 if (peek() == Token::SUPER) { 2714 if (peek() == Token::SUPER) {
2700 const bool is_new = true; 2715 const bool is_new = true;
2701 result = ParseSuperExpression(is_new, CHECK_OK); 2716 result = ParseSuperExpression(is_new, CHECK_OK);
2717 } else if (allow_harmony_new_target() && peek() == Token::PERIOD) {
2718 return ParseNewTargetExpression(CHECK_OK);
2702 } else { 2719 } else {
2703 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); 2720 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
2704 } 2721 }
2705 if (peek() == Token::LPAREN) { 2722 if (peek() == Token::LPAREN) {
2706 // NewExpression with arguments. 2723 // NewExpression with arguments.
2707 typename Traits::Type::ExpressionList args = 2724 typename Traits::Type::ExpressionList args =
2708 this->ParseArguments(CHECK_OK); 2725 this->ParseArguments(CHECK_OK);
2709 result = factory()->NewCallNew(result, args, new_pos); 2726 result = factory()->NewCallNew(result, args, new_pos);
2710 // The expression can still continue with . or [ after the arguments. 2727 // The expression can still continue with . or [ after the arguments.
2711 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); 2728 result = this->ParseMemberExpressionContinuation(result, CHECK_OK);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2792 } 2809 }
2793 2810
2794 ReportMessageAt(scanner()->location(), "unexpected_super"); 2811 ReportMessageAt(scanner()->location(), "unexpected_super");
2795 *ok = false; 2812 *ok = false;
2796 return this->EmptyExpression(); 2813 return this->EmptyExpression();
2797 } 2814 }
2798 2815
2799 2816
2800 template <class Traits> 2817 template <class Traits>
2801 typename ParserBase<Traits>::ExpressionT 2818 typename ParserBase<Traits>::ExpressionT
2819 ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
2820 Consume(Token::PERIOD);
2821 ExpectContextualKeyword(CStrVector("target"), CHECK_OK);
2822
2823 Scope* scope = scope_;
2824 while (scope->is_eval_scope() || scope->is_arrow_scope()) {
2825 scope = scope->outer_scope();
2826 DCHECK_NOT_NULL(scope);
2827 scope = scope->DeclarationScope();
2828 }
2829
2830 if (scope->is_script_scope() || scope->is_module_scope()) {
2831 ReportMessageAt(scanner()->location(), "unexpected_new_target");
2832 *ok = false;
2833 return this->EmptyExpression();
2834 }
2835
2836 scope_->RecordNewTargetUsage();
2837 return this->NewTargetExpression(scope_, factory());
2838 }
2839
2840
2841 template <class Traits>
2842 typename ParserBase<Traits>::ExpressionT
2802 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, 2843 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
2803 bool* ok) { 2844 bool* ok) {
2804 // Parses this part of MemberExpression: 2845 // Parses this part of MemberExpression:
2805 // ('[' Expression ']' | '.' Identifier)* 2846 // ('[' Expression ']' | '.' Identifier)*
2806 while (true) { 2847 while (true) {
2807 switch (peek()) { 2848 switch (peek()) {
2808 case Token::LBRACK: { 2849 case Token::LBRACK: {
2809 Consume(Token::LBRACK); 2850 Consume(Token::LBRACK);
2810 int pos = position(); 2851 int pos = position();
2811 ExpressionT index = this->ParseExpression(true, CHECK_OK); 2852 ExpressionT index = this->ParseExpression(true, CHECK_OK);
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
3109 *ok = false; 3150 *ok = false;
3110 return; 3151 return;
3111 } 3152 }
3112 has_seen_constructor_ = true; 3153 has_seen_constructor_ = true;
3113 return; 3154 return;
3114 } 3155 }
3115 } 3156 }
3116 } } // v8::internal 3157 } } // v8::internal
3117 3158
3118 #endif // V8_PREPARSER_H 3159 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698