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/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 | 210 |
211 int NextHandlerIndex() { return next_handler_index_++; } | 211 int NextHandlerIndex() { return next_handler_index_++; } |
212 int handler_count() { return next_handler_index_; } | 212 int handler_count() { return next_handler_index_; } |
213 | 213 |
214 void AddProperty() { expected_property_count_++; } | 214 void AddProperty() { expected_property_count_++; } |
215 int expected_property_count() { return expected_property_count_; } | 215 int expected_property_count() { return expected_property_count_; } |
216 | 216 |
217 bool is_generator() const { return IsGeneratorFunction(kind_); } | 217 bool is_generator() const { return IsGeneratorFunction(kind_); } |
218 | 218 |
219 FunctionKind kind() const { return kind_; } | 219 FunctionKind kind() const { return kind_; } |
| 220 FunctionState* outer() const { return outer_function_state_; } |
220 | 221 |
221 void set_generator_object_variable( | 222 void set_generator_object_variable( |
222 typename Traits::Type::GeneratorVariable* variable) { | 223 typename Traits::Type::GeneratorVariable* variable) { |
223 DCHECK(variable != NULL); | 224 DCHECK(variable != NULL); |
224 DCHECK(is_generator()); | 225 DCHECK(is_generator()); |
225 generator_object_variable_ = variable; | 226 generator_object_variable_ = variable; |
226 } | 227 } |
227 typename Traits::Type::GeneratorVariable* generator_object_variable() | 228 typename Traits::Type::GeneratorVariable* generator_object_variable() |
228 const { | 229 const { |
229 return generator_object_variable_; | 230 return generator_object_variable_; |
(...skipping 12 matching lines...) Expand all Loading... |
242 | 243 |
243 // Properties count estimation. | 244 // Properties count estimation. |
244 int expected_property_count_; | 245 int expected_property_count_; |
245 | 246 |
246 FunctionKind kind_; | 247 FunctionKind kind_; |
247 // For generators, this variable may hold the generator object. It variable | 248 // For generators, this variable may hold the generator object. It variable |
248 // is used by yield expressions and return statements. It is not necessary | 249 // is used by yield expressions and return statements. It is not necessary |
249 // for generator functions to have this variable set. | 250 // for generator functions to have this variable set. |
250 Variable* generator_object_variable_; | 251 Variable* generator_object_variable_; |
251 | 252 |
252 | |
253 FunctionState** function_state_stack_; | 253 FunctionState** function_state_stack_; |
254 FunctionState* outer_function_state_; | 254 FunctionState* outer_function_state_; |
255 Scope** scope_stack_; | 255 Scope** scope_stack_; |
256 Scope* outer_scope_; | 256 Scope* outer_scope_; |
257 typename Traits::Type::Factory* factory_; | 257 typename Traits::Type::Factory* factory_; |
258 | 258 |
259 friend class ParserTraits; | 259 friend class ParserTraits; |
260 friend class Checkpoint; | 260 friend class Checkpoint; |
261 }; | 261 }; |
262 | 262 |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 ExpressionT ParsePostfixExpression(bool* ok); | 562 ExpressionT ParsePostfixExpression(bool* ok); |
563 ExpressionT ParseLeftHandSideExpression(bool* ok); | 563 ExpressionT ParseLeftHandSideExpression(bool* ok); |
564 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 564 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
565 ExpressionT ParseMemberExpression(bool* ok); | 565 ExpressionT ParseMemberExpression(bool* ok); |
566 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 566 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
567 bool* ok); | 567 bool* ok); |
568 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | 568 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
569 bool* ok); | 569 bool* ok); |
570 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 570 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
571 void AddTemplateExpression(ExpressionT); | 571 void AddTemplateExpression(ExpressionT); |
| 572 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
572 | 573 |
573 // Checks if the expression is a valid reference expression (e.g., on the | 574 // Checks if the expression is a valid reference expression (e.g., on the |
574 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 575 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
575 // we allow calls for web compatibility and rewrite them to a runtime throw. | 576 // we allow calls for web compatibility and rewrite them to a runtime throw. |
576 ExpressionT CheckAndRewriteReferenceExpression( | 577 ExpressionT CheckAndRewriteReferenceExpression( |
577 ExpressionT expression, | 578 ExpressionT expression, |
578 Scanner::Location location, const char* message, bool* ok); | 579 Scanner::Location location, const char* message, bool* ok); |
579 | 580 |
580 // Used to validate property names in object literals and class literals | 581 // Used to validate property names in object literals and class literals |
581 enum PropertyKind { | 582 enum PropertyKind { |
(...skipping 2077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2659 // new foo()() means (new foo())() | 2660 // new foo()() means (new foo())() |
2660 // new new foo()() means (new (new foo())()) | 2661 // new new foo()() means (new (new foo())()) |
2661 // new new foo means new (new foo) | 2662 // new new foo means new (new foo) |
2662 // new new foo() means new (new foo()) | 2663 // new new foo() means new (new foo()) |
2663 // new new foo().bar().baz means (new (new foo()).bar()).baz | 2664 // new new foo().bar().baz means (new (new foo()).bar()).baz |
2664 | 2665 |
2665 if (peek() == Token::NEW) { | 2666 if (peek() == Token::NEW) { |
2666 Consume(Token::NEW); | 2667 Consume(Token::NEW); |
2667 int new_pos = position(); | 2668 int new_pos = position(); |
2668 ExpressionT result = this->EmptyExpression(); | 2669 ExpressionT result = this->EmptyExpression(); |
2669 if (Check(Token::SUPER)) { | 2670 if (peek() == Token::SUPER) { |
2670 result = this->SuperReference(scope_, factory()); | 2671 const bool is_new = true; |
| 2672 result = ParseSuperExpression(is_new, CHECK_OK); |
2671 } else { | 2673 } else { |
2672 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2674 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); |
2673 } | 2675 } |
2674 if (peek() == Token::LPAREN) { | 2676 if (peek() == Token::LPAREN) { |
2675 // NewExpression with arguments. | 2677 // NewExpression with arguments. |
2676 typename Traits::Type::ExpressionList args = | 2678 typename Traits::Type::ExpressionList args = |
2677 this->ParseArguments(CHECK_OK); | 2679 this->ParseArguments(CHECK_OK); |
2678 result = factory()->NewCallNew(result, args, new_pos); | 2680 result = factory()->NewCallNew(result, args, new_pos); |
2679 // The expression can still continue with . or [ after the arguments. | 2681 // The expression can still continue with . or [ after the arguments. |
2680 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); | 2682 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2717 function_name_location = scanner()->location(); | 2719 function_name_location = scanner()->location(); |
2718 function_type = FunctionLiteral::NAMED_EXPRESSION; | 2720 function_type = FunctionLiteral::NAMED_EXPRESSION; |
2719 } | 2721 } |
2720 result = this->ParseFunctionLiteral( | 2722 result = this->ParseFunctionLiteral( |
2721 name, function_name_location, is_strict_reserved_name, | 2723 name, function_name_location, is_strict_reserved_name, |
2722 is_generator ? FunctionKind::kGeneratorFunction | 2724 is_generator ? FunctionKind::kGeneratorFunction |
2723 : FunctionKind::kNormalFunction, | 2725 : FunctionKind::kNormalFunction, |
2724 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, | 2726 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, |
2725 CHECK_OK); | 2727 CHECK_OK); |
2726 } else if (peek() == Token::SUPER) { | 2728 } else if (peek() == Token::SUPER) { |
2727 int beg_pos = position(); | 2729 const bool is_new = false; |
2728 Consume(Token::SUPER); | 2730 result = ParseSuperExpression(is_new, CHECK_OK); |
2729 Token::Value next = peek(); | |
2730 if (next == Token::PERIOD || next == Token::LBRACK) { | |
2731 scope_->RecordSuperPropertyUsage(); | |
2732 result = this->SuperReference(scope_, factory()); | |
2733 } else if (next == Token::LPAREN) { | |
2734 scope_->RecordSuperConstructorCallUsage(); | |
2735 result = this->SuperReference(scope_, factory()); | |
2736 } else { | |
2737 ReportMessageAt(Scanner::Location(beg_pos, position()), | |
2738 "unexpected_super"); | |
2739 *ok = false; | |
2740 return this->EmptyExpression(); | |
2741 } | |
2742 } else { | 2731 } else { |
2743 result = ParsePrimaryExpression(CHECK_OK); | 2732 result = ParsePrimaryExpression(CHECK_OK); |
2744 } | 2733 } |
2745 | 2734 |
2746 result = ParseMemberExpressionContinuation(result, CHECK_OK); | 2735 result = ParseMemberExpressionContinuation(result, CHECK_OK); |
2747 return result; | 2736 return result; |
2748 } | 2737 } |
2749 | 2738 |
2750 | 2739 |
2751 template <class Traits> | 2740 template <class Traits> |
2752 typename ParserBase<Traits>::ExpressionT | 2741 typename ParserBase<Traits>::ExpressionT |
| 2742 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { |
| 2743 int beg_pos = position(); |
| 2744 Expect(Token::SUPER, CHECK_OK); |
| 2745 |
| 2746 FunctionState* function_state = function_state_; |
| 2747 while (IsArrowFunction(function_state->kind())) { |
| 2748 function_state = function_state->outer(); |
| 2749 } |
| 2750 // TODO(arv): Handle eval scopes similarly. |
| 2751 |
| 2752 FunctionKind kind = function_state->kind(); |
| 2753 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
| 2754 i::IsConstructor(kind)) { |
| 2755 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
| 2756 scope_->RecordSuperPropertyUsage(); |
| 2757 return this->SuperReference(scope_, factory()); |
| 2758 } |
| 2759 // new super() is never allowed. |
| 2760 // super() is only allowed in constructor |
| 2761 if (!is_new && peek() == Token::LPAREN && i::IsConstructor(kind)) { |
| 2762 scope_->RecordSuperConstructorCallUsage(); |
| 2763 return this->SuperReference(scope_, factory()); |
| 2764 } |
| 2765 } |
| 2766 |
| 2767 ReportMessageAt(Scanner::Location(beg_pos, position()), "unexpected_super"); |
| 2768 *ok = false; |
| 2769 return this->EmptyExpression(); |
| 2770 } |
| 2771 |
| 2772 |
| 2773 template <class Traits> |
| 2774 typename ParserBase<Traits>::ExpressionT |
2753 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, | 2775 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, |
2754 bool* ok) { | 2776 bool* ok) { |
2755 // Parses this part of MemberExpression: | 2777 // Parses this part of MemberExpression: |
2756 // ('[' Expression ']' | '.' Identifier)* | 2778 // ('[' Expression ']' | '.' Identifier)* |
2757 while (true) { | 2779 while (true) { |
2758 switch (peek()) { | 2780 switch (peek()) { |
2759 case Token::LBRACK: { | 2781 case Token::LBRACK: { |
2760 Consume(Token::LBRACK); | 2782 Consume(Token::LBRACK); |
2761 int pos = position(); | 2783 int pos = position(); |
2762 ExpressionT index = this->ParseExpression(true, CHECK_OK); | 2784 ExpressionT index = this->ParseExpression(true, CHECK_OK); |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3060 *ok = false; | 3082 *ok = false; |
3061 return; | 3083 return; |
3062 } | 3084 } |
3063 has_seen_constructor_ = true; | 3085 has_seen_constructor_ = true; |
3064 return; | 3086 return; |
3065 } | 3087 } |
3066 } | 3088 } |
3067 } } // v8::internal | 3089 } } // v8::internal |
3068 | 3090 |
3069 #endif // V8_PREPARSER_H | 3091 #endif // V8_PREPARSER_H |
OLD | NEW |