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_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 stack_overflow_(false), | 211 stack_overflow_(false), |
212 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), | 212 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), |
213 function_literal_id_(0), | 213 function_literal_id_(0), |
214 allow_natives_(false), | 214 allow_natives_(false), |
215 allow_tailcalls_(false), | 215 allow_tailcalls_(false), |
216 allow_harmony_do_expressions_(false), | 216 allow_harmony_do_expressions_(false), |
217 allow_harmony_function_sent_(false), | 217 allow_harmony_function_sent_(false), |
218 allow_harmony_restrictive_generators_(false), | 218 allow_harmony_restrictive_generators_(false), |
219 allow_harmony_trailing_commas_(false), | 219 allow_harmony_trailing_commas_(false), |
220 allow_harmony_class_fields_(false), | 220 allow_harmony_class_fields_(false), |
221 allow_harmony_object_spread_(false) {} | 221 allow_harmony_object_rest_spread_(false) {} |
222 | 222 |
223 #define ALLOW_ACCESSORS(name) \ | 223 #define ALLOW_ACCESSORS(name) \ |
224 bool allow_##name() const { return allow_##name##_; } \ | 224 bool allow_##name() const { return allow_##name##_; } \ |
225 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 225 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
226 | 226 |
227 ALLOW_ACCESSORS(natives); | 227 ALLOW_ACCESSORS(natives); |
228 ALLOW_ACCESSORS(tailcalls); | 228 ALLOW_ACCESSORS(tailcalls); |
229 ALLOW_ACCESSORS(harmony_do_expressions); | 229 ALLOW_ACCESSORS(harmony_do_expressions); |
230 ALLOW_ACCESSORS(harmony_function_sent); | 230 ALLOW_ACCESSORS(harmony_function_sent); |
231 ALLOW_ACCESSORS(harmony_restrictive_generators); | 231 ALLOW_ACCESSORS(harmony_restrictive_generators); |
232 ALLOW_ACCESSORS(harmony_trailing_commas); | 232 ALLOW_ACCESSORS(harmony_trailing_commas); |
233 ALLOW_ACCESSORS(harmony_class_fields); | 233 ALLOW_ACCESSORS(harmony_class_fields); |
234 ALLOW_ACCESSORS(harmony_object_spread); | 234 ALLOW_ACCESSORS(harmony_object_rest_spread); |
235 | 235 |
236 #undef ALLOW_ACCESSORS | 236 #undef ALLOW_ACCESSORS |
237 | 237 |
238 uintptr_t stack_limit() const { return stack_limit_; } | 238 uintptr_t stack_limit() const { return stack_limit_; } |
239 | 239 |
240 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } | 240 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } |
241 | 241 |
242 void set_default_eager_compile_hint( | 242 void set_default_eager_compile_hint( |
243 FunctionLiteral::EagerCompileHint eager_compile_hint) { | 243 FunctionLiteral::EagerCompileHint eager_compile_hint) { |
244 default_eager_compile_hint_ = eager_compile_hint; | 244 default_eager_compile_hint_ = eager_compile_hint; |
(...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1160 bool* is_async, bool* is_computed_name, | 1160 bool* is_async, bool* is_computed_name, |
1161 bool* ok); | 1161 bool* ok); |
1162 ExpressionT ParseObjectLiteral(bool* ok); | 1162 ExpressionT ParseObjectLiteral(bool* ok); |
1163 ClassLiteralPropertyT ParseClassPropertyDefinition( | 1163 ClassLiteralPropertyT ParseClassPropertyDefinition( |
1164 ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name, | 1164 ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name, |
1165 bool* has_seen_constructor, ClassLiteralProperty::Kind* property_kind, | 1165 bool* has_seen_constructor, ClassLiteralProperty::Kind* property_kind, |
1166 bool* is_static, bool* has_name_static_property, bool* ok); | 1166 bool* is_static, bool* has_name_static_property, bool* ok); |
1167 FunctionLiteralT ParseClassFieldForInitializer(bool has_initializer, | 1167 FunctionLiteralT ParseClassFieldForInitializer(bool has_initializer, |
1168 bool* ok); | 1168 bool* ok); |
1169 ObjectLiteralPropertyT ParseObjectPropertyDefinition( | 1169 ObjectLiteralPropertyT ParseObjectPropertyDefinition( |
1170 ObjectLiteralChecker* checker, bool* is_computed_name, bool* ok); | 1170 ObjectLiteralChecker* checker, bool* is_computed_name, |
| 1171 bool* is_rest_property, bool* ok); |
1171 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, | 1172 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, |
1172 bool maybe_arrow, bool* ok); | 1173 bool maybe_arrow, bool* ok); |
1173 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, | 1174 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, |
1174 bool* ok) { | 1175 bool* ok) { |
1175 return ParseArguments(first_spread_pos, false, ok); | 1176 return ParseArguments(first_spread_pos, false, ok); |
1176 } | 1177 } |
1177 | 1178 |
1178 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 1179 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
1179 ExpressionT ParseYieldExpression(bool accept_IN, bool* ok); | 1180 ExpressionT ParseYieldExpression(bool accept_IN, bool* ok); |
1180 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 1181 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1449 | 1450 |
1450 int function_literal_id_; | 1451 int function_literal_id_; |
1451 | 1452 |
1452 bool allow_natives_; | 1453 bool allow_natives_; |
1453 bool allow_tailcalls_; | 1454 bool allow_tailcalls_; |
1454 bool allow_harmony_do_expressions_; | 1455 bool allow_harmony_do_expressions_; |
1455 bool allow_harmony_function_sent_; | 1456 bool allow_harmony_function_sent_; |
1456 bool allow_harmony_restrictive_generators_; | 1457 bool allow_harmony_restrictive_generators_; |
1457 bool allow_harmony_trailing_commas_; | 1458 bool allow_harmony_trailing_commas_; |
1458 bool allow_harmony_class_fields_; | 1459 bool allow_harmony_class_fields_; |
1459 bool allow_harmony_object_spread_; | 1460 bool allow_harmony_object_rest_spread_; |
1460 | 1461 |
1461 friend class DiscardableZoneScope; | 1462 friend class DiscardableZoneScope; |
1462 }; | 1463 }; |
1463 | 1464 |
1464 template <typename Impl> | 1465 template <typename Impl> |
1465 ParserBase<Impl>::FunctionState::FunctionState( | 1466 ParserBase<Impl>::FunctionState::FunctionState( |
1466 FunctionState** function_state_stack, ScopeState** scope_stack, | 1467 FunctionState** function_state_stack, ScopeState** scope_stack, |
1467 DeclarationScope* scope) | 1468 DeclarationScope* scope) |
1468 : ScopeState(scope_stack, scope), | 1469 : ScopeState(scope_stack, scope), |
1469 next_materialized_literal_index_(0), | 1470 next_materialized_literal_index_(0), |
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2103 Consume(Token::LBRACK); | 2104 Consume(Token::LBRACK); |
2104 ExpressionClassifier computed_name_classifier(this); | 2105 ExpressionClassifier computed_name_classifier(this); |
2105 expression = ParseAssignmentExpression(true, CHECK_OK); | 2106 expression = ParseAssignmentExpression(true, CHECK_OK); |
2106 impl()->RewriteNonPattern(CHECK_OK); | 2107 impl()->RewriteNonPattern(CHECK_OK); |
2107 impl()->AccumulateFormalParameterContainmentErrors(); | 2108 impl()->AccumulateFormalParameterContainmentErrors(); |
2108 Expect(Token::RBRACK, CHECK_OK); | 2109 Expect(Token::RBRACK, CHECK_OK); |
2109 break; | 2110 break; |
2110 } | 2111 } |
2111 | 2112 |
2112 case Token::ELLIPSIS: | 2113 case Token::ELLIPSIS: |
2113 if (allow_harmony_object_spread()) { | 2114 if (allow_harmony_object_rest_spread()) { |
2114 // TODO(gsathya): Implement destructuring/rest | |
2115 classifier()->RecordPatternError(scanner()->location(), | |
2116 MessageTemplate::kUnexpectedToken); | |
2117 | |
2118 *name = impl()->EmptyIdentifier(); | 2115 *name = impl()->EmptyIdentifier(); |
2119 Consume(Token::ELLIPSIS); | 2116 Consume(Token::ELLIPSIS); |
2120 ExpressionClassifier spread_classifier(this); | |
2121 expression = ParseAssignmentExpression(true, CHECK_OK); | 2117 expression = ParseAssignmentExpression(true, CHECK_OK); |
2122 impl()->RewriteNonPattern(CHECK_OK); | |
2123 impl()->AccumulateFormalParameterContainmentErrors(); | |
2124 *kind = PropertyKind::kSpreadProperty; | 2118 *kind = PropertyKind::kSpreadProperty; |
| 2119 |
| 2120 if (expression->IsAssignment()) { |
| 2121 classifier()->RecordPatternError( |
| 2122 scanner()->location(), |
| 2123 MessageTemplate::kInvalidDestructuringTarget); |
| 2124 } else { |
| 2125 // TODO(gsathya): Throw error if number of properties > |
| 2126 // Code::kMaxArguments |
| 2127 CheckDestructuringElement(expression, pos, |
| 2128 scanner()->location().end_pos); |
| 2129 } |
| 2130 |
| 2131 if (peek() != Token::RBRACE) { |
| 2132 classifier()->RecordPatternError(scanner()->location(), |
| 2133 MessageTemplate::kElementAfterRest); |
| 2134 } |
2125 return expression; | 2135 return expression; |
2126 } | 2136 } |
2127 | 2137 |
2128 default: | 2138 default: |
2129 *name = ParseIdentifierName(CHECK_OK); | 2139 *name = ParseIdentifierName(CHECK_OK); |
2130 break; | 2140 break; |
2131 } | 2141 } |
2132 | 2142 |
2133 if (*kind == PropertyKind::kNotSet) { | 2143 if (*kind == PropertyKind::kNotSet) { |
2134 SetPropertyKindFromToken(peek(), kind); | 2144 SetPropertyKindFromToken(peek(), kind); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2324 FunctionLiteral::kNoDuplicateParameters, | 2334 FunctionLiteral::kNoDuplicateParameters, |
2325 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_, | 2335 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_, |
2326 initializer_scope->start_position(), true, GetNextFunctionLiteralId()); | 2336 initializer_scope->start_position(), true, GetNextFunctionLiteralId()); |
2327 return function_literal; | 2337 return function_literal; |
2328 } | 2338 } |
2329 | 2339 |
2330 template <typename Impl> | 2340 template <typename Impl> |
2331 typename ParserBase<Impl>::ObjectLiteralPropertyT | 2341 typename ParserBase<Impl>::ObjectLiteralPropertyT |
2332 ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, | 2342 ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, |
2333 bool* is_computed_name, | 2343 bool* is_computed_name, |
| 2344 bool* is_rest_property, |
2334 bool* ok) { | 2345 bool* ok) { |
2335 bool is_get = false; | 2346 bool is_get = false; |
2336 bool is_set = false; | 2347 bool is_set = false; |
2337 bool is_generator = false; | 2348 bool is_generator = false; |
2338 bool is_async = false; | 2349 bool is_async = false; |
2339 PropertyKind kind = PropertyKind::kNotSet; | 2350 PropertyKind kind = PropertyKind::kNotSet; |
2340 | 2351 |
2341 IdentifierT name = impl()->EmptyIdentifier(); | 2352 IdentifierT name = impl()->EmptyIdentifier(); |
2342 Token::Value name_token = peek(); | 2353 Token::Value name_token = peek(); |
2343 int next_beg_pos = scanner()->peek_location().beg_pos; | 2354 int next_beg_pos = scanner()->peek_location().beg_pos; |
2344 int next_end_pos = scanner()->peek_location().end_pos; | 2355 int next_end_pos = scanner()->peek_location().end_pos; |
2345 | 2356 |
2346 ExpressionT name_expression = ParsePropertyName( | 2357 ExpressionT name_expression = ParsePropertyName( |
2347 &name, &kind, &is_generator, &is_get, &is_set, &is_async, | 2358 &name, &kind, &is_generator, &is_get, &is_set, &is_async, |
2348 is_computed_name, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2359 is_computed_name, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
2349 | 2360 |
2350 switch (kind) { | 2361 switch (kind) { |
2351 case PropertyKind::kSpreadProperty: | 2362 case PropertyKind::kSpreadProperty: |
2352 DCHECK(allow_harmony_object_spread()); | 2363 DCHECK(allow_harmony_object_rest_spread()); |
2353 DCHECK(!is_get && !is_set && !is_generator && !is_async && | 2364 DCHECK(!is_get && !is_set && !is_generator && !is_async && |
2354 !*is_computed_name); | 2365 !*is_computed_name); |
2355 DCHECK(name_token == Token::ELLIPSIS); | 2366 DCHECK(name_token == Token::ELLIPSIS); |
2356 | 2367 |
2357 *is_computed_name = true; | 2368 *is_computed_name = true; |
| 2369 *is_rest_property = true; |
2358 | 2370 |
2359 return factory()->NewObjectLiteralProperty( | 2371 return factory()->NewObjectLiteralProperty( |
2360 impl()->GetLiteralTheHole(kNoSourcePosition), name_expression, | 2372 impl()->GetLiteralTheHole(kNoSourcePosition), name_expression, |
2361 ObjectLiteralProperty::SPREAD, true); | 2373 ObjectLiteralProperty::SPREAD, true); |
2362 | 2374 |
2363 case PropertyKind::kValueProperty: { | 2375 case PropertyKind::kValueProperty: { |
2364 DCHECK(!is_get && !is_set && !is_generator && !is_async); | 2376 DCHECK(!is_get && !is_set && !is_generator && !is_async); |
2365 | 2377 |
2366 if (!*is_computed_name) { | 2378 if (!*is_computed_name) { |
2367 checker->CheckDuplicateProto(name_token); | 2379 checker->CheckDuplicateProto(name_token); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2522 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( | 2534 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( |
2523 bool* ok) { | 2535 bool* ok) { |
2524 // ObjectLiteral :: | 2536 // ObjectLiteral :: |
2525 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' | 2537 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' |
2526 | 2538 |
2527 int pos = peek_position(); | 2539 int pos = peek_position(); |
2528 typename Types::ObjectPropertyList properties = | 2540 typename Types::ObjectPropertyList properties = |
2529 impl()->NewObjectPropertyList(4); | 2541 impl()->NewObjectPropertyList(4); |
2530 int number_of_boilerplate_properties = 0; | 2542 int number_of_boilerplate_properties = 0; |
2531 bool has_computed_names = false; | 2543 bool has_computed_names = false; |
| 2544 bool has_rest_property = false; |
2532 ObjectLiteralChecker checker(this); | 2545 ObjectLiteralChecker checker(this); |
2533 | 2546 |
2534 Expect(Token::LBRACE, CHECK_OK); | 2547 Expect(Token::LBRACE, CHECK_OK); |
2535 | 2548 |
2536 while (peek() != Token::RBRACE) { | 2549 while (peek() != Token::RBRACE) { |
2537 FuncNameInferrer::State fni_state(fni_); | 2550 FuncNameInferrer::State fni_state(fni_); |
2538 | 2551 |
2539 bool is_computed_name = false; | 2552 bool is_computed_name = false; |
2540 ObjectLiteralPropertyT property = | 2553 bool is_rest_property = false; |
2541 ParseObjectPropertyDefinition(&checker, &is_computed_name, CHECK_OK); | 2554 ObjectLiteralPropertyT property = ParseObjectPropertyDefinition( |
| 2555 &checker, &is_computed_name, &is_rest_property, CHECK_OK); |
2542 | 2556 |
2543 if (is_computed_name) { | 2557 if (is_computed_name) { |
2544 has_computed_names = true; | 2558 has_computed_names = true; |
2545 } | 2559 } |
2546 | 2560 |
| 2561 if (is_rest_property) { |
| 2562 has_rest_property = true; |
| 2563 } |
| 2564 |
2547 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 2565 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
2548 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { | 2566 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { |
2549 number_of_boilerplate_properties++; | 2567 number_of_boilerplate_properties++; |
2550 } | 2568 } |
2551 properties->Add(property, zone()); | 2569 properties->Add(property, zone()); |
2552 | 2570 |
2553 if (peek() != Token::RBRACE) { | 2571 if (peek() != Token::RBRACE) { |
2554 // Need {} because of the CHECK_OK macro. | 2572 // Need {} because of the CHECK_OK macro. |
2555 Expect(Token::COMMA, CHECK_OK); | 2573 Expect(Token::COMMA, CHECK_OK); |
2556 } | 2574 } |
2557 | 2575 |
2558 if (fni_ != nullptr) fni_->Infer(); | 2576 if (fni_ != nullptr) fni_->Infer(); |
2559 } | 2577 } |
2560 Expect(Token::RBRACE, CHECK_OK); | 2578 Expect(Token::RBRACE, CHECK_OK); |
2561 | 2579 |
2562 // Computation of literal_index must happen before pre parse bailout. | 2580 // Computation of literal_index must happen before pre parse bailout. |
2563 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 2581 int literal_index = function_state_->NextMaterializedLiteralIndex(); |
2564 | 2582 |
2565 return factory()->NewObjectLiteral(properties, | 2583 return factory()->NewObjectLiteral(properties, literal_index, |
2566 literal_index, | 2584 number_of_boilerplate_properties, pos, |
2567 number_of_boilerplate_properties, | 2585 has_rest_property); |
2568 pos); | |
2569 } | 2586 } |
2570 | 2587 |
2571 template <typename Impl> | 2588 template <typename Impl> |
2572 typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments( | 2589 typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments( |
2573 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, bool* ok) { | 2590 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, bool* ok) { |
2574 // Arguments :: | 2591 // Arguments :: |
2575 // '(' (AssignmentExpression)*[','] ')' | 2592 // '(' (AssignmentExpression)*[','] ')' |
2576 | 2593 |
2577 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2594 Scanner::Location spread_arg = Scanner::Location::invalid(); |
2578 ExpressionListT result = impl()->NewExpressionList(4); | 2595 ExpressionListT result = impl()->NewExpressionList(4); |
(...skipping 2965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5544 has_seen_constructor_ = true; | 5561 has_seen_constructor_ = true; |
5545 return; | 5562 return; |
5546 } | 5563 } |
5547 } | 5564 } |
5548 | 5565 |
5549 | 5566 |
5550 } // namespace internal | 5567 } // namespace internal |
5551 } // namespace v8 | 5568 } // namespace v8 |
5552 | 5569 |
5553 #endif // V8_PARSING_PARSER_BASE_H | 5570 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |