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 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 int materialized_literal_count() { | 226 int materialized_literal_count() { |
227 return next_materialized_literal_index_; | 227 return next_materialized_literal_index_; |
228 } | 228 } |
229 | 229 |
230 int NextHandlerIndex() { return next_handler_index_++; } | 230 int NextHandlerIndex() { return next_handler_index_++; } |
231 int handler_count() { return next_handler_index_; } | 231 int handler_count() { return next_handler_index_; } |
232 | 232 |
233 void AddProperty() { expected_property_count_++; } | 233 void AddProperty() { expected_property_count_++; } |
234 int expected_property_count() { return expected_property_count_; } | 234 int expected_property_count() { return expected_property_count_; } |
235 | 235 |
236 Scanner::Location this_location() const { return this_location_; } | |
237 Scanner::Location super_location() const { return super_location_; } | |
238 Scanner::Location return_location() const { return return_location_; } | 236 Scanner::Location return_location() const { return return_location_; } |
239 void set_this_location(Scanner::Location location) { | 237 Scanner::Location super_call_location() const { |
240 this_location_ = location; | 238 return super_call_location_; |
241 } | |
242 void set_super_location(Scanner::Location location) { | |
243 super_location_ = location; | |
244 } | 239 } |
245 void set_return_location(Scanner::Location location) { | 240 void set_return_location(Scanner::Location location) { |
246 return_location_ = location; | 241 return_location_ = location; |
247 } | 242 } |
| 243 void set_super_call_location(Scanner::Location location) { |
| 244 super_call_location_ = location; |
| 245 } |
248 | 246 |
249 bool is_generator() const { return IsGeneratorFunction(kind_); } | 247 bool is_generator() const { return IsGeneratorFunction(kind_); } |
250 | 248 |
251 FunctionKind kind() const { return kind_; } | 249 FunctionKind kind() const { return kind_; } |
252 FunctionState* outer() const { return outer_function_state_; } | 250 FunctionState* outer() const { return outer_function_state_; } |
253 | 251 |
254 void set_generator_object_variable( | 252 void set_generator_object_variable( |
255 typename Traits::Type::GeneratorVariable* variable) { | 253 typename Traits::Type::GeneratorVariable* variable) { |
256 DCHECK(variable != NULL); | 254 DCHECK(variable != NULL); |
257 DCHECK(is_generator()); | 255 DCHECK(is_generator()); |
(...skipping 11 matching lines...) Expand all Loading... |
269 // the function. Includes regexp literals, and boilerplate for object and | 267 // the function. Includes regexp literals, and boilerplate for object and |
270 // array literals. | 268 // array literals. |
271 int next_materialized_literal_index_; | 269 int next_materialized_literal_index_; |
272 | 270 |
273 // Used to assign a per-function index to try and catch handlers. | 271 // Used to assign a per-function index to try and catch handlers. |
274 int next_handler_index_; | 272 int next_handler_index_; |
275 | 273 |
276 // Properties count estimation. | 274 // Properties count estimation. |
277 int expected_property_count_; | 275 int expected_property_count_; |
278 | 276 |
279 // Location of most recent use of 'this' (invalid if none). | |
280 Scanner::Location this_location_; | |
281 | |
282 // Location of most recent 'return' statement (invalid if none). | 277 // Location of most recent 'return' statement (invalid if none). |
283 Scanner::Location return_location_; | 278 Scanner::Location return_location_; |
284 | 279 |
285 // Location of call to the "super" constructor (invalid if none). | 280 // Location of call to the "super" constructor (invalid if none). |
286 Scanner::Location super_location_; | 281 Scanner::Location super_call_location_; |
287 | 282 |
288 FunctionKind kind_; | 283 FunctionKind kind_; |
289 // For generators, this variable may hold the generator object. It variable | 284 // For generators, this variable may hold the generator object. It variable |
290 // is used by yield expressions and return statements. It is not necessary | 285 // is used by yield expressions and return statements. It is not necessary |
291 // for generator functions to have this variable set. | 286 // for generator functions to have this variable set. |
292 Variable* generator_object_variable_; | 287 Variable* generator_object_variable_; |
293 | 288 |
294 FunctionState** function_state_stack_; | 289 FunctionState** function_state_stack_; |
295 FunctionState* outer_function_state_; | 290 FunctionState* outer_function_state_; |
296 Scope** scope_stack_; | 291 Scope** scope_stack_; |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 620 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
626 ExpressionT ParseMemberExpression(bool* ok); | 621 ExpressionT ParseMemberExpression(bool* ok); |
627 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 622 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
628 bool* ok); | 623 bool* ok); |
629 ExpressionT ParseArrowFunctionLiteral( | 624 ExpressionT ParseArrowFunctionLiteral( |
630 Scope* function_scope, const FormalParameterErrorLocations& error_locs, | 625 Scope* function_scope, const FormalParameterErrorLocations& error_locs, |
631 bool has_rest, bool* ok); | 626 bool has_rest, bool* ok); |
632 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 627 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
633 void AddTemplateExpression(ExpressionT); | 628 void AddTemplateExpression(ExpressionT); |
634 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 629 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
635 ExpressionT ParseStrongInitializationExpression(bool* ok); | |
636 ExpressionT ParseStrongSuperCallExpression(bool* ok); | |
637 | 630 |
638 void ParseFormalParameter(FormalParameterScopeT* scope, | 631 void ParseFormalParameter(FormalParameterScopeT* scope, |
639 FormalParameterErrorLocations* locs, bool is_rest, | 632 FormalParameterErrorLocations* locs, bool is_rest, |
640 bool* ok); | 633 bool* ok); |
641 int ParseFormalParameterList(FormalParameterScopeT* scope, | 634 int ParseFormalParameterList(FormalParameterScopeT* scope, |
642 FormalParameterErrorLocations* locs, | 635 FormalParameterErrorLocations* locs, |
643 bool* has_rest, bool* ok); | 636 bool* has_rest, bool* ok); |
644 void CheckArityRestrictions( | 637 void CheckArityRestrictions( |
645 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | 638 int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
646 int formals_start_pos, int formals_end_pos, bool* ok); | 639 int formals_start_pos, int formals_end_pos, bool* ok); |
(...skipping 901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 } | 1541 } |
1549 | 1542 |
1550 static PreParserStatementList NewStatementList(int size, Zone* zone) { | 1543 static PreParserStatementList NewStatementList(int size, Zone* zone) { |
1551 return PreParserStatementList(); | 1544 return PreParserStatementList(); |
1552 } | 1545 } |
1553 | 1546 |
1554 static PreParserExpressionList NewPropertyList(int size, Zone* zone) { | 1547 static PreParserExpressionList NewPropertyList(int size, Zone* zone) { |
1555 return PreParserExpressionList(); | 1548 return PreParserExpressionList(); |
1556 } | 1549 } |
1557 | 1550 |
1558 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count, | 1551 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, |
| 1552 int* materialized_literal_count, |
1559 int* expected_property_count, bool* ok) { | 1553 int* expected_property_count, bool* ok) { |
1560 UNREACHABLE(); | 1554 UNREACHABLE(); |
1561 } | 1555 } |
1562 | 1556 |
1563 V8_INLINE PreParserStatementList | 1557 V8_INLINE PreParserStatementList |
1564 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1558 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
1565 Variable* fvar, Token::Value fvar_init_op, | 1559 Variable* fvar, Token::Value fvar_init_op, |
1566 FunctionKind kind, bool* ok); | 1560 FunctionKind kind, bool* ok); |
1567 | 1561 |
1568 V8_INLINE void ParseArrowFunctionFormalParameters( | 1562 V8_INLINE void ParseArrowFunctionFormalParameters( |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1731 Statement ParseDoWhileStatement(bool* ok); | 1725 Statement ParseDoWhileStatement(bool* ok); |
1732 Statement ParseWhileStatement(bool* ok); | 1726 Statement ParseWhileStatement(bool* ok); |
1733 Statement ParseForStatement(bool* ok); | 1727 Statement ParseForStatement(bool* ok); |
1734 Statement ParseThrowStatement(bool* ok); | 1728 Statement ParseThrowStatement(bool* ok); |
1735 Statement ParseTryStatement(bool* ok); | 1729 Statement ParseTryStatement(bool* ok); |
1736 Statement ParseDebuggerStatement(bool* ok); | 1730 Statement ParseDebuggerStatement(bool* ok); |
1737 Expression ParseConditionalExpression(bool accept_IN, bool* ok); | 1731 Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
1738 Expression ParseObjectLiteral(bool* ok); | 1732 Expression ParseObjectLiteral(bool* ok); |
1739 Expression ParseV8Intrinsic(bool* ok); | 1733 Expression ParseV8Intrinsic(bool* ok); |
1740 | 1734 |
1741 V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count, | 1735 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name, |
| 1736 int* materialized_literal_count, |
1742 int* expected_property_count, bool* ok); | 1737 int* expected_property_count, bool* ok); |
1743 V8_INLINE PreParserStatementList | 1738 V8_INLINE PreParserStatementList |
1744 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, | 1739 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos, |
1745 Variable* fvar, Token::Value fvar_init_op, | 1740 Variable* fvar, Token::Value fvar_init_op, |
1746 FunctionKind kind, bool* ok); | 1741 FunctionKind kind, bool* ok); |
1747 | 1742 |
1748 Expression ParseFunctionLiteral( | 1743 Expression ParseFunctionLiteral( |
1749 Identifier name, Scanner::Location function_name_location, | 1744 Identifier name, Scanner::Location function_name_location, |
1750 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, | 1745 bool name_is_strict_reserved, FunctionKind kind, int function_token_pos, |
1751 FunctionLiteral::FunctionType function_type, | 1746 FunctionLiteral::FunctionType function_type, |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1827 } | 1822 } |
1828 | 1823 |
1829 | 1824 |
1830 template <class Traits> | 1825 template <class Traits> |
1831 ParserBase<Traits>::FunctionState::FunctionState( | 1826 ParserBase<Traits>::FunctionState::FunctionState( |
1832 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, | 1827 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, |
1833 FunctionKind kind, typename Traits::Type::Factory* factory) | 1828 FunctionKind kind, typename Traits::Type::Factory* factory) |
1834 : next_materialized_literal_index_(0), | 1829 : next_materialized_literal_index_(0), |
1835 next_handler_index_(0), | 1830 next_handler_index_(0), |
1836 expected_property_count_(0), | 1831 expected_property_count_(0), |
1837 this_location_(Scanner::Location::invalid()), | |
1838 return_location_(Scanner::Location::invalid()), | 1832 return_location_(Scanner::Location::invalid()), |
1839 super_location_(Scanner::Location::invalid()), | 1833 super_call_location_(Scanner::Location::invalid()), |
1840 kind_(kind), | 1834 kind_(kind), |
1841 generator_object_variable_(NULL), | 1835 generator_object_variable_(NULL), |
1842 function_state_stack_(function_state_stack), | 1836 function_state_stack_(function_state_stack), |
1843 outer_function_state_(*function_state_stack), | 1837 outer_function_state_(*function_state_stack), |
1844 scope_stack_(scope_stack), | 1838 scope_stack_(scope_stack), |
1845 outer_scope_(*scope_stack), | 1839 outer_scope_(*scope_stack), |
1846 factory_(factory) { | 1840 factory_(factory) { |
1847 *scope_stack_ = scope; | 1841 *scope_stack_ = scope; |
1848 *function_state_stack = this; | 1842 *function_state_stack = this; |
1849 } | 1843 } |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2044 // '(' Expression ')' | 2038 // '(' Expression ')' |
2045 // TemplateLiteral | 2039 // TemplateLiteral |
2046 | 2040 |
2047 int beg_pos = scanner()->peek_location().beg_pos; | 2041 int beg_pos = scanner()->peek_location().beg_pos; |
2048 int end_pos = scanner()->peek_location().end_pos; | 2042 int end_pos = scanner()->peek_location().end_pos; |
2049 ExpressionT result = this->EmptyExpression(); | 2043 ExpressionT result = this->EmptyExpression(); |
2050 Token::Value token = peek(); | 2044 Token::Value token = peek(); |
2051 switch (token) { | 2045 switch (token) { |
2052 case Token::THIS: { | 2046 case Token::THIS: { |
2053 Consume(Token::THIS); | 2047 Consume(Token::THIS); |
2054 if (is_strong(language_mode())) { | |
2055 // Constructors' usages of 'this' in strong mode are parsed separately. | |
2056 // TODO(rossberg): this does not work with arrow functions yet. | |
2057 if (i::IsConstructor(function_state_->kind())) { | |
2058 ReportMessage("strong_constructor_this"); | |
2059 *ok = false; | |
2060 break; | |
2061 } | |
2062 } | |
2063 scope_->RecordThisUsage(); | 2048 scope_->RecordThisUsage(); |
2064 result = this->ThisExpression(scope_, factory(), beg_pos); | 2049 result = this->ThisExpression(scope_, factory(), beg_pos); |
2065 break; | 2050 break; |
2066 } | 2051 } |
2067 | 2052 |
2068 case Token::NULL_LITERAL: | 2053 case Token::NULL_LITERAL: |
2069 case Token::TRUE_LITERAL: | 2054 case Token::TRUE_LITERAL: |
2070 case Token::FALSE_LITERAL: | 2055 case Token::FALSE_LITERAL: |
2071 case Token::SMI: | 2056 case Token::SMI: |
2072 case Token::NUMBER: | 2057 case Token::NUMBER: |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2125 parenthesized_function_ = (peek() == Token::FUNCTION); | 2110 parenthesized_function_ = (peek() == Token::FUNCTION); |
2126 result = this->ParseExpression(true, CHECK_OK); | 2111 result = this->ParseExpression(true, CHECK_OK); |
2127 result->increase_parenthesization_level(); | 2112 result->increase_parenthesization_level(); |
2128 Expect(Token::RPAREN, CHECK_OK); | 2113 Expect(Token::RPAREN, CHECK_OK); |
2129 } | 2114 } |
2130 break; | 2115 break; |
2131 | 2116 |
2132 case Token::CLASS: { | 2117 case Token::CLASS: { |
2133 Consume(Token::CLASS); | 2118 Consume(Token::CLASS); |
2134 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { | 2119 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { |
2135 ReportMessage("sloppy_lexical"); | 2120 ReportMessage("sloppy_lexical", NULL); |
2136 *ok = false; | 2121 *ok = false; |
2137 break; | 2122 break; |
2138 } | 2123 } |
2139 int class_token_position = position(); | 2124 int class_token_position = position(); |
2140 IdentifierT name = this->EmptyIdentifier(); | 2125 IdentifierT name = this->EmptyIdentifier(); |
2141 bool is_strict_reserved_name = false; | 2126 bool is_strict_reserved_name = false; |
2142 Scanner::Location class_name_location = Scanner::Location::invalid(); | 2127 Scanner::Location class_name_location = Scanner::Location::invalid(); |
2143 if (peek_any_identifier()) { | 2128 if (peek_any_identifier()) { |
2144 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 2129 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
2145 CHECK_OK); | 2130 CHECK_OK); |
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3013 result = ParsePrimaryExpression(CHECK_OK); | 2998 result = ParsePrimaryExpression(CHECK_OK); |
3014 } | 2999 } |
3015 | 3000 |
3016 result = ParseMemberExpressionContinuation(result, CHECK_OK); | 3001 result = ParseMemberExpressionContinuation(result, CHECK_OK); |
3017 return result; | 3002 return result; |
3018 } | 3003 } |
3019 | 3004 |
3020 | 3005 |
3021 template <class Traits> | 3006 template <class Traits> |
3022 typename ParserBase<Traits>::ExpressionT | 3007 typename ParserBase<Traits>::ExpressionT |
3023 ParserBase<Traits>::ParseStrongInitializationExpression(bool* ok) { | |
3024 // InitializationExpression :: (strong mode) | |
3025 // 'this' '.' IdentifierName '=' AssignmentExpression | |
3026 // 'this' '[' Expression ']' '=' AssignmentExpression | |
3027 | |
3028 if (fni_ != NULL) fni_->Enter(); | |
3029 | |
3030 Consume(Token::THIS); | |
3031 int pos = position(); | |
3032 function_state_->set_this_location(scanner()->location()); | |
3033 scope_->RecordThisUsage(); | |
3034 ExpressionT this_expr = this->ThisExpression(scope_, factory(), pos); | |
3035 | |
3036 ExpressionT left = this->EmptyExpression(); | |
3037 switch (peek()) { | |
3038 case Token::LBRACK: { | |
3039 Consume(Token::LBRACK); | |
3040 int pos = position(); | |
3041 ExpressionT index = this->ParseExpression(true, CHECK_OK); | |
3042 left = factory()->NewProperty(this_expr, index, pos); | |
3043 if (fni_ != NULL) { | |
3044 this->PushPropertyName(fni_, index); | |
3045 } | |
3046 Expect(Token::RBRACK, CHECK_OK); | |
3047 break; | |
3048 } | |
3049 case Token::PERIOD: { | |
3050 Consume(Token::PERIOD); | |
3051 int pos = position(); | |
3052 IdentifierT name = ParseIdentifierName(CHECK_OK); | |
3053 left = factory()->NewProperty( | |
3054 this_expr, factory()->NewStringLiteral(name, pos), pos); | |
3055 if (fni_ != NULL) { | |
3056 this->PushLiteralName(fni_, name); | |
3057 } | |
3058 break; | |
3059 } | |
3060 default: | |
3061 ReportMessage("strong_constructor_this"); | |
3062 *ok = false; | |
3063 return this->EmptyExpression(); | |
3064 } | |
3065 | |
3066 if (peek() != Token::ASSIGN) { | |
3067 ReportMessageAt(function_state_->this_location(), | |
3068 "strong_constructor_this"); | |
3069 *ok = false; | |
3070 return this->EmptyExpression(); | |
3071 } | |
3072 Consume(Token::ASSIGN); | |
3073 left = this->MarkExpressionAsAssigned(left); | |
3074 | |
3075 ExpressionT right = this->ParseAssignmentExpression(true, CHECK_OK); | |
3076 this->CheckAssigningFunctionLiteralToProperty(left, right); | |
3077 function_state_->AddProperty(); | |
3078 if (fni_ != NULL) { | |
3079 // Check if the right hand side is a call to avoid inferring a | |
3080 // name if we're dealing with "this.a = function(){...}();"-like | |
3081 // expression. | |
3082 if (!right->IsCall() && !right->IsCallNew()) { | |
3083 fni_->Infer(); | |
3084 } else { | |
3085 fni_->RemoveLastFunction(); | |
3086 } | |
3087 fni_->Leave(); | |
3088 } | |
3089 | |
3090 if (function_state_->return_location().IsValid()) { | |
3091 ReportMessageAt(function_state_->return_location(), | |
3092 "strong_constructor_return_misplaced"); | |
3093 *ok = false; | |
3094 return this->EmptyExpression(); | |
3095 } | |
3096 | |
3097 return factory()->NewAssignment(Token::ASSIGN, left, right, pos); | |
3098 } | |
3099 | |
3100 | |
3101 template <class Traits> | |
3102 typename ParserBase<Traits>::ExpressionT | |
3103 ParserBase<Traits>::ParseStrongSuperCallExpression(bool* ok) { | |
3104 // SuperCallExpression :: (strong mode) | |
3105 // 'super' '(' ExpressionList ')' | |
3106 | |
3107 Consume(Token::SUPER); | |
3108 int pos = position(); | |
3109 Scanner::Location super_loc = scanner()->location(); | |
3110 ExpressionT expr = this->SuperReference(scope_, factory()); | |
3111 | |
3112 if (peek() != Token::LPAREN) { | |
3113 ReportMessage("strong_constructor_super"); | |
3114 *ok = false; | |
3115 return this->EmptyExpression(); | |
3116 } | |
3117 | |
3118 Scanner::Location spread_pos; | |
3119 typename Traits::Type::ExpressionList args = | |
3120 ParseArguments(&spread_pos, CHECK_OK); | |
3121 | |
3122 // TODO(rossberg): This doesn't work with arrow functions yet. | |
3123 if (!IsSubclassConstructor(function_state_->kind())) { | |
3124 ReportMessage("unexpected_super"); | |
3125 *ok = false; | |
3126 return this->EmptyExpression(); | |
3127 } else if (function_state_->super_location().IsValid()) { | |
3128 ReportMessageAt(scanner()->location(), "strong_super_call_duplicate"); | |
3129 *ok = false; | |
3130 return this->EmptyExpression(); | |
3131 } else if (function_state_->this_location().IsValid()) { | |
3132 ReportMessageAt(scanner()->location(), "strong_super_call_misplaced"); | |
3133 *ok = false; | |
3134 return this->EmptyExpression(); | |
3135 } else if (function_state_->return_location().IsValid()) { | |
3136 ReportMessageAt(function_state_->return_location(), | |
3137 "strong_constructor_return_misplaced"); | |
3138 *ok = false; | |
3139 return this->EmptyExpression(); | |
3140 } | |
3141 | |
3142 function_state_->set_super_location(super_loc); | |
3143 if (spread_pos.IsValid()) { | |
3144 args = Traits::PrepareSpreadArguments(args); | |
3145 return Traits::SpreadCall(expr, args, pos); | |
3146 } else { | |
3147 return factory()->NewCall(expr, args, pos); | |
3148 } | |
3149 } | |
3150 | |
3151 | |
3152 template <class Traits> | |
3153 typename ParserBase<Traits>::ExpressionT | |
3154 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { | 3008 ParserBase<Traits>::ParseSuperExpression(bool is_new, bool* ok) { |
3155 Expect(Token::SUPER, CHECK_OK); | 3009 Expect(Token::SUPER, CHECK_OK); |
3156 | 3010 |
3157 // TODO(wingo): Does this actually work with lazily compiled arrows? | |
3158 FunctionState* function_state = function_state_; | 3011 FunctionState* function_state = function_state_; |
3159 while (IsArrowFunction(function_state->kind())) { | 3012 while (IsArrowFunction(function_state->kind())) { |
3160 function_state = function_state->outer(); | 3013 function_state = function_state->outer(); |
3161 } | 3014 } |
3162 // TODO(arv): Handle eval scopes similarly. | 3015 // TODO(arv): Handle eval scopes similarly. |
3163 | 3016 |
3164 FunctionKind kind = function_state->kind(); | 3017 FunctionKind kind = function_state->kind(); |
3165 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || | 3018 if (IsConciseMethod(kind) || IsAccessorFunction(kind) || |
3166 i::IsConstructor(kind)) { | 3019 i::IsConstructor(kind)) { |
3167 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { | 3020 if (peek() == Token::PERIOD || peek() == Token::LBRACK) { |
3168 scope_->RecordSuperPropertyUsage(); | 3021 scope_->RecordSuperPropertyUsage(); |
3169 return this->SuperReference(scope_, factory()); | 3022 return this->SuperReference(scope_, factory()); |
3170 } | 3023 } |
3171 // new super() is never allowed. | 3024 // new super() is never allowed. |
3172 // super() is only allowed in derived constructor | 3025 // super() is only allowed in derived constructor |
3173 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { | 3026 if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) { |
3174 if (is_strong(language_mode())) { | 3027 if (is_strong(language_mode())) { |
3175 // Super calls in strong mode are parsed separately. | 3028 if (function_state->super_call_location().IsValid()) { |
3176 ReportMessageAt(scanner()->location(), "strong_constructor_super"); | 3029 ReportMessageAt(scanner()->location(), "strong_super_call_duplicate"); |
3177 *ok = false; | 3030 *ok = false; |
3178 return this->EmptyExpression(); | 3031 return this->EmptyExpression(); |
| 3032 } else if (function_state->return_location().IsValid()) { |
| 3033 ReportMessageAt(function_state->return_location(), |
| 3034 "strong_constructor_return_misplaced"); |
| 3035 *ok = false; |
| 3036 return this->EmptyExpression(); |
| 3037 } |
3179 } | 3038 } |
3180 function_state->set_super_location(scanner()->location()); | 3039 function_state->set_super_call_location(scanner()->location()); |
3181 return this->SuperReference(scope_, factory()); | 3040 return this->SuperReference(scope_, factory()); |
3182 } | 3041 } |
3183 } | 3042 } |
3184 | 3043 |
3185 ReportMessageAt(scanner()->location(), "unexpected_super"); | 3044 ReportMessageAt(scanner()->location(), "unexpected_super"); |
3186 *ok = false; | 3045 *ok = false; |
3187 return this->EmptyExpression(); | 3046 return this->EmptyExpression(); |
3188 } | 3047 } |
3189 | 3048 |
3190 | 3049 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3367 | 3226 |
3368 Expect(Token::ARROW, CHECK_OK); | 3227 Expect(Token::ARROW, CHECK_OK); |
3369 | 3228 |
3370 if (peek() == Token::LBRACE) { | 3229 if (peek() == Token::LBRACE) { |
3371 // Multiple statement body | 3230 // Multiple statement body |
3372 Consume(Token::LBRACE); | 3231 Consume(Token::LBRACE); |
3373 bool is_lazily_parsed = | 3232 bool is_lazily_parsed = |
3374 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); | 3233 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation()); |
3375 if (is_lazily_parsed) { | 3234 if (is_lazily_parsed) { |
3376 body = this->NewStatementList(0, zone()); | 3235 body = this->NewStatementList(0, zone()); |
3377 this->SkipLazyFunctionBody(&materialized_literal_count, | 3236 this->SkipLazyFunctionBody(this->EmptyIdentifier(), |
| 3237 &materialized_literal_count, |
3378 &expected_property_count, CHECK_OK); | 3238 &expected_property_count, CHECK_OK); |
3379 } else { | 3239 } else { |
3380 body = this->ParseEagerFunctionBody( | 3240 body = this->ParseEagerFunctionBody( |
3381 this->EmptyIdentifier(), RelocInfo::kNoPosition, NULL, | 3241 this->EmptyIdentifier(), RelocInfo::kNoPosition, NULL, |
3382 Token::INIT_VAR, kArrowFunction, CHECK_OK); | 3242 Token::INIT_VAR, kArrowFunction, CHECK_OK); |
3383 materialized_literal_count = | 3243 materialized_literal_count = |
3384 function_state.materialized_literal_count(); | 3244 function_state.materialized_literal_count(); |
3385 expected_property_count = function_state.expected_property_count(); | 3245 expected_property_count = function_state.expected_property_count(); |
3386 handler_count = function_state.handler_count(); | 3246 handler_count = function_state.handler_count(); |
3387 } | 3247 } |
3388 } else { | 3248 } else { |
3389 // Single-expression body | 3249 // Single-expression body |
3390 int pos = position(); | 3250 int pos = position(); |
3391 parenthesized_function_ = false; | 3251 parenthesized_function_ = false; |
3392 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); | 3252 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); |
3393 body = this->NewStatementList(1, zone()); | 3253 body = this->NewStatementList(1, zone()); |
3394 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3254 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
3395 materialized_literal_count = function_state.materialized_literal_count(); | 3255 materialized_literal_count = function_state.materialized_literal_count(); |
3396 expected_property_count = function_state.expected_property_count(); | 3256 expected_property_count = function_state.expected_property_count(); |
3397 handler_count = function_state.handler_count(); | 3257 handler_count = function_state.handler_count(); |
3398 } | 3258 } |
3399 super_loc = function_state.super_location(); | 3259 super_loc = function_state.super_call_location(); |
3400 | 3260 |
3401 scope->set_end_position(scanner()->location().end_pos); | 3261 scope->set_end_position(scanner()->location().end_pos); |
3402 | 3262 |
3403 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3263 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
3404 // which is not the same as "parameters of a strict function"; it only means | 3264 // which is not the same as "parameters of a strict function"; it only means |
3405 // that duplicates are not allowed. Of course, the arrow function may | 3265 // that duplicates are not allowed. Of course, the arrow function may |
3406 // itself be strict as well. | 3266 // itself be strict as well. |
3407 const bool use_strict_params = true; | 3267 const bool use_strict_params = true; |
3408 this->CheckFunctionParameterNames(language_mode(), use_strict_params, | 3268 this->CheckFunctionParameterNames(language_mode(), use_strict_params, |
3409 error_locs, CHECK_OK); | 3269 error_locs, CHECK_OK); |
3410 | 3270 |
3411 // Validate strict mode. | 3271 // Validate strict mode. |
3412 if (is_strict(language_mode())) { | 3272 if (is_strict(language_mode())) { |
3413 CheckStrictOctalLiteral(scope->start_position(), | 3273 CheckStrictOctalLiteral(scope->start_position(), |
3414 scanner()->location().end_pos, CHECK_OK); | 3274 scanner()->location().end_pos, CHECK_OK); |
3415 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | 3275 this->CheckConflictingVarDeclarations(scope, CHECK_OK); |
3416 } | 3276 } |
3417 } | 3277 } |
3418 | 3278 |
3419 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3279 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
3420 this->EmptyIdentifierString(), ast_value_factory(), scope, body, | 3280 this->EmptyIdentifierString(), ast_value_factory(), scope, body, |
3421 materialized_literal_count, expected_property_count, handler_count, | 3281 materialized_literal_count, expected_property_count, handler_count, |
3422 num_parameters, FunctionLiteral::kNoDuplicateParameters, | 3282 num_parameters, FunctionLiteral::kNoDuplicateParameters, |
3423 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, | 3283 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, |
3424 FunctionLiteral::kNotParenthesized, FunctionKind::kArrowFunction, | 3284 FunctionLiteral::kNotParenthesized, FunctionKind::kArrowFunction, |
3425 scope->start_position()); | 3285 scope->start_position()); |
3426 | 3286 |
3427 function_literal->set_function_token_position(scope->start_position()); | 3287 function_literal->set_function_token_position(scope->start_position()); |
3428 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); | 3288 if (super_loc.IsValid()) function_state_->set_super_call_location(super_loc); |
3429 | 3289 |
3430 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | 3290 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); |
3431 | 3291 |
3432 return function_literal; | 3292 return function_literal; |
3433 } | 3293 } |
3434 | 3294 |
3435 | 3295 |
3436 template <typename Traits> | 3296 template <typename Traits> |
3437 typename ParserBase<Traits>::ExpressionT | 3297 typename ParserBase<Traits>::ExpressionT |
3438 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) { | 3298 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) { |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3612 *ok = false; | 3472 *ok = false; |
3613 return; | 3473 return; |
3614 } | 3474 } |
3615 has_seen_constructor_ = true; | 3475 has_seen_constructor_ = true; |
3616 return; | 3476 return; |
3617 } | 3477 } |
3618 } | 3478 } |
3619 } } // v8::internal | 3479 } } // v8::internal |
3620 | 3480 |
3621 #endif // V8_PREPARSER_H | 3481 #endif // V8_PREPARSER_H |
OLD | NEW |