| 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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 | 214 |
| 215 int NextHandlerIndex() { return next_handler_index_++; } | 215 int NextHandlerIndex() { return next_handler_index_++; } |
| 216 int handler_count() { return next_handler_index_; } | 216 int handler_count() { return next_handler_index_; } |
| 217 | 217 |
| 218 void AddProperty() { expected_property_count_++; } | 218 void AddProperty() { expected_property_count_++; } |
| 219 int expected_property_count() { return expected_property_count_; } | 219 int expected_property_count() { return expected_property_count_; } |
| 220 | 220 |
| 221 bool is_generator() const { return IsGeneratorFunction(kind_); } | 221 bool is_generator() const { return IsGeneratorFunction(kind_); } |
| 222 | 222 |
| 223 FunctionKind kind() const { return kind_; } | 223 FunctionKind kind() const { return kind_; } |
| 224 FunctionState* outer() const { return outer_function_state_; } |
| 224 | 225 |
| 225 void set_generator_object_variable( | 226 void set_generator_object_variable( |
| 226 typename Traits::Type::GeneratorVariable* variable) { | 227 typename Traits::Type::GeneratorVariable* variable) { |
| 227 DCHECK(variable != NULL); | 228 DCHECK(variable != NULL); |
| 228 DCHECK(is_generator()); | 229 DCHECK(is_generator()); |
| 229 generator_object_variable_ = variable; | 230 generator_object_variable_ = variable; |
| 230 } | 231 } |
| 231 typename Traits::Type::GeneratorVariable* generator_object_variable() | 232 typename Traits::Type::GeneratorVariable* generator_object_variable() |
| 232 const { | 233 const { |
| 233 return generator_object_variable_; | 234 return generator_object_variable_; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 246 | 247 |
| 247 // Properties count estimation. | 248 // Properties count estimation. |
| 248 int expected_property_count_; | 249 int expected_property_count_; |
| 249 | 250 |
| 250 FunctionKind kind_; | 251 FunctionKind kind_; |
| 251 // For generators, this variable may hold the generator object. It variable | 252 // For generators, this variable may hold the generator object. It variable |
| 252 // is used by yield expressions and return statements. It is not necessary | 253 // is used by yield expressions and return statements. It is not necessary |
| 253 // for generator functions to have this variable set. | 254 // for generator functions to have this variable set. |
| 254 Variable* generator_object_variable_; | 255 Variable* generator_object_variable_; |
| 255 | 256 |
| 256 | |
| 257 FunctionState** function_state_stack_; | 257 FunctionState** function_state_stack_; |
| 258 FunctionState* outer_function_state_; | 258 FunctionState* outer_function_state_; |
| 259 typename Traits::Type::Scope** scope_stack_; | 259 typename Traits::Type::Scope** scope_stack_; |
| 260 typename Traits::Type::Scope* outer_scope_; | 260 typename Traits::Type::Scope* outer_scope_; |
| 261 typename Traits::Type::Factory* factory_; | 261 typename Traits::Type::Factory* factory_; |
| 262 | 262 |
| 263 friend class ParserTraits; | 263 friend class ParserTraits; |
| 264 friend class Checkpoint; | 264 friend class Checkpoint; |
| 265 }; | 265 }; |
| 266 | 266 |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 ExpressionT ParsePostfixExpression(bool* ok); | 552 ExpressionT ParsePostfixExpression(bool* ok); |
| 553 ExpressionT ParseLeftHandSideExpression(bool* ok); | 553 ExpressionT ParseLeftHandSideExpression(bool* ok); |
| 554 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 554 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
| 555 ExpressionT ParseMemberExpression(bool* ok); | 555 ExpressionT ParseMemberExpression(bool* ok); |
| 556 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 556 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
| 557 bool* ok); | 557 bool* ok); |
| 558 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | 558 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
| 559 bool* ok); | 559 bool* ok); |
| 560 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 560 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
| 561 void AddTemplateExpression(ExpressionT); | 561 void AddTemplateExpression(ExpressionT); |
| 562 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
| 562 | 563 |
| 563 // Checks if the expression is a valid reference expression (e.g., on the | 564 // Checks if the expression is a valid reference expression (e.g., on the |
| 564 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 565 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
| 565 // we allow calls for web compatibility and rewrite them to a runtime throw. | 566 // we allow calls for web compatibility and rewrite them to a runtime throw. |
| 566 ExpressionT CheckAndRewriteReferenceExpression( | 567 ExpressionT CheckAndRewriteReferenceExpression( |
| 567 ExpressionT expression, | 568 ExpressionT expression, |
| 568 Scanner::Location location, const char* message, bool* ok); | 569 Scanner::Location location, const char* message, bool* ok); |
| 569 | 570 |
| 570 // Used to validate property names in object literals and class literals | 571 // Used to validate property names in object literals and class literals |
| 571 enum PropertyKind { | 572 enum PropertyKind { |
| (...skipping 2130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2702 // new foo()() means (new foo())() | 2703 // new foo()() means (new foo())() |
| 2703 // new new foo()() means (new (new foo())()) | 2704 // new new foo()() means (new (new foo())()) |
| 2704 // new new foo means new (new foo) | 2705 // new new foo means new (new foo) |
| 2705 // new new foo() means new (new foo()) | 2706 // new new foo() means new (new foo()) |
| 2706 // new new foo().bar().baz means (new (new foo()).bar()).baz | 2707 // new new foo().bar().baz means (new (new foo()).bar()).baz |
| 2707 | 2708 |
| 2708 if (peek() == Token::NEW) { | 2709 if (peek() == Token::NEW) { |
| 2709 Consume(Token::NEW); | 2710 Consume(Token::NEW); |
| 2710 int new_pos = position(); | 2711 int new_pos = position(); |
| 2711 ExpressionT result = this->EmptyExpression(); | 2712 ExpressionT result = this->EmptyExpression(); |
| 2712 if (Check(Token::SUPER)) { | 2713 if (peek() == Token::SUPER) { |
| 2713 result = this->SuperReference(scope_, factory()); | 2714 const bool is_new = true; |
| 2715 result = ParseSuperExpression(is_new, CHECK_OK); |
| 2714 } else { | 2716 } else { |
| 2715 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2717 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); |
| 2716 } | 2718 } |
| 2717 if (peek() == Token::LPAREN) { | 2719 if (peek() == Token::LPAREN) { |
| 2718 // NewExpression with arguments. | 2720 // NewExpression with arguments. |
| 2719 typename Traits::Type::ExpressionList args = | 2721 typename Traits::Type::ExpressionList args = |
| 2720 this->ParseArguments(CHECK_OK); | 2722 this->ParseArguments(CHECK_OK); |
| 2721 result = factory()->NewCallNew(result, args, new_pos); | 2723 result = factory()->NewCallNew(result, args, new_pos); |
| 2722 // The expression can still continue with . or [ after the arguments. | 2724 // The expression can still continue with . or [ after the arguments. |
| 2723 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); | 2725 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2760 function_name_location = scanner()->location(); | 2762 function_name_location = scanner()->location(); |
| 2761 function_type = FunctionLiteral::NAMED_EXPRESSION; | 2763 function_type = FunctionLiteral::NAMED_EXPRESSION; |
| 2762 } | 2764 } |
| 2763 result = this->ParseFunctionLiteral( | 2765 result = this->ParseFunctionLiteral( |
| 2764 name, function_name_location, is_strict_reserved_name, | 2766 name, function_name_location, is_strict_reserved_name, |
| 2765 is_generator ? FunctionKind::kGeneratorFunction | 2767 is_generator ? FunctionKind::kGeneratorFunction |
| 2766 : FunctionKind::kNormalFunction, | 2768 : FunctionKind::kNormalFunction, |
| 2767 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, | 2769 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, |
| 2768 CHECK_OK); | 2770 CHECK_OK); |
| 2769 } else if (peek() == Token::SUPER) { | 2771 } else if (peek() == Token::SUPER) { |
| 2770 int beg_pos = position(); | 2772 const bool is_new = false; |
| 2771 Consume(Token::SUPER); | 2773 result = ParseSuperExpression(is_new, CHECK_OK); |
| 2772 Token::Value next = peek(); | |
| 2773 if (next == Token::PERIOD || next == Token::LBRACK) { | |
| 2774 scope_->RecordSuperPropertyUsage(); | |
| 2775 result = this->SuperReference(scope_, factory()); | |
| 2776 } else if (next == Token::LPAREN) { | |
| 2777 scope_->RecordSuperConstructorCallUsage(); | |
| 2778 result = this->SuperReference(scope_, factory()); | |
| 2779 } else { | |
| 2780 ReportMessageAt(Scanner::Location(beg_pos, position()), | |
| 2781 "unexpected_super"); | |
| 2782 *ok = false; | |
| 2783 return this->EmptyExpression(); | |
| 2784 } | |
| 2785 } else { | 2774 } else { |
| 2786 result = ParsePrimaryExpression(CHECK_OK); | 2775 result = ParsePrimaryExpression(CHECK_OK); |
| 2787 } | 2776 } |
| 2788 | 2777 |
| 2789 result = ParseMemberExpressionContinuation(result, CHECK_OK); | 2778 result = ParseMemberExpressionContinuation(result, CHECK_OK); |
| 2790 return result; | 2779 return result; |
| 2791 } | 2780 } |
| 2792 | 2781 |
| 2793 | 2782 |
| 2794 template <class Traits> | 2783 template <class Traits> |
| 2795 typename ParserBase<Traits>::ExpressionT | 2784 typename ParserBase<Traits>::ExpressionT |
| 2785 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { |
| 2786 int beg_pos = position(); |
| 2787 Expect(Token::SUPER, CHECK_OK); |
| 2788 |
| 2789 FunctionState* function_state = function_state_; |
| 2790 while (IsArrowFunction(function_state->kind())) { |
| 2791 function_state = function_state->outer(); |
| 2792 } |
| 2793 // TODO(arv): Handle eval scopes similarly. |
| 2794 |
| 2795 FunctionKind kind = function_state->kind(); |
| 2796 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
| 2797 IsConstructor(kind)) { |
| 2798 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
| 2799 scope_->RecordSuperPropertyUsage(); |
| 2800 return this->SuperReference(scope_, factory()); |
| 2801 } |
| 2802 // new super() is never allowed. |
| 2803 // super() is only allowed in constructor |
| 2804 if (!is_new && peek() == Token::LPAREN && IsConstructor(kind)) { |
| 2805 scope_->RecordSuperConstructorCallUsage(); |
| 2806 return this->SuperReference(scope_, factory()); |
| 2807 } |
| 2808 } |
| 2809 |
| 2810 ReportMessageAt(Scanner::Location(beg_pos, position()), "unexpected_super"); |
| 2811 *ok = false; |
| 2812 return this->EmptyExpression(); |
| 2813 } |
| 2814 |
| 2815 |
| 2816 template <class Traits> |
| 2817 typename ParserBase<Traits>::ExpressionT |
| 2796 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, | 2818 ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression, |
| 2797 bool* ok) { | 2819 bool* ok) { |
| 2798 // Parses this part of MemberExpression: | 2820 // Parses this part of MemberExpression: |
| 2799 // ('[' Expression ']' | '.' Identifier)* | 2821 // ('[' Expression ']' | '.' Identifier)* |
| 2800 while (true) { | 2822 while (true) { |
| 2801 switch (peek()) { | 2823 switch (peek()) { |
| 2802 case Token::LBRACK: { | 2824 case Token::LBRACK: { |
| 2803 Consume(Token::LBRACK); | 2825 Consume(Token::LBRACK); |
| 2804 int pos = position(); | 2826 int pos = position(); |
| 2805 ExpressionT index = this->ParseExpression(true, CHECK_OK); | 2827 ExpressionT index = this->ParseExpression(true, CHECK_OK); |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3104 *ok = false; | 3126 *ok = false; |
| 3105 return; | 3127 return; |
| 3106 } | 3128 } |
| 3107 has_seen_constructor_ = true; | 3129 has_seen_constructor_ = true; |
| 3108 return; | 3130 return; |
| 3109 } | 3131 } |
| 3110 } | 3132 } |
| 3111 } } // v8::internal | 3133 } } // v8::internal |
| 3112 | 3134 |
| 3113 #endif // V8_PREPARSER_H | 3135 #endif // V8_PREPARSER_H |
| OLD | NEW |