Chromium Code Reviews| 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 int materialized_literal_count() { | 210 int materialized_literal_count() { |
| 211 return next_materialized_literal_index_; | 211 return next_materialized_literal_index_; |
| 212 } | 212 } |
| 213 | 213 |
| 214 int NextHandlerIndex() { return next_handler_index_++; } | 214 int NextHandlerIndex() { return next_handler_index_++; } |
| 215 int handler_count() { return next_handler_index_; } | 215 int handler_count() { return next_handler_index_; } |
| 216 | 216 |
| 217 void AddProperty() { expected_property_count_++; } | 217 void AddProperty() { expected_property_count_++; } |
| 218 int expected_property_count() { return expected_property_count_; } | 218 int expected_property_count() { return expected_property_count_; } |
| 219 | 219 |
| 220 Scanner::Location this_location() const { return this_location_; } | |
| 221 Scanner::Location super_location() const { return super_location_; } | |
| 220 Scanner::Location return_location() const { return return_location_; } | 222 Scanner::Location return_location() const { return return_location_; } |
| 221 Scanner::Location super_call_location() const { | 223 void set_this_location(Scanner::Location location) { |
| 222 return super_call_location_; | 224 this_location_ = location; |
| 225 } | |
| 226 void set_super_location(Scanner::Location location) { | |
| 227 super_location_ = location; | |
| 223 } | 228 } |
| 224 void set_return_location(Scanner::Location location) { | 229 void set_return_location(Scanner::Location location) { |
| 225 return_location_ = location; | 230 return_location_ = location; |
| 226 } | 231 } |
| 227 void set_super_call_location(Scanner::Location location) { | |
| 228 super_call_location_ = location; | |
| 229 } | |
| 230 | 232 |
| 231 bool is_generator() const { return IsGeneratorFunction(kind_); } | 233 bool is_generator() const { return IsGeneratorFunction(kind_); } |
| 232 | 234 |
| 233 FunctionKind kind() const { return kind_; } | 235 FunctionKind kind() const { return kind_; } |
| 234 FunctionState* outer() const { return outer_function_state_; } | 236 FunctionState* outer() const { return outer_function_state_; } |
| 235 | 237 |
| 236 void set_generator_object_variable( | 238 void set_generator_object_variable( |
| 237 typename Traits::Type::GeneratorVariable* variable) { | 239 typename Traits::Type::GeneratorVariable* variable) { |
| 238 DCHECK(variable != NULL); | 240 DCHECK(variable != NULL); |
| 239 DCHECK(is_generator()); | 241 DCHECK(is_generator()); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 251 // the function. Includes regexp literals, and boilerplate for object and | 253 // the function. Includes regexp literals, and boilerplate for object and |
| 252 // array literals. | 254 // array literals. |
| 253 int next_materialized_literal_index_; | 255 int next_materialized_literal_index_; |
| 254 | 256 |
| 255 // Used to assign a per-function index to try and catch handlers. | 257 // Used to assign a per-function index to try and catch handlers. |
| 256 int next_handler_index_; | 258 int next_handler_index_; |
| 257 | 259 |
| 258 // Properties count estimation. | 260 // Properties count estimation. |
| 259 int expected_property_count_; | 261 int expected_property_count_; |
| 260 | 262 |
| 263 // Location of most recent use of 'this' (invalid if none). | |
| 264 Scanner::Location this_location_; | |
| 265 | |
| 261 // Location of most recent 'return' statement (invalid if none). | 266 // Location of most recent 'return' statement (invalid if none). |
| 262 Scanner::Location return_location_; | 267 Scanner::Location return_location_; |
| 263 | 268 |
| 264 // Location of call to the "super" constructor (invalid if none). | 269 // Location of call to the "super" constructor (invalid if none). |
| 265 Scanner::Location super_call_location_; | 270 Scanner::Location super_location_; |
| 266 | 271 |
| 267 FunctionKind kind_; | 272 FunctionKind kind_; |
| 268 // For generators, this variable may hold the generator object. It variable | 273 // For generators, this variable may hold the generator object. It variable |
| 269 // is used by yield expressions and return statements. It is not necessary | 274 // is used by yield expressions and return statements. It is not necessary |
| 270 // for generator functions to have this variable set. | 275 // for generator functions to have this variable set. |
| 271 Variable* generator_object_variable_; | 276 Variable* generator_object_variable_; |
| 272 | 277 |
| 273 FunctionState** function_state_stack_; | 278 FunctionState** function_state_stack_; |
| 274 FunctionState* outer_function_state_; | 279 FunctionState* outer_function_state_; |
| 275 Scope** scope_stack_; | 280 Scope** scope_stack_; |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 597 ExpressionT ParseLeftHandSideExpression(bool* ok); | 602 ExpressionT ParseLeftHandSideExpression(bool* ok); |
| 598 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 603 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
| 599 ExpressionT ParseMemberExpression(bool* ok); | 604 ExpressionT ParseMemberExpression(bool* ok); |
| 600 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 605 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
| 601 bool* ok); | 606 bool* ok); |
| 602 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | 607 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
| 603 bool* ok); | 608 bool* ok); |
| 604 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 609 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
| 605 void AddTemplateExpression(ExpressionT); | 610 void AddTemplateExpression(ExpressionT); |
| 606 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 611 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
| 612 ExpressionT ParseStrongInitializationExpression(bool* ok); | |
| 613 ExpressionT ParseStrongSuperCallExpression(bool* ok); | |
| 607 | 614 |
| 608 // Checks if the expression is a valid reference expression (e.g., on the | 615 // Checks if the expression is a valid reference expression (e.g., on the |
| 609 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 616 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
| 610 // we allow calls for web compatibility and rewrite them to a runtime throw. | 617 // we allow calls for web compatibility and rewrite them to a runtime throw. |
| 611 ExpressionT CheckAndRewriteReferenceExpression( | 618 ExpressionT CheckAndRewriteReferenceExpression( |
| 612 ExpressionT expression, | 619 ExpressionT expression, |
| 613 Scanner::Location location, const char* message, bool* ok); | 620 Scanner::Location location, const char* message, bool* ok); |
| 614 | 621 |
| 615 // Used to validate property names in object literals and class literals | 622 // Used to validate property names in object literals and class literals |
| 616 enum PropertyKind { | 623 enum PropertyKind { |
| (...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1440 } | 1447 } |
| 1441 | 1448 |
| 1442 static PreParserStatementList NewStatementList(int size, Zone* zone) { | 1449 static PreParserStatementList NewStatementList(int size, Zone* zone) { |
| 1443 return PreParserStatementList(); | 1450 return PreParserStatementList(); |
| 1444 } | 1451 } |
| 1445 | 1452 |
| 1446 static PreParserExpressionList NewPropertyList(int size, Zone* zone) { | 1453 static PreParserExpressionList NewPropertyList(int size, Zone* zone) { |
| 1447 return PreParserExpressionList(); | 1454 return PreParserExpressionList(); |
| 1448 } | 1455 } |
| 1449 | 1456 |
| 1450 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, | 1457 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count, |
| 1451 int* materialized_literal_count, | |
| 1452 int* expected_property_count, bool* ok) { | 1458 int* expected_property_count, bool* ok) { |
| 1453 UNREACHABLE(); | 1459 UNREACHABLE(); |
| 1454 } | 1460 } |
| 1455 | 1461 |
| 1456 V8_INLINE PreParserStatementList | 1462 V8_INLINE PreParserStatementList |
| 1457 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1463 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
| 1458 Variable* fvar, Token::Value fvar_init_op, | 1464 Variable* fvar, Token::Value fvar_init_op, |
| 1459 FunctionKind kind, bool* ok); | 1465 FunctionKind kind, bool* ok); |
| 1460 | 1466 |
| 1461 // Utility functions | 1467 // Utility functions |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1611 Statement ParseDoWhileStatement(bool* ok); | 1617 Statement ParseDoWhileStatement(bool* ok); |
| 1612 Statement ParseWhileStatement(bool* ok); | 1618 Statement ParseWhileStatement(bool* ok); |
| 1613 Statement ParseForStatement(bool* ok); | 1619 Statement ParseForStatement(bool* ok); |
| 1614 Statement ParseThrowStatement(bool* ok); | 1620 Statement ParseThrowStatement(bool* ok); |
| 1615 Statement ParseTryStatement(bool* ok); | 1621 Statement ParseTryStatement(bool* ok); |
| 1616 Statement ParseDebuggerStatement(bool* ok); | 1622 Statement ParseDebuggerStatement(bool* ok); |
| 1617 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 1623 Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
| 1618 Expression ParseObjectLiteral(bool* ok); | 1624 Expression ParseObjectLiteral(bool* ok); |
| 1619 Expression ParseV8Intrinsic(bool* ok); | 1625 Expression ParseV8Intrinsic(bool* ok); |
| 1620 | 1626 |
| 1621 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, | 1627 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count, |
| 1622 int* materialized_literal_count, | |
| 1623 int* expected_property_count, bool* ok); | 1628 int* expected_property_count, bool* ok); |
| 1624 V8_INLINE PreParserStatementList | 1629 V8_INLINE PreParserStatementList |
| 1625 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1630 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
| 1626 Variable* fvar, Token::Value fvar_init_op, | 1631 Variable* fvar, Token::Value fvar_init_op, |
| 1627 FunctionKind kind, bool* ok); | 1632 FunctionKind kind, bool* ok); |
| 1628 | 1633 |
| 1629 Expression ParseFunctionLiteral( | 1634 Expression ParseFunctionLiteral( |
| 1630 Identifier name, Scanner::Location function_name_location, | 1635 Identifier name, Scanner::Location function_name_location, |
| 1631 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, | 1636 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, |
| 1632 FunctionLiteral::FunctionType function_type, | 1637 FunctionLiteral::FunctionType function_type, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1667 } | 1672 } |
| 1668 | 1673 |
| 1669 | 1674 |
| 1670 template <class Traits> | 1675 template <class Traits> |
| 1671 ParserBase<Traits>::FunctionState::FunctionState( | 1676 ParserBase<Traits>::FunctionState::FunctionState( |
| 1672 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, | 1677 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, |
| 1673 FunctionKind kind, typename Traits::Type::Factory* factory) | 1678 FunctionKind kind, typename Traits::Type::Factory* factory) |
| 1674 : next_materialized_literal_index_(0), | 1679 : next_materialized_literal_index_(0), |
| 1675 next_handler_index_(0), | 1680 next_handler_index_(0), |
| 1676 expected_property_count_(0), | 1681 expected_property_count_(0), |
| 1682 this_location_(Scanner::Location::invalid()), | |
| 1677 return_location_(Scanner::Location::invalid()), | 1683 return_location_(Scanner::Location::invalid()), |
| 1678 super_call_location_(Scanner::Location::invalid()), | 1684 super_location_(Scanner::Location::invalid()), |
| 1679 kind_(kind), | 1685 kind_(kind), |
| 1680 generator_object_variable_(NULL), | 1686 generator_object_variable_(NULL), |
| 1681 function_state_stack_(function_state_stack), | 1687 function_state_stack_(function_state_stack), |
| 1682 outer_function_state_(*function_state_stack), | 1688 outer_function_state_(*function_state_stack), |
| 1683 scope_stack_(scope_stack), | 1689 scope_stack_(scope_stack), |
| 1684 outer_scope_(*scope_stack), | 1690 outer_scope_(*scope_stack), |
| 1685 factory_(factory) { | 1691 factory_(factory) { |
| 1686 *scope_stack_ = scope; | 1692 *scope_stack_ = scope; |
| 1687 *function_state_stack = this; | 1693 *function_state_stack = this; |
| 1688 } | 1694 } |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1881 // '(' Expression ')' | 1887 // '(' Expression ')' |
| 1882 // TemplateLiteral | 1888 // TemplateLiteral |
| 1883 | 1889 |
| 1884 int beg_pos = scanner()->peek_location().beg_pos; | 1890 int beg_pos = scanner()->peek_location().beg_pos; |
| 1885 int end_pos = scanner()->peek_location().end_pos; | 1891 int end_pos = scanner()->peek_location().end_pos; |
| 1886 ExpressionT result = this->EmptyExpression(); | 1892 ExpressionT result = this->EmptyExpression(); |
| 1887 Token::Value token = peek(); | 1893 Token::Value token = peek(); |
| 1888 switch (token) { | 1894 switch (token) { |
| 1889 case Token::THIS: { | 1895 case Token::THIS: { |
| 1890 Consume(Token::THIS); | 1896 Consume(Token::THIS); |
| 1897 if (is_strong(language_mode())) { | |
| 1898 // Constructors' usages of 'this' in strong mode are parsed separately. | |
| 1899 // TODO(rossberg): this does not work with arrow functions yet. | |
| 1900 if (i::IsConstructor(function_state_->kind())) { | |
| 1901 ReportMessage("strong_constructor_this"); | |
| 1902 *ok = false; | |
| 1903 break; | |
| 1904 } | |
| 1905 } | |
| 1891 scope_->RecordThisUsage(); | 1906 scope_->RecordThisUsage(); |
| 1892 result = this->ThisExpression(scope_, factory(), beg_pos); | 1907 result = this->ThisExpression(scope_, factory(), beg_pos); |
| 1893 break; | 1908 break; |
| 1894 } | 1909 } |
| 1895 | 1910 |
| 1896 case Token::NULL_LITERAL: | 1911 case Token::NULL_LITERAL: |
| 1897 case Token::TRUE_LITERAL: | 1912 case Token::TRUE_LITERAL: |
| 1898 case Token::FALSE_LITERAL: | 1913 case Token::FALSE_LITERAL: |
| 1899 case Token::SMI: | 1914 case Token::SMI: |
| 1900 case Token::NUMBER: | 1915 case Token::NUMBER: |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1951 parenthesized_function_ = (peek() == Token::FUNCTION); | 1966 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 1952 result = this->ParseExpression(true, CHECK_OK); | 1967 result = this->ParseExpression(true, CHECK_OK); |
| 1953 result->increase_parenthesization_level(); | 1968 result->increase_parenthesization_level(); |
| 1954 Expect(Token::RPAREN, CHECK_OK); | 1969 Expect(Token::RPAREN, CHECK_OK); |
| 1955 } | 1970 } |
| 1956 break; | 1971 break; |
| 1957 | 1972 |
| 1958 case Token::CLASS: { | 1973 case Token::CLASS: { |
| 1959 Consume(Token::CLASS); | 1974 Consume(Token::CLASS); |
| 1960 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 1975 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
| 1961 ReportMessage("sloppy_lexical", NULL); | 1976 ReportMessage("sloppy_lexical"); |
| 1962 *ok = false; | 1977 *ok = false; |
| 1963 break; | 1978 break; |
| 1964 } | 1979 } |
| 1965 int class_token_position = position(); | 1980 int class_token_position = position(); |
| 1966 IdentifierT name = this->EmptyIdentifier(); | 1981 IdentifierT name = this->EmptyIdentifier(); |
| 1967 bool is_strict_reserved_name = false; | 1982 bool is_strict_reserved_name = false; |
| 1968 Scanner::Location class_name_location = Scanner::Location::invalid(); | 1983 Scanner::Location class_name_location = Scanner::Location::invalid(); |
| 1969 if (peek_any_identifier()) { | 1984 if (peek_any_identifier()) { |
| 1970 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 1985 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
| 1971 CHECK_OK); | 1986 CHECK_OK); |
| (...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2778 result = ParsePrimaryExpression(CHECK_OK); | 2793 result = ParsePrimaryExpression(CHECK_OK); |
| 2779 } | 2794 } |
| 2780 | 2795 |
| 2781 result = ParseMemberExpressionContinuation(result, CHECK_OK); | 2796 result = ParseMemberExpressionContinuation(result, CHECK_OK); |
| 2782 return result; | 2797 return result; |
| 2783 } | 2798 } |
| 2784 | 2799 |
| 2785 | 2800 |
| 2786 template <class Traits> | 2801 template <class Traits> |
| 2787 typename ParserBase<Traits>::ExpressionT | 2802 typename ParserBase<Traits>::ExpressionT |
| 2803 ParserBase<Traits>::ParseStrongInitializationExpression(bool* ok) { | |
| 2804 // InitializationExpression :: (strong mode) | |
| 2805 // 'this' '.' IdentifierName '=' AssignmentExpression | |
| 2806 // 'this' '[' Expression ']' '=' AssignmentExpression | |
| 2807 | |
| 2808 Consume(Token::THIS); | |
| 2809 int pos = position(); | |
| 2810 function_state_->set_this_location(scanner()->location()); | |
| 2811 scope_->RecordThisUsage(); | |
| 2812 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); | |
| 2813 | |
| 2814 ExpressionT left = this->EmptyExpression(); | |
| 2815 switch (peek()) { | |
| 2816 case Token::LBRACK: { | |
| 2817 Consume(Token::LBRACK); | |
| 2818 int pos = position(); | |
| 2819 ExpressionT index = this->ParseExpression(true, CHECK_OK); | |
| 2820 left = factory()->NewProperty(this_expr, index, pos); | |
| 2821 if (fni_ != NULL) { | |
| 2822 this->PushPropertyName(fni_, index); | |
| 2823 } | |
| 2824 Expect(Token::RBRACK, CHECK_OK); | |
| 2825 break; | |
| 2826 } | |
| 2827 case Token::PERIOD: { | |
| 2828 Consume(Token::PERIOD); | |
| 2829 int pos = position(); | |
| 2830 IdentifierT name = ParseIdentifierName(CHECK_OK); | |
| 2831 left = factory()->NewProperty( | |
| 2832 this_expr, factory()->NewStringLiteral(name, pos), pos); | |
| 2833 if (fni_ != NULL) { | |
| 2834 this->PushLiteralName(fni_, name); | |
| 2835 } | |
| 2836 break; | |
| 2837 } | |
| 2838 default: | |
| 2839 ReportMessage("strong_constructor_this"); | |
| 2840 *ok = false; | |
| 2841 return this->EmptyExpression(); | |
| 2842 } | |
| 2843 | |
| 2844 if (peek() != Token::ASSIGN) { | |
| 2845 ReportMessageAt(function_state_->this_location(), | |
| 2846 "strong_constructor_this"); | |
| 2847 *ok = false; | |
| 2848 return this->EmptyExpression(); | |
| 2849 } | |
| 2850 Consume(Token::ASSIGN); | |
| 2851 left = this->MarkExpressionAsAssigned(left); | |
| 2852 | |
| 2853 ExpressionT right = this->ParseAssignmentExpression(true, CHECK_OK); | |
| 2854 this->CheckAssigningFunctionLiteralToProperty(left, right); | |
| 2855 function_state_->AddProperty(); | |
| 2856 if (fni_ != NULL) { | |
| 2857 // Check if the right hand side is a call to avoid inferring a | |
| 2858 // name if we're dealing with "this.a = function(){...}();"-like | |
| 2859 // expression. | |
| 2860 if (!right->IsCall() && !right->IsCallNew()) { | |
| 2861 fni_->Infer(); | |
| 2862 } else { | |
| 2863 fni_->RemoveLastFunction(); | |
| 2864 } | |
| 2865 fni_->Leave(); | |
| 2866 } | |
| 2867 | |
| 2868 if (function_state_->return_location().IsValid()) { | |
| 2869 ReportMessageAt(function_state_->return_location(), | |
| 2870 "strong_constructor_return_misplaced"); | |
| 2871 *ok = false; | |
| 2872 return this->EmptyExpression(); | |
| 2873 } | |
| 2874 | |
| 2875 return factory()->NewAssignment(Token::ASSIGN, left, right, pos); | |
| 2876 } | |
| 2877 | |
| 2878 | |
| 2879 template <class Traits> | |
| 2880 typename ParserBase<Traits>::ExpressionT | |
| 2881 ParserBase<Traits>::ParseStrongSuperCallExpression(bool* ok) { | |
| 2882 // SuperCallExpression :: (strong mode) | |
| 2883 // 'super' '(' ExpressionList ')' | |
| 2884 | |
| 2885 Consume(Token::SUPER); | |
| 2886 int pos = position(); | |
| 2887 Scanner::Location super_loc = scanner()->location(); | |
| 2888 ExpressionT expr = this->SuperReference(scope_, factory()); | |
| 2889 | |
| 2890 if (peek() != Token::LPAREN) { | |
| 2891 ReportMessage("strong_constructor_super"); | |
| 2892 *ok = false; | |
| 2893 return this->EmptyExpression(); | |
| 2894 } | |
| 2895 | |
| 2896 typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK); | |
| 2897 | |
| 2898 // TODO(rossberg): This doesn't work with arrow functions yet. | |
| 2899 if (!IsSubclassConstructor(function_state_->kind())) { | |
| 2900 ReportMessage("unexpected_super"); | |
| 2901 *ok = false; | |
| 2902 return this->EmptyExpression(); | |
| 2903 } else if (function_state_->super_location().IsValid()) { | |
| 2904 ReportMessageAt(scanner()->location(), "strong_super_call_duplicate"); | |
| 2905 *ok = false; | |
| 2906 return this->EmptyExpression(); | |
| 2907 } else if (function_state_->this_location().IsValid()) { | |
| 2908 ReportMessageAt(scanner()->location(), "strong_super_call_misplaced"); | |
| 2909 *ok = false; | |
| 2910 return this->EmptyExpression(); | |
| 2911 } else if (function_state_->return_location().IsValid()) { | |
| 2912 ReportMessageAt(function_state_->return_location(), | |
| 2913 "strong_constructor_return_misplaced"); | |
| 2914 *ok = false; | |
| 2915 return this->EmptyExpression(); | |
| 2916 } | |
| 2917 | |
| 2918 function_state_->set_super_location(super_loc); | |
| 2919 return factory()->NewCall(expr, args, pos); | |
| 2920 } | |
| 2921 | |
| 2922 | |
| 2923 template <class Traits> | |
| 2924 typename ParserBase<Traits>::ExpressionT | |
| 2788 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { | 2925 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { |
| 2789 Expect(Token::SUPER, CHECK_OK); | 2926 Expect(Token::SUPER, CHECK_OK); |
| 2790 | 2927 |
| 2928 // TODO(aperez): Does this actually work with lazily compiled arrows? | |
|
marja
2015/04/21 09:01:37
-> wingo, since he took over?
rossberg
2015/04/21 09:47:47
Done.
| |
| 2791 FunctionState* function_state = function_state_; | 2929 FunctionState* function_state = function_state_; |
| 2792 while (IsArrowFunction(function_state->kind())) { | 2930 while (IsArrowFunction(function_state->kind())) { |
| 2793 function_state = function_state->outer(); | 2931 function_state = function_state->outer(); |
| 2794 } | 2932 } |
| 2795 // TODO(arv): Handle eval scopes similarly. | 2933 // TODO(arv): Handle eval scopes similarly. |
| 2796 | 2934 |
| 2797 FunctionKind kind = function_state->kind(); | 2935 FunctionKind kind = function_state->kind(); |
| 2798 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || | 2936 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
| 2799 i::IsConstructor(kind)) { | 2937 i::IsConstructor(kind)) { |
| 2800 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { | 2938 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
| 2801 scope_->RecordSuperPropertyUsage(); | 2939 scope_->RecordSuperPropertyUsage(); |
| 2802 return this->SuperReference(scope_, factory()); | 2940 return this->SuperReference(scope_, factory()); |
| 2803 } | 2941 } |
| 2804 // new super() is never allowed. | 2942 // new super() is never allowed. |
| 2805 // super() is only allowed in derived constructor | 2943 // super() is only allowed in derived constructor |
| 2806 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { | 2944 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { |
| 2807 if (is_strong(language_mode())) { | 2945 if (is_strong(language_mode())) { |
| 2808 if (function_state->super_call_location().IsValid()) { | 2946 // Super calls in strong mode are parsed separately. |
| 2809 ReportMessageAt(scanner()->location(), "strong_super_call_duplicate"); | 2947 ReportMessageAt(scanner()->location(), "strong_constructor_super"); |
| 2810 *ok = false; | 2948 *ok = false; |
| 2811 return this->EmptyExpression(); | 2949 return this->EmptyExpression(); |
| 2812 } else if (function_state->return_location().IsValid()) { | |
| 2813 ReportMessageAt(function_state->return_location(), | |
| 2814 "strong_constructor_return_misplaced"); | |
| 2815 *ok = false; | |
| 2816 return this->EmptyExpression(); | |
| 2817 } | |
| 2818 } | 2950 } |
| 2819 function_state->set_super_call_location(scanner()->location()); | 2951 function_state->set_super_location(scanner()->location()); |
| 2820 return this->SuperReference(scope_, factory()); | 2952 return this->SuperReference(scope_, factory()); |
| 2821 } | 2953 } |
| 2822 } | 2954 } |
| 2823 | 2955 |
| 2824 ReportMessageAt(scanner()->location(), "unexpected_super"); | 2956 ReportMessageAt(scanner()->location(), "unexpected_super"); |
| 2825 *ok = false; | 2957 *ok = false; |
| 2826 return this->EmptyExpression(); | 2958 return this->EmptyExpression(); |
| 2827 } | 2959 } |
| 2828 | 2960 |
| 2829 | 2961 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2928 | 3060 |
| 2929 Expect(Token::ARROW, CHECK_OK); | 3061 Expect(Token::ARROW, CHECK_OK); |
| 2930 | 3062 |
| 2931 if (peek() == Token::LBRACE) { | 3063 if (peek() == Token::LBRACE) { |
| 2932 // Multiple statemente body | 3064 // Multiple statemente body |
| 2933 Consume(Token::LBRACE); | 3065 Consume(Token::LBRACE); |
| 2934 bool is_lazily_parsed = | 3066 bool is_lazily_parsed = |
| 2935 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); | 3067 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
| 2936 if (is_lazily_parsed) { | 3068 if (is_lazily_parsed) { |
| 2937 body = this->NewStatementList(0, zone()); | 3069 body = this->NewStatementList(0, zone()); |
| 2938 this->SkipLazyFunctionBody(this->EmptyIdentifier(), | 3070 this->SkipLazyFunctionBody(&materialized_literal_count, |
| 2939 &materialized_literal_count, | |
| 2940 &expected_property_count, CHECK_OK); | 3071 &expected_property_count, CHECK_OK); |
| 2941 } else { | 3072 } else { |
| 2942 body = this->ParseEagerFunctionBody( | 3073 body = this->ParseEagerFunctionBody( |
| 2943 this->EmptyIdentifier(), RelocInfo::kNoPosition, NULL, | 3074 this->EmptyIdentifier(), RelocInfo::kNoPosition, NULL, |
| 2944 Token::INIT_VAR, kArrowFunction, CHECK_OK); | 3075 Token::INIT_VAR, kArrowFunction, CHECK_OK); |
| 2945 materialized_literal_count = | 3076 materialized_literal_count = |
| 2946 function_state.materialized_literal_count(); | 3077 function_state.materialized_literal_count(); |
| 2947 expected_property_count = function_state.expected_property_count(); | 3078 expected_property_count = function_state.expected_property_count(); |
| 2948 handler_count = function_state.handler_count(); | 3079 handler_count = function_state.handler_count(); |
| 2949 } | 3080 } |
| 2950 } else { | 3081 } else { |
| 2951 // Single-expression body | 3082 // Single-expression body |
| 2952 int pos = position(); | 3083 int pos = position(); |
| 2953 parenthesized_function_ = false; | 3084 parenthesized_function_ = false; |
| 2954 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); | 3085 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); |
| 2955 body = this->NewStatementList(1, zone()); | 3086 body = this->NewStatementList(1, zone()); |
| 2956 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3087 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
| 2957 materialized_literal_count = function_state.materialized_literal_count(); | 3088 materialized_literal_count = function_state.materialized_literal_count(); |
| 2958 expected_property_count = function_state.expected_property_count(); | 3089 expected_property_count = function_state.expected_property_count(); |
| 2959 handler_count = function_state.handler_count(); | 3090 handler_count = function_state.handler_count(); |
| 2960 } | 3091 } |
| 2961 super_loc = function_state.super_call_location(); | 3092 super_loc = function_state.super_location(); |
| 2962 | 3093 |
| 2963 scope->set_start_position(start_pos); | 3094 scope->set_start_position(start_pos); |
| 2964 scope->set_end_position(scanner()->location().end_pos); | 3095 scope->set_end_position(scanner()->location().end_pos); |
| 2965 | 3096 |
| 2966 // Arrow function *parameter lists* are always checked as in strict mode. | 3097 // Arrow function *parameter lists* are always checked as in strict mode. |
| 2967 // TODO(arv): eval_args_error_loc and reserved_loc needs to be set by | 3098 // TODO(arv): eval_args_error_loc and reserved_loc needs to be set by |
| 2968 // DeclareArrowParametersFromExpression. | 3099 // DeclareArrowParametersFromExpression. |
| 2969 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); | 3100 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); |
| 2970 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 3101 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 2971 const bool use_strict_params = true; | 3102 const bool use_strict_params = true; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2982 | 3113 |
| 2983 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3114 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| 2984 this->EmptyIdentifierString(), ast_value_factory(), scope, body, | 3115 this->EmptyIdentifierString(), ast_value_factory(), scope, body, |
| 2985 materialized_literal_count, expected_property_count, handler_count, | 3116 materialized_literal_count, expected_property_count, handler_count, |
| 2986 num_parameters, FunctionLiteral::kNoDuplicateParameters, | 3117 num_parameters, FunctionLiteral::kNoDuplicateParameters, |
| 2987 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, | 3118 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, |
| 2988 FunctionLiteral::kNotParenthesized, FunctionKind::kArrowFunction, | 3119 FunctionLiteral::kNotParenthesized, FunctionKind::kArrowFunction, |
| 2989 start_pos); | 3120 start_pos); |
| 2990 | 3121 |
| 2991 function_literal->set_function_token_position(start_pos); | 3122 function_literal->set_function_token_position(start_pos); |
| 2992 if (super_loc.IsValid()) function_state_->set_super_call_location(super_loc); | 3123 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); |
| 2993 | 3124 |
| 2994 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | 3125 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); |
| 2995 | 3126 |
| 2996 return function_literal; | 3127 return function_literal; |
| 2997 } | 3128 } |
| 2998 | 3129 |
| 2999 | 3130 |
| 3000 template <typename Traits> | 3131 template <typename Traits> |
| 3001 typename ParserBase<Traits>::ExpressionT | 3132 typename ParserBase<Traits>::ExpressionT |
| 3002 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) { | 3133 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) { |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3167 *ok = false; | 3298 *ok = false; |
| 3168 return; | 3299 return; |
| 3169 } | 3300 } |
| 3170 has_seen_constructor_ = true; | 3301 has_seen_constructor_ = true; |
| 3171 return; | 3302 return; |
| 3172 } | 3303 } |
| 3173 } | 3304 } |
| 3174 } } // v8::internal | 3305 } } // v8::internal |
| 3175 | 3306 |
| 3176 #endif // V8_PREPARSER_H | 3307 #endif // V8_PREPARSER_H |
| OLD | NEW |