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/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/hashmap.h" | 10 #include "src/hashmap.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 kDisallowLabelledFunctionStatement, | 29 kDisallowLabelledFunctionStatement, |
30 }; | 30 }; |
31 | 31 |
32 enum class ParseFunctionFlags { | 32 enum class ParseFunctionFlags { |
33 kIsNormal = 0, | 33 kIsNormal = 0, |
34 kIsGenerator = 1, | 34 kIsGenerator = 1, |
35 kIsAsync = 2, | 35 kIsAsync = 2, |
36 kIsDefault = 4 | 36 kIsDefault = 4 |
37 }; | 37 }; |
38 | 38 |
| 39 enum class FunctionBody { Normal, SingleExpression }; |
| 40 |
| 41 enum class FunctionParsePhase { Unknown, FormalParameters, FunctionBody }; |
| 42 |
39 static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs, | 43 static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs, |
40 ParseFunctionFlags rhs) { | 44 ParseFunctionFlags rhs) { |
41 typedef unsigned char T; | 45 typedef unsigned char T; |
42 return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) | | 46 return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) | |
43 static_cast<T>(rhs)); | 47 static_cast<T>(rhs)); |
44 } | 48 } |
45 | 49 |
46 static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs, | 50 static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs, |
47 const ParseFunctionFlags& rhs) { | 51 const ParseFunctionFlags& rhs) { |
48 lhs = lhs | rhs; | 52 lhs = lhs | rhs; |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 } | 310 } |
307 void set_super_location(Scanner::Location location) { | 311 void set_super_location(Scanner::Location location) { |
308 super_location_ = location; | 312 super_location_ = location; |
309 } | 313 } |
310 void set_return_location(Scanner::Location location) { | 314 void set_return_location(Scanner::Location location) { |
311 return_location_ = location; | 315 return_location_ = location; |
312 } | 316 } |
313 | 317 |
314 bool is_generator() const { return IsGeneratorFunction(kind_); } | 318 bool is_generator() const { return IsGeneratorFunction(kind_); } |
315 bool is_async_function() const { return IsAsyncFunction(kind_); } | 319 bool is_async_function() const { return IsAsyncFunction(kind_); } |
| 320 bool is_resumable() const { return is_generator() || is_async_function(); } |
316 | 321 |
317 FunctionKind kind() const { return kind_; } | 322 FunctionKind kind() const { return kind_; } |
318 FunctionState* outer() const { return outer_function_state_; } | 323 FunctionState* outer() const { return outer_function_state_; } |
319 | 324 |
| 325 bool is_async_function_body() const { |
| 326 return is_async_function() && |
| 327 parse_phase() == FunctionParsePhase::FunctionBody; |
| 328 } |
| 329 |
| 330 FunctionParsePhase parse_phase() const { return parse_phase_; } |
| 331 |
| 332 void set_parse_phase(FunctionParsePhase parse_phase) { |
| 333 parse_phase_ = parse_phase; |
| 334 } |
| 335 |
320 void set_generator_object_variable( | 336 void set_generator_object_variable( |
321 typename Traits::Type::GeneratorVariable* variable) { | 337 typename Traits::Type::GeneratorVariable* variable) { |
322 DCHECK(variable != NULL); | 338 DCHECK(variable != NULL); |
323 DCHECK(is_generator()); | 339 DCHECK(is_resumable()); |
324 generator_object_variable_ = variable; | 340 generator_object_variable_ = variable; |
325 } | 341 } |
326 typename Traits::Type::GeneratorVariable* generator_object_variable() | 342 typename Traits::Type::GeneratorVariable* generator_object_variable() |
327 const { | 343 const { |
328 return generator_object_variable_; | 344 return generator_object_variable_; |
329 } | 345 } |
330 | 346 |
331 typename Traits::Type::Factory* factory() { return factory_; } | 347 typename Traits::Type::Factory* factory() { return factory_; } |
332 | 348 |
333 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | 349 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 typename Traits::Type::Factory* factory_; | 435 typename Traits::Type::Factory* factory_; |
420 | 436 |
421 // If true, the next (and immediately following) function literal is | 437 // If true, the next (and immediately following) function literal is |
422 // preceded by a parenthesis. | 438 // preceded by a parenthesis. |
423 bool next_function_is_parenthesized_; | 439 bool next_function_is_parenthesized_; |
424 | 440 |
425 // The value of the parents' next_function_is_parenthesized_, as it applies | 441 // The value of the parents' next_function_is_parenthesized_, as it applies |
426 // to this function. Filled in by constructor. | 442 // to this function. Filled in by constructor. |
427 bool this_function_is_parenthesized_; | 443 bool this_function_is_parenthesized_; |
428 | 444 |
| 445 FunctionParsePhase parse_phase_ = FunctionParsePhase::Unknown; |
| 446 |
429 friend class ParserTraits; | 447 friend class ParserTraits; |
430 friend class PreParserTraits; | 448 friend class PreParserTraits; |
431 friend class Checkpoint; | 449 friend class Checkpoint; |
432 }; | 450 }; |
433 | 451 |
434 // This scope sets current ReturnExprContext to given value. | 452 // This scope sets current ReturnExprContext to given value. |
435 class ReturnExprScope { | 453 class ReturnExprScope { |
436 public: | 454 public: |
437 explicit ReturnExprScope(FunctionState* function_state, | 455 explicit ReturnExprScope(FunctionState* function_state, |
438 ReturnExprContext return_expr_context) | 456 ReturnExprContext return_expr_context) |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 | 732 |
715 typename Traits::Type::Factory* factory() { | 733 typename Traits::Type::Factory* factory() { |
716 return function_state_->factory(); | 734 return function_state_->factory(); |
717 } | 735 } |
718 | 736 |
719 LanguageMode language_mode() { return scope_->language_mode(); } | 737 LanguageMode language_mode() { return scope_->language_mode(); } |
720 bool is_generator() const { return function_state_->is_generator(); } | 738 bool is_generator() const { return function_state_->is_generator(); } |
721 bool is_async_function() const { | 739 bool is_async_function() const { |
722 return function_state_->is_async_function(); | 740 return function_state_->is_async_function(); |
723 } | 741 } |
| 742 bool is_resumable() const { return function_state_->is_resumable(); } |
724 | 743 |
725 // Report syntax errors. | 744 // Report syntax errors. |
726 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, | 745 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, |
727 ParseErrorType error_type = kSyntaxError) { | 746 ParseErrorType error_type = kSyntaxError) { |
728 Scanner::Location source_location = scanner()->location(); | 747 Scanner::Location source_location = scanner()->location(); |
729 Traits::ReportMessageAt(source_location, message, arg, error_type); | 748 Traits::ReportMessageAt(source_location, message, arg, error_type); |
730 } | 749 } |
731 | 750 |
732 void ReportMessageAt(Scanner::Location location, | 751 void ReportMessageAt(Scanner::Location location, |
733 MessageTemplate::Template message, | 752 MessageTemplate::Template message, |
(...skipping 1433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2167 parenthesized_formals, is_async, CHECK_OK); | 2186 parenthesized_formals, is_async, CHECK_OK); |
2168 // This reads strangely, but is correct: it checks whether any | 2187 // This reads strangely, but is correct: it checks whether any |
2169 // sub-expression of the parameter list failed to be a valid formal | 2188 // sub-expression of the parameter list failed to be a valid formal |
2170 // parameter initializer. Since YieldExpressions are banned anywhere | 2189 // parameter initializer. Since YieldExpressions are banned anywhere |
2171 // in an arrow parameter list, this is correct. | 2190 // in an arrow parameter list, this is correct. |
2172 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to | 2191 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to |
2173 // "YieldExpression", which is its only use. | 2192 // "YieldExpression", which is its only use. |
2174 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); | 2193 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); |
2175 | 2194 |
2176 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); | 2195 Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); |
2177 Scope* scope = | 2196 Scope* scope = this->NewScope(scope_, FUNCTION_SCOPE, |
2178 this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); | 2197 is_async ? FunctionKind::kAsyncArrowFunction |
| 2198 : FunctionKind::kArrowFunction); |
2179 // Because the arrow's parameters were parsed in the outer scope, any | 2199 // Because the arrow's parameters were parsed in the outer scope, any |
2180 // usage flags that might have been triggered there need to be copied | 2200 // usage flags that might have been triggered there need to be copied |
2181 // to the arrow scope. | 2201 // to the arrow scope. |
2182 scope_->PropagateUsageFlagsToScope(scope); | 2202 scope_->PropagateUsageFlagsToScope(scope); |
2183 FormalParametersT parameters(scope); | 2203 FormalParametersT parameters(scope); |
2184 if (!arrow_formals_classifier.is_simple_parameter_list()) { | 2204 if (!arrow_formals_classifier.is_simple_parameter_list()) { |
2185 scope->SetHasNonSimpleParameters(); | 2205 scope->SetHasNonSimpleParameters(); |
2186 parameters.is_simple = false; | 2206 parameters.is_simple = false; |
2187 } | 2207 } |
2188 | 2208 |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2603 | 2623 |
2604 return this->ExpressionFromIdentifier( | 2624 return this->ExpressionFromIdentifier( |
2605 name, beg_pos, scanner()->location().end_pos, scope_, factory()); | 2625 name, beg_pos, scanner()->location().end_pos, scope_, factory()); |
2606 } | 2626 } |
2607 default: | 2627 default: |
2608 break; | 2628 break; |
2609 } | 2629 } |
2610 Consume(Token::AWAIT); | 2630 Consume(Token::AWAIT); |
2611 | 2631 |
2612 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); | 2632 ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); |
2613 classifier->RecordFormalParameterInitializerError( | 2633 if (!function_state_->is_async_function_body()) { |
2614 Scanner::Location(beg_pos, scanner()->location().end_pos), | 2634 // Not currently parsing function body --- must have occurred within |
2615 MessageTemplate::kAwaitExpressionFormalParameter); | 2635 // formal parameter parsing. |
2616 | 2636 ReportMessageAt(Scanner::Location(beg_pos, scanner()->location().end_pos), |
| 2637 MessageTemplate::kAwaitExpressionFormalParameter); |
| 2638 *ok = false; |
| 2639 return this->EmptyExpression(); |
| 2640 } |
2617 return Traits::RewriteAwaitExpression(value, beg_pos); | 2641 return Traits::RewriteAwaitExpression(value, beg_pos); |
2618 } else { | 2642 } else { |
2619 return this->ParsePostfixExpression(classifier, ok); | 2643 return this->ParsePostfixExpression(classifier, ok); |
2620 } | 2644 } |
2621 } | 2645 } |
2622 | 2646 |
2623 | 2647 |
2624 template <class Traits> | 2648 template <class Traits> |
2625 typename ParserBase<Traits>::ExpressionT | 2649 typename ParserBase<Traits>::ExpressionT |
2626 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, | 2650 ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3204 *ok = false; | 3228 *ok = false; |
3205 return this->EmptyExpression(); | 3229 return this->EmptyExpression(); |
3206 } | 3230 } |
3207 | 3231 |
3208 typename Traits::Type::StatementList body; | 3232 typename Traits::Type::StatementList body; |
3209 int num_parameters = formal_parameters.scope->num_parameters(); | 3233 int num_parameters = formal_parameters.scope->num_parameters(); |
3210 int materialized_literal_count = -1; | 3234 int materialized_literal_count = -1; |
3211 int expected_property_count = -1; | 3235 int expected_property_count = -1; |
3212 Scanner::Location super_loc; | 3236 Scanner::Location super_loc; |
3213 | 3237 |
| 3238 FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; |
3214 { | 3239 { |
3215 typename Traits::Type::Factory function_factory(ast_value_factory()); | 3240 typename Traits::Type::Factory function_factory(ast_value_factory()); |
3216 FunctionState function_state( | 3241 FunctionState function_state(&function_state_, &scope_, |
3217 &function_state_, &scope_, formal_parameters.scope, | 3242 formal_parameters.scope, arrow_kind, |
3218 is_async ? kAsyncArrowFunction : kArrowFunction, &function_factory); | 3243 &function_factory); |
3219 | 3244 |
3220 function_state.SkipMaterializedLiterals( | 3245 function_state.SkipMaterializedLiterals( |
3221 formal_parameters.materialized_literals_count); | 3246 formal_parameters.materialized_literals_count); |
3222 | 3247 |
3223 this->ReindexLiterals(formal_parameters); | 3248 this->ReindexLiterals(formal_parameters); |
3224 | 3249 |
3225 Expect(Token::ARROW, CHECK_OK); | 3250 Expect(Token::ARROW, CHECK_OK); |
| 3251 function_state.set_parse_phase(FunctionParsePhase::FunctionBody); |
3226 | 3252 |
3227 if (peek() == Token::LBRACE) { | 3253 if (peek() == Token::LBRACE) { |
3228 // Multiple statement body | 3254 // Multiple statement body |
3229 Consume(Token::LBRACE); | 3255 Consume(Token::LBRACE); |
3230 bool is_lazily_parsed = | 3256 bool is_lazily_parsed = |
3231 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing()); | 3257 (mode() == PARSE_LAZILY && scope_->AllowsLazyParsing()); |
3232 if (is_lazily_parsed) { | 3258 if (is_lazily_parsed) { |
3233 body = this->NewStatementList(0, zone()); | 3259 body = this->NewStatementList(0, zone()); |
3234 this->SkipLazyFunctionBody(&materialized_literal_count, | 3260 this->SkipLazyFunctionBody(&materialized_literal_count, |
3235 &expected_property_count, CHECK_OK); | 3261 &expected_property_count, CHECK_OK); |
3236 if (formal_parameters.materialized_literals_count > 0) { | 3262 if (formal_parameters.materialized_literals_count > 0) { |
3237 materialized_literal_count += | 3263 materialized_literal_count += |
3238 formal_parameters.materialized_literals_count; | 3264 formal_parameters.materialized_literals_count; |
3239 } | 3265 } |
3240 } else { | 3266 } else { |
3241 body = this->ParseEagerFunctionBody( | 3267 body = this->ParseEagerFunctionBody( |
3242 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, | 3268 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, |
3243 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 3269 arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
3244 materialized_literal_count = | 3270 materialized_literal_count = |
3245 function_state.materialized_literal_count(); | 3271 function_state.materialized_literal_count(); |
3246 expected_property_count = function_state.expected_property_count(); | 3272 expected_property_count = function_state.expected_property_count(); |
3247 } | 3273 } |
3248 } else { | 3274 } else { |
3249 // Single-expression body | 3275 // Single-expression body |
3250 int pos = position(); | 3276 int pos = position(); |
3251 ExpressionClassifier classifier(this); | 3277 ExpressionClassifier classifier(this); |
3252 DCHECK(ReturnExprContext::kInsideValidBlock == | 3278 DCHECK(ReturnExprContext::kInsideValidBlock == |
3253 function_state_->return_expr_context()); | 3279 function_state_->return_expr_context()); |
3254 ReturnExprScope allow_tail_calls( | 3280 ReturnExprScope allow_tail_calls( |
3255 function_state_, ReturnExprContext::kInsideValidReturnStatement); | 3281 function_state_, ReturnExprContext::kInsideValidReturnStatement); |
3256 ExpressionT expression = | |
3257 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); | |
3258 Traits::RewriteNonPattern(&classifier, CHECK_OK); | |
3259 body = this->NewStatementList(1, zone()); | 3282 body = this->NewStatementList(1, zone()); |
3260 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); | 3283 this->AddParameterInitializationBlock(formal_parameters, body, is_async, |
3261 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 3284 CHECK_OK); |
| 3285 if (is_async) { |
| 3286 this->ParseAsyncArrowSingleExpressionBody(body, accept_IN, &classifier, |
| 3287 pos, CHECK_OK); |
| 3288 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
| 3289 } else { |
| 3290 ExpressionT expression = |
| 3291 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); |
| 3292 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
| 3293 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
| 3294 if (allow_tailcalls() && !is_sloppy(language_mode())) { |
| 3295 // ES6 14.6.1 Static Semantics: IsInTailPosition |
| 3296 this->MarkTailPosition(expression); |
| 3297 } |
| 3298 } |
3262 materialized_literal_count = function_state.materialized_literal_count(); | 3299 materialized_literal_count = function_state.materialized_literal_count(); |
3263 expected_property_count = function_state.expected_property_count(); | 3300 expected_property_count = function_state.expected_property_count(); |
3264 if (allow_tailcalls() && !is_sloppy(language_mode())) { | |
3265 // ES6 14.6.1 Static Semantics: IsInTailPosition | |
3266 this->MarkTailPosition(expression); | |
3267 } | |
3268 this->MarkCollectedTailCallExpressions(); | 3301 this->MarkCollectedTailCallExpressions(); |
3269 } | 3302 } |
3270 super_loc = function_state.super_location(); | 3303 super_loc = function_state.super_location(); |
3271 | 3304 |
3272 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 3305 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
3273 | 3306 |
3274 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 3307 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
3275 // which is not the same as "parameters of a strict function"; it only means | 3308 // which is not the same as "parameters of a strict function"; it only means |
3276 // that duplicates are not allowed. Of course, the arrow function may | 3309 // that duplicates are not allowed. Of course, the arrow function may |
3277 // itself be strict as well. | 3310 // itself be strict as well. |
3278 const bool allow_duplicate_parameters = false; | 3311 const bool allow_duplicate_parameters = false; |
3279 this->ValidateFormalParameters(&formals_classifier, language_mode(), | 3312 this->ValidateFormalParameters(&formals_classifier, language_mode(), |
3280 allow_duplicate_parameters, CHECK_OK); | 3313 allow_duplicate_parameters, CHECK_OK); |
3281 | 3314 |
3282 // Validate strict mode. | 3315 // Validate strict mode. |
3283 if (is_strict(language_mode())) { | 3316 if (is_strict(language_mode())) { |
3284 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), | 3317 CheckStrictOctalLiteral(formal_parameters.scope->start_position(), |
3285 scanner()->location().end_pos, CHECK_OK); | 3318 scanner()->location().end_pos, CHECK_OK); |
3286 } | 3319 } |
3287 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); | 3320 this->CheckConflictingVarDeclarations(formal_parameters.scope, CHECK_OK); |
3288 | 3321 |
3289 Traits::RewriteDestructuringAssignments(); | 3322 Traits::RewriteDestructuringAssignments(); |
3290 } | 3323 } |
3291 | 3324 |
3292 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 3325 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
3293 this->EmptyIdentifierString(), formal_parameters.scope, body, | 3326 this->EmptyIdentifierString(), formal_parameters.scope, body, |
3294 materialized_literal_count, expected_property_count, num_parameters, | 3327 materialized_literal_count, expected_property_count, num_parameters, |
3295 FunctionLiteral::kNoDuplicateParameters, | 3328 FunctionLiteral::kNoDuplicateParameters, |
3296 FunctionLiteral::kAnonymousExpression, | 3329 FunctionLiteral::kAnonymousExpression, |
3297 FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, | 3330 FunctionLiteral::kShouldLazyCompile, arrow_kind, |
3298 formal_parameters.scope->start_position()); | 3331 formal_parameters.scope->start_position()); |
3299 | 3332 |
3300 function_literal->set_function_token_position( | 3333 function_literal->set_function_token_position( |
3301 formal_parameters.scope->start_position()); | 3334 formal_parameters.scope->start_position()); |
3302 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); | 3335 if (super_loc.IsValid()) function_state_->set_super_location(super_loc); |
3303 | 3336 |
3304 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | 3337 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); |
3305 | 3338 |
3306 return function_literal; | 3339 return function_literal; |
3307 } | 3340 } |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3517 has_seen_constructor_ = true; | 3550 has_seen_constructor_ = true; |
3518 return; | 3551 return; |
3519 } | 3552 } |
3520 } | 3553 } |
3521 | 3554 |
3522 | 3555 |
3523 } // namespace internal | 3556 } // namespace internal |
3524 } // namespace v8 | 3557 } // namespace v8 |
3525 | 3558 |
3526 #endif // V8_PARSING_PARSER_BASE_H | 3559 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |