| 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 |