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