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 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 void SkipMaterializedLiterals(int count) { | 418 void SkipMaterializedLiterals(int count) { |
419 next_materialized_literal_index_ += count; | 419 next_materialized_literal_index_ += count; |
420 } | 420 } |
421 | 421 |
422 void AddProperty() { expected_property_count_++; } | 422 void AddProperty() { expected_property_count_++; } |
423 int expected_property_count() { return expected_property_count_; } | 423 int expected_property_count() { return expected_property_count_; } |
424 | 424 |
425 FunctionKind kind() const { return scope()->function_kind(); } | 425 FunctionKind kind() const { return scope()->function_kind(); } |
426 FunctionState* outer() const { return outer_function_state_; } | 426 FunctionState* outer() const { return outer_function_state_; } |
427 | 427 |
428 void set_generator_object_variable(typename Types::Variable* variable) { | |
429 DCHECK_NOT_NULL(variable); | |
430 DCHECK(IsResumableFunction(kind())); | |
431 DCHECK(scope()->has_forced_context_allocation()); | |
432 generator_object_variable_ = variable; | |
433 } | |
434 typename Types::Variable* generator_object_variable() const { | |
435 return generator_object_variable_; | |
436 } | |
437 | |
438 void set_promise_variable(typename Types::Variable* variable) { | |
439 DCHECK(variable != NULL); | |
440 DCHECK(IsAsyncFunction(kind())); | |
441 promise_variable_ = variable; | |
442 } | |
443 typename Types::Variable* promise_variable() const { | |
444 return promise_variable_; | |
445 } | |
446 | |
447 const ZoneList<DestructuringAssignment>& | 428 const ZoneList<DestructuringAssignment>& |
448 destructuring_assignments_to_rewrite() const { | 429 destructuring_assignments_to_rewrite() const { |
449 return destructuring_assignments_to_rewrite_; | 430 return destructuring_assignments_to_rewrite_; |
450 } | 431 } |
451 | 432 |
452 TailCallExpressionList& tail_call_expressions() { | 433 TailCallExpressionList& tail_call_expressions() { |
453 return tail_call_expressions_; | 434 return tail_call_expressions_; |
454 } | 435 } |
455 void AddImplicitTailCallExpression(ExpressionT expression) { | 436 void AddImplicitTailCallExpression(ExpressionT expression) { |
456 if (return_expr_context() == | 437 if (return_expr_context() == |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 } | 480 } |
500 | 481 |
501 // Used to assign an index to each literal that needs materialization in | 482 // Used to assign an index to each literal that needs materialization in |
502 // the function. Includes regexp literals, and boilerplate for object and | 483 // the function. Includes regexp literals, and boilerplate for object and |
503 // array literals. | 484 // array literals. |
504 int next_materialized_literal_index_; | 485 int next_materialized_literal_index_; |
505 | 486 |
506 // Properties count estimation. | 487 // Properties count estimation. |
507 int expected_property_count_; | 488 int expected_property_count_; |
508 | 489 |
509 // For generators, this variable may hold the generator object. It variable | |
510 // is used by yield expressions and return statements. It is not necessary | |
511 // for generator functions to have this variable set. | |
512 Variable* generator_object_variable_; | |
513 // For async functions, this variable holds a temporary for the Promise | |
514 // being created as output of the async function. | |
515 Variable* promise_variable_; | |
516 | |
517 FunctionState** function_state_stack_; | 490 FunctionState** function_state_stack_; |
518 FunctionState* outer_function_state_; | 491 FunctionState* outer_function_state_; |
519 | 492 |
520 ZoneList<DestructuringAssignment> destructuring_assignments_to_rewrite_; | 493 ZoneList<DestructuringAssignment> destructuring_assignments_to_rewrite_; |
521 TailCallExpressionList tail_call_expressions_; | 494 TailCallExpressionList tail_call_expressions_; |
522 ReturnExprContext return_expr_context_; | 495 ReturnExprContext return_expr_context_; |
523 ZoneList<ExpressionT> non_patterns_to_rewrite_; | 496 ZoneList<ExpressionT> non_patterns_to_rewrite_; |
524 | 497 |
525 ZoneList<typename ExpressionClassifier::Error> reported_errors_; | 498 ZoneList<typename ExpressionClassifier::Error> reported_errors_; |
526 | 499 |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 DeclarationScope* NewFunctionScope(FunctionKind kind, | 705 DeclarationScope* NewFunctionScope(FunctionKind kind, |
733 Zone* target_zone = nullptr) const { | 706 Zone* target_zone = nullptr) const { |
734 DCHECK(ast_value_factory()); | 707 DCHECK(ast_value_factory()); |
735 if (target_zone == nullptr) target_zone = zone(); | 708 if (target_zone == nullptr) target_zone = zone(); |
736 DeclarationScope* result = new (target_zone) | 709 DeclarationScope* result = new (target_zone) |
737 DeclarationScope(zone(), scope(), FUNCTION_SCOPE, kind); | 710 DeclarationScope(zone(), scope(), FUNCTION_SCOPE, kind); |
738 // TODO(verwaest): Move into the DeclarationScope constructor. | 711 // TODO(verwaest): Move into the DeclarationScope constructor. |
739 if (!IsArrowFunction(kind)) { | 712 if (!IsArrowFunction(kind)) { |
740 result->DeclareDefaultFunctionVariables(ast_value_factory()); | 713 result->DeclareDefaultFunctionVariables(ast_value_factory()); |
741 } | 714 } |
| 715 |
742 return result; | 716 return result; |
743 } | 717 } |
744 | 718 |
745 V8_INLINE DeclarationScope* GetDeclarationScope() const { | 719 V8_INLINE DeclarationScope* GetDeclarationScope() const { |
746 return scope()->GetDeclarationScope(); | 720 return scope()->GetDeclarationScope(); |
747 } | 721 } |
748 V8_INLINE DeclarationScope* GetClosureScope() const { | 722 V8_INLINE DeclarationScope* GetClosureScope() const { |
749 return scope()->GetClosureScope(); | 723 return scope()->GetClosureScope(); |
750 } | 724 } |
751 | 725 |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1189 ExpressionT ParseUnaryExpression(bool* ok); | 1163 ExpressionT ParseUnaryExpression(bool* ok); |
1190 ExpressionT ParsePostfixExpression(bool* ok); | 1164 ExpressionT ParsePostfixExpression(bool* ok); |
1191 ExpressionT ParseLeftHandSideExpression(bool* ok); | 1165 ExpressionT ParseLeftHandSideExpression(bool* ok); |
1192 ExpressionT ParseMemberWithNewPrefixesExpression(bool* is_async, bool* ok); | 1166 ExpressionT ParseMemberWithNewPrefixesExpression(bool* is_async, bool* ok); |
1193 ExpressionT ParseMemberExpression(bool* is_async, bool* ok); | 1167 ExpressionT ParseMemberExpression(bool* is_async, bool* ok); |
1194 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 1168 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
1195 bool* is_async, bool* ok); | 1169 bool* is_async, bool* ok); |
1196 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, | 1170 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, |
1197 const FormalParametersT& parameters, | 1171 const FormalParametersT& parameters, |
1198 bool* ok); | 1172 bool* ok); |
1199 void ParseAsyncFunctionBody(Scope* scope, StatementListT body, | |
1200 FunctionKind kind, FunctionBodyType type, | |
1201 bool accept_IN, int pos, bool* ok); | |
1202 ExpressionT ParseAsyncFunctionLiteral(bool* ok); | 1173 ExpressionT ParseAsyncFunctionLiteral(bool* ok); |
1203 ExpressionT ParseClassLiteral(IdentifierT name, | 1174 ExpressionT ParseClassLiteral(IdentifierT name, |
1204 Scanner::Location class_name_location, | 1175 Scanner::Location class_name_location, |
1205 bool name_is_strict_reserved, | 1176 bool name_is_strict_reserved, |
1206 int class_token_pos, bool* ok); | 1177 int class_token_pos, bool* ok); |
1207 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 1178 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
1208 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 1179 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
1209 ExpressionT ParseNewTargetExpression(bool* ok); | 1180 ExpressionT ParseNewTargetExpression(bool* ok); |
1210 | 1181 |
1211 void ParseFormalParameter(FormalParametersT* parameters, bool* ok); | 1182 void ParseFormalParameter(FormalParametersT* parameters, bool* ok); |
(...skipping 12 matching lines...) Expand all Loading... |
1224 StatementT ParseHoistableDeclaration(ZoneList<const AstRawString*>* names, | 1195 StatementT ParseHoistableDeclaration(ZoneList<const AstRawString*>* names, |
1225 bool default_export, bool* ok); | 1196 bool default_export, bool* ok); |
1226 StatementT ParseHoistableDeclaration(int pos, ParseFunctionFlags flags, | 1197 StatementT ParseHoistableDeclaration(int pos, ParseFunctionFlags flags, |
1227 ZoneList<const AstRawString*>* names, | 1198 ZoneList<const AstRawString*>* names, |
1228 bool default_export, bool* ok); | 1199 bool default_export, bool* ok); |
1229 StatementT ParseClassDeclaration(ZoneList<const AstRawString*>* names, | 1200 StatementT ParseClassDeclaration(ZoneList<const AstRawString*>* names, |
1230 bool default_export, bool* ok); | 1201 bool default_export, bool* ok); |
1231 StatementT ParseNativeDeclaration(bool* ok); | 1202 StatementT ParseNativeDeclaration(bool* ok); |
1232 | 1203 |
1233 // Consumes the ending }. | 1204 // Consumes the ending }. |
1234 void ParseFunctionBody(StatementListT result, IdentifierT function_name, | 1205 void ParseFunctionBody(StatementListT result, BlockT* init_block, |
1235 int pos, const FormalParametersT& parameters, | 1206 IdentifierT function_name, int pos, |
1236 FunctionKind kind, | 1207 const FormalParametersT& parameters, FunctionKind kind, |
1237 FunctionLiteral::FunctionType function_type, bool* ok); | 1208 FunctionLiteral::FunctionType function_type, bool* ok); |
1238 | 1209 |
1239 // Under some circumstances, we allow preparsing to abort if the preparsed | 1210 // Under some circumstances, we allow preparsing to abort if the preparsed |
1240 // function is "long and trivial", and fully parse instead. Our current | 1211 // function is "long and trivial", and fully parse instead. Our current |
1241 // definition of "long and trivial" is: | 1212 // definition of "long and trivial" is: |
1242 // - over kLazyParseTrialLimit statements | 1213 // - over kLazyParseTrialLimit statements |
1243 // - all starting with an identifier (i.e., no if, for, while, etc.) | 1214 // - all starting with an identifier (i.e., no if, for, while, etc.) |
1244 static const int kLazyParseTrialLimit = 200; | 1215 static const int kLazyParseTrialLimit = 200; |
1245 | 1216 |
1246 // TODO(nikolaos, marja): The first argument should not really be passed | 1217 // TODO(nikolaos, marja): The first argument should not really be passed |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1488 friend class DiscardableZoneScope; | 1459 friend class DiscardableZoneScope; |
1489 }; | 1460 }; |
1490 | 1461 |
1491 template <typename Impl> | 1462 template <typename Impl> |
1492 ParserBase<Impl>::FunctionState::FunctionState( | 1463 ParserBase<Impl>::FunctionState::FunctionState( |
1493 FunctionState** function_state_stack, ScopeState** scope_stack, | 1464 FunctionState** function_state_stack, ScopeState** scope_stack, |
1494 DeclarationScope* scope) | 1465 DeclarationScope* scope) |
1495 : ScopeState(scope_stack, scope), | 1466 : ScopeState(scope_stack, scope), |
1496 next_materialized_literal_index_(0), | 1467 next_materialized_literal_index_(0), |
1497 expected_property_count_(0), | 1468 expected_property_count_(0), |
1498 generator_object_variable_(nullptr), | |
1499 promise_variable_(nullptr), | |
1500 function_state_stack_(function_state_stack), | 1469 function_state_stack_(function_state_stack), |
1501 outer_function_state_(*function_state_stack), | 1470 outer_function_state_(*function_state_stack), |
1502 destructuring_assignments_to_rewrite_(16, scope->zone()), | 1471 destructuring_assignments_to_rewrite_(16, scope->zone()), |
1503 tail_call_expressions_(scope->zone()), | 1472 tail_call_expressions_(scope->zone()), |
1504 return_expr_context_(ReturnExprContext::kInsideValidBlock), | 1473 return_expr_context_(ReturnExprContext::kInsideValidBlock), |
1505 non_patterns_to_rewrite_(0, scope->zone()), | 1474 non_patterns_to_rewrite_(0, scope->zone()), |
1506 reported_errors_(16, scope->zone()), | 1475 reported_errors_(16, scope->zone()), |
1507 next_function_is_likely_called_(false), | 1476 next_function_is_likely_called_(false), |
1508 previous_function_was_likely_called_(false) { | 1477 previous_function_was_likely_called_(false) { |
1509 *function_state_stack = this; | 1478 *function_state_stack = this; |
(...skipping 1398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2908 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( | 2877 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseYieldExpression( |
2909 bool accept_IN, bool* ok) { | 2878 bool accept_IN, bool* ok) { |
2910 // YieldExpression :: | 2879 // YieldExpression :: |
2911 // 'yield' ([no line terminator] '*'? AssignmentExpression)? | 2880 // 'yield' ([no line terminator] '*'? AssignmentExpression)? |
2912 int pos = peek_position(); | 2881 int pos = peek_position(); |
2913 classifier()->RecordPatternError( | 2882 classifier()->RecordPatternError( |
2914 scanner()->peek_location(), MessageTemplate::kInvalidDestructuringTarget); | 2883 scanner()->peek_location(), MessageTemplate::kInvalidDestructuringTarget); |
2915 classifier()->RecordFormalParameterInitializerError( | 2884 classifier()->RecordFormalParameterInitializerError( |
2916 scanner()->peek_location(), MessageTemplate::kYieldInParameter); | 2885 scanner()->peek_location(), MessageTemplate::kYieldInParameter); |
2917 Expect(Token::YIELD, CHECK_OK); | 2886 Expect(Token::YIELD, CHECK_OK); |
2918 ExpressionT generator_object = | 2887 |
2919 factory()->NewVariableProxy(function_state_->generator_object_variable()); | |
2920 // The following initialization is necessary. | 2888 // The following initialization is necessary. |
2921 ExpressionT expression = impl()->EmptyExpression(); | 2889 ExpressionT expression = impl()->EmptyExpression(); |
2922 bool delegating = false; // yield* | 2890 bool delegating = false; // yield* |
2923 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { | 2891 if (!scanner()->HasAnyLineTerminatorBeforeNext()) { |
2924 if (Check(Token::MUL)) delegating = true; | 2892 if (Check(Token::MUL)) delegating = true; |
2925 switch (peek()) { | 2893 switch (peek()) { |
2926 case Token::EOS: | 2894 case Token::EOS: |
2927 case Token::SEMICOLON: | 2895 case Token::SEMICOLON: |
2928 case Token::RBRACE: | 2896 case Token::RBRACE: |
2929 case Token::RBRACK: | 2897 case Token::RBRACK: |
2930 case Token::RPAREN: | 2898 case Token::RPAREN: |
2931 case Token::COLON: | 2899 case Token::COLON: |
2932 case Token::COMMA: | 2900 case Token::COMMA: |
2933 // The above set of tokens is the complete set of tokens that can appear | 2901 // The above set of tokens is the complete set of tokens that can appear |
2934 // after an AssignmentExpression, and none of them can start an | 2902 // after an AssignmentExpression, and none of them can start an |
2935 // AssignmentExpression. This allows us to avoid looking for an RHS for | 2903 // AssignmentExpression. This allows us to avoid looking for an RHS for |
2936 // a regular yield, given only one look-ahead token. | 2904 // a regular yield, given only one look-ahead token. |
2937 if (!delegating) break; | 2905 if (!delegating) break; |
2938 // Delegating yields require an RHS; fall through. | 2906 // Delegating yields require an RHS; fall through. |
2939 default: | 2907 default: |
2940 expression = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2908 expression = ParseAssignmentExpression(accept_IN, CHECK_OK); |
2941 impl()->RewriteNonPattern(CHECK_OK); | 2909 impl()->RewriteNonPattern(CHECK_OK); |
2942 break; | 2910 break; |
2943 } | 2911 } |
2944 } | 2912 } |
2945 | 2913 |
2946 if (delegating) { | 2914 if (delegating) { |
2947 return impl()->RewriteYieldStar(generator_object, expression, pos); | 2915 return impl()->RewriteYieldStar(expression, pos); |
2948 } | 2916 } |
2949 | 2917 |
2950 expression = impl()->BuildIteratorResult(expression, false); | 2918 expression = impl()->BuildIteratorResult(expression, false); |
2951 // Hackily disambiguate o from o.next and o [Symbol.iterator](). | 2919 // Hackily disambiguate o from o.next and o [Symbol.iterator](). |
2952 // TODO(verwaest): Come up with a better solution. | 2920 // TODO(verwaest): Come up with a better solution. |
2953 ExpressionT yield = factory()->NewYield(generator_object, expression, pos, | 2921 ExpressionT yield = factory()->NewYield( |
2954 Yield::kOnExceptionThrow); | 2922 expression, pos, Yield::kOnExceptionThrow, Yield::kNormal); |
2955 return yield; | 2923 return yield; |
2956 } | 2924 } |
2957 | 2925 |
2958 // Precedence = 3 | 2926 // Precedence = 3 |
2959 template <typename Impl> | 2927 template <typename Impl> |
2960 typename ParserBase<Impl>::ExpressionT | 2928 typename ParserBase<Impl>::ExpressionT |
2961 ParserBase<Impl>::ParseConditionalExpression(bool accept_IN, | 2929 ParserBase<Impl>::ParseConditionalExpression(bool accept_IN, |
2962 bool* ok) { | 2930 bool* ok) { |
2963 // ConditionalExpression :: | 2931 // ConditionalExpression :: |
2964 // LogicalOrExpression | 2932 // LogicalOrExpression |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3104 } else if (is_async_function() && peek() == Token::AWAIT) { | 3072 } else if (is_async_function() && peek() == Token::AWAIT) { |
3105 classifier()->RecordFormalParameterInitializerError( | 3073 classifier()->RecordFormalParameterInitializerError( |
3106 scanner()->peek_location(), | 3074 scanner()->peek_location(), |
3107 MessageTemplate::kAwaitExpressionFormalParameter); | 3075 MessageTemplate::kAwaitExpressionFormalParameter); |
3108 | 3076 |
3109 int await_pos = peek_position(); | 3077 int await_pos = peek_position(); |
3110 Consume(Token::AWAIT); | 3078 Consume(Token::AWAIT); |
3111 | 3079 |
3112 ExpressionT value = ParseUnaryExpression(CHECK_OK); | 3080 ExpressionT value = ParseUnaryExpression(CHECK_OK); |
3113 | 3081 |
3114 return impl()->RewriteAwaitExpression(value, await_pos); | 3082 return factory()->NewYield(value, await_pos, Yield::kOnExceptionRethrow, |
| 3083 Yield::kAwait); |
3115 } else { | 3084 } else { |
3116 return ParsePostfixExpression(ok); | 3085 return ParsePostfixExpression(ok); |
3117 } | 3086 } |
3118 } | 3087 } |
3119 | 3088 |
3120 template <typename Impl> | 3089 template <typename Impl> |
3121 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression( | 3090 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePostfixExpression( |
3122 bool* ok) { | 3091 bool* ok) { |
3123 // PostfixExpression :: | 3092 // PostfixExpression :: |
3124 // LeftHandSideExpression ('++' | '--')? | 3093 // LeftHandSideExpression ('++' | '--')? |
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3938 impl()->ReportUnexpectedToken(scanner()->current_token()); | 3907 impl()->ReportUnexpectedToken(scanner()->current_token()); |
3939 return impl()->NullStatement(); | 3908 return impl()->NullStatement(); |
3940 } | 3909 } |
3941 Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement)); | 3910 Expect(Token::FUNCTION, CHECK_OK_CUSTOM(NullStatement)); |
3942 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; | 3911 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; |
3943 return ParseHoistableDeclaration(pos, flags, names, default_export, ok); | 3912 return ParseHoistableDeclaration(pos, flags, names, default_export, ok); |
3944 } | 3913 } |
3945 | 3914 |
3946 template <typename Impl> | 3915 template <typename Impl> |
3947 void ParserBase<Impl>::ParseFunctionBody( | 3916 void ParserBase<Impl>::ParseFunctionBody( |
3948 typename ParserBase<Impl>::StatementListT result, IdentifierT function_name, | 3917 typename ParserBase<Impl>::StatementListT result, |
| 3918 typename ParserBase<Impl>::BlockT* init_block, IdentifierT function_name, |
3949 int pos, const FormalParametersT& parameters, FunctionKind kind, | 3919 int pos, const FormalParametersT& parameters, FunctionKind kind, |
3950 FunctionLiteral::FunctionType function_type, bool* ok) { | 3920 FunctionLiteral::FunctionType function_type, bool* ok) { |
3951 static const int kFunctionNameAssignmentIndex = 0; | |
3952 if (function_type == FunctionLiteral::kNamedExpression) { | |
3953 DCHECK(!impl()->IsEmptyIdentifier(function_name)); | |
3954 // If we have a named function expression, we add a local variable | |
3955 // declaration to the body of the function with the name of the | |
3956 // function and let it refer to the function itself (closure). | |
3957 // Not having parsed the function body, the language mode may still change, | |
3958 // so we reserve a spot and create the actual const assignment later. | |
3959 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length()); | |
3960 result->Add(impl()->NullStatement(), zone()); | |
3961 } | |
3962 | |
3963 DeclarationScope* function_scope = scope()->AsDeclarationScope(); | 3921 DeclarationScope* function_scope = scope()->AsDeclarationScope(); |
3964 DeclarationScope* inner_scope = function_scope; | 3922 DeclarationScope* inner_scope = function_scope; |
3965 BlockT inner_block = impl()->NullBlock(); | 3923 BlockT inner_block = impl()->NullBlock(); |
3966 | 3924 |
3967 StatementListT body = result; | 3925 StatementListT body = result; |
3968 if (!parameters.is_simple) { | 3926 if (!parameters.is_simple) { |
3969 inner_scope = NewVarblockScope(); | 3927 inner_scope = NewVarblockScope(); |
3970 inner_scope->set_start_position(scanner()->location().beg_pos); | 3928 inner_scope->set_start_position(scanner()->location().beg_pos); |
3971 inner_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); | 3929 inner_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); |
3972 inner_block->set_scope(inner_scope); | 3930 inner_block->set_scope(inner_scope); |
3973 body = inner_block->statements(); | 3931 body = inner_block->statements(); |
3974 } | 3932 } |
3975 | 3933 |
3976 { | 3934 { |
3977 BlockState block_state(&scope_state_, inner_scope); | 3935 BlockState block_state(&scope_state_, inner_scope); |
3978 | 3936 |
3979 if (IsGeneratorFunction(kind)) { | 3937 ParseStatementList(body, Token::RBRACE, CHECK_OK_VOID); |
3980 impl()->ParseAndRewriteGeneratorFunctionBody(pos, kind, body, ok); | |
3981 } else if (IsAsyncFunction(kind)) { | |
3982 const bool accept_IN = true; | |
3983 ParseAsyncFunctionBody(inner_scope, body, kind, FunctionBodyType::kNormal, | |
3984 accept_IN, pos, CHECK_OK_VOID); | |
3985 } else { | |
3986 ParseStatementList(body, Token::RBRACE, CHECK_OK_VOID); | |
3987 } | |
3988 | 3938 |
3989 if (IsDerivedConstructor(kind)) { | 3939 if (IsDerivedConstructor(kind)) { |
3990 body->Add(factory()->NewReturnStatement(impl()->ThisExpression(), | 3940 body->Add(factory()->NewReturnStatement(impl()->ThisExpression(), |
3991 kNoSourcePosition), | 3941 kNoSourcePosition), |
3992 zone()); | 3942 zone()); |
3993 } | 3943 } |
3994 } | 3944 } |
3995 | 3945 |
3996 Expect(Token::RBRACE, CHECK_OK_VOID); | 3946 Expect(Token::RBRACE, CHECK_OK_VOID); |
3997 scope()->set_end_position(scanner()->location().end_pos); | 3947 scope()->set_end_position(scanner()->location().end_pos); |
3998 | 3948 |
3999 if (!parameters.is_simple) { | 3949 if (!parameters.is_simple) { |
4000 DCHECK_NOT_NULL(inner_scope); | 3950 DCHECK_NOT_NULL(inner_scope); |
4001 DCHECK_EQ(function_scope, scope()); | 3951 DCHECK_EQ(function_scope, scope()); |
4002 DCHECK_EQ(function_scope, inner_scope->outer_scope()); | 3952 DCHECK_EQ(function_scope, inner_scope->outer_scope()); |
4003 impl()->SetLanguageMode(function_scope, inner_scope->language_mode()); | 3953 impl()->SetLanguageMode(function_scope, inner_scope->language_mode()); |
4004 BlockT init_block = | 3954 *init_block = |
4005 impl()->BuildParameterInitializationBlock(parameters, CHECK_OK_VOID); | 3955 impl()->BuildParameterInitializationBlock(parameters, CHECK_OK_VOID); |
4006 | 3956 |
4007 if (is_sloppy(inner_scope->language_mode())) { | 3957 if (is_sloppy(inner_scope->language_mode())) { |
4008 impl()->InsertSloppyBlockFunctionVarBindings(inner_scope); | 3958 impl()->InsertSloppyBlockFunctionVarBindings(inner_scope); |
4009 } | 3959 } |
4010 | 3960 |
4011 // TODO(littledan): Merge the two rejection blocks into one | |
4012 if (IsAsyncFunction(kind)) { | |
4013 init_block = impl()->BuildRejectPromiseOnException(init_block); | |
4014 } | |
4015 | |
4016 inner_scope->set_end_position(scanner()->location().end_pos); | 3961 inner_scope->set_end_position(scanner()->location().end_pos); |
4017 if (inner_scope->FinalizeBlockScope() != nullptr) { | 3962 if (inner_scope->FinalizeBlockScope() != nullptr) { |
4018 impl()->CheckConflictingVarDeclarations(inner_scope, CHECK_OK_VOID); | 3963 impl()->CheckConflictingVarDeclarations(inner_scope, CHECK_OK_VOID); |
4019 impl()->InsertShadowingVarBindingInitializers(inner_block); | 3964 impl()->InsertShadowingVarBindingInitializers(inner_block); |
4020 } | 3965 } |
4021 inner_scope = nullptr; | 3966 inner_scope = nullptr; |
4022 | 3967 |
4023 result->Add(init_block, zone()); | |
4024 result->Add(inner_block, zone()); | 3968 result->Add(inner_block, zone()); |
4025 } else { | 3969 } else { |
4026 DCHECK_EQ(inner_scope, function_scope); | 3970 DCHECK_EQ(inner_scope, function_scope); |
4027 if (is_sloppy(function_scope->language_mode())) { | 3971 if (is_sloppy(function_scope->language_mode())) { |
4028 impl()->InsertSloppyBlockFunctionVarBindings(function_scope); | 3972 impl()->InsertSloppyBlockFunctionVarBindings(function_scope); |
4029 } | 3973 } |
4030 } | 3974 } |
4031 | 3975 |
4032 if (!IsArrowFunction(kind)) { | 3976 if (!IsArrowFunction(kind)) { |
4033 // Declare arguments after parsing the function since lexical 'arguments' | 3977 // Declare arguments after parsing the function since lexical 'arguments' |
4034 // masks the arguments object. Declare arguments before declaring the | 3978 // masks the arguments object. Declare arguments before declaring the |
4035 // function var since the arguments object masks 'function arguments'. | 3979 // function var since the arguments object masks 'function arguments'. |
4036 function_scope->DeclareArguments(ast_value_factory()); | 3980 function_scope->DeclareArguments(ast_value_factory()); |
4037 } | 3981 } |
4038 | 3982 |
4039 impl()->CreateFunctionNameAssignment(function_name, pos, function_type, | 3983 impl()->CreateFunctionNameVariable(function_name, pos, function_type, |
4040 function_scope, result, | 3984 function_scope); |
4041 kFunctionNameAssignmentIndex); | |
4042 impl()->MarkCollectedTailCallExpressions(); | 3985 impl()->MarkCollectedTailCallExpressions(); |
4043 } | 3986 } |
4044 | 3987 |
4045 template <typename Impl> | 3988 template <typename Impl> |
4046 void ParserBase<Impl>::CheckArityRestrictions(int param_count, | 3989 void ParserBase<Impl>::CheckArityRestrictions(int param_count, |
4047 FunctionKind function_kind, | 3990 FunctionKind function_kind, |
4048 bool has_rest, | 3991 bool has_rest, |
4049 int formals_start_pos, | 3992 int formals_start_pos, |
4050 int formals_end_pos, bool* ok) { | 3993 int formals_end_pos, bool* ok) { |
4051 if (IsGetterFunction(function_kind)) { | 3994 if (IsGetterFunction(function_kind)) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4129 | 4072 |
4130 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 4073 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
4131 // ASI inserts `;` after arrow parameters if a line terminator is found. | 4074 // ASI inserts `;` after arrow parameters if a line terminator is found. |
4132 // `=> ...` is never a valid expression, so report as syntax error. | 4075 // `=> ...` is never a valid expression, so report as syntax error. |
4133 // If next token is not `=>`, it's a syntax error anyways. | 4076 // If next token is not `=>`, it's a syntax error anyways. |
4134 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 4077 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
4135 *ok = false; | 4078 *ok = false; |
4136 return impl()->EmptyExpression(); | 4079 return impl()->EmptyExpression(); |
4137 } | 4080 } |
4138 | 4081 |
| 4082 BlockT parameter_init_block = impl()->NullBlock(); |
4139 StatementListT body = impl()->NullStatementList(); | 4083 StatementListT body = impl()->NullStatementList(); |
4140 int materialized_literal_count = -1; | 4084 int materialized_literal_count = -1; |
4141 int expected_property_count = -1; | 4085 int expected_property_count = -1; |
4142 int function_literal_id = GetNextFunctionLiteralId(); | 4086 int function_literal_id = GetNextFunctionLiteralId(); |
4143 | 4087 |
4144 FunctionKind kind = formal_parameters.scope->function_kind(); | 4088 FunctionKind kind = formal_parameters.scope->function_kind(); |
4145 FunctionLiteral::EagerCompileHint eager_compile_hint = | 4089 FunctionLiteral::EagerCompileHint eager_compile_hint = |
4146 default_eager_compile_hint_; | 4090 default_eager_compile_hint_; |
4147 bool can_preparse = impl()->parse_lazily() && | 4091 bool can_preparse = impl()->parse_lazily() && |
4148 eager_compile_hint == FunctionLiteral::kShouldLazyCompile; | 4092 eager_compile_hint == FunctionLiteral::kShouldLazyCompile; |
4149 // TODO(marja): consider lazy-parsing inner arrow functions too. is_this | 4093 // TODO(marja): consider lazy-parsing inner arrow functions too. is_this |
4150 // handling in Scope::ResolveVariable needs to change. | 4094 // handling in Scope::ResolveVariable needs to change. |
4151 bool is_lazy_top_level_function = | 4095 bool is_lazy_top_level_function = |
4152 can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables(); | 4096 can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables(); |
4153 bool should_be_used_once_hint = false; | 4097 bool should_be_used_once_hint = false; |
4154 bool has_braces = true; | 4098 bool has_braces = true; |
4155 { | 4099 { |
4156 FunctionState function_state(&function_state_, &scope_state_, | 4100 FunctionState function_state(&function_state_, &scope_state_, |
4157 formal_parameters.scope); | 4101 formal_parameters.scope); |
4158 | 4102 if (kind == kAsyncArrowFunction) { |
| 4103 function_state.scope()->ForceContextAllocation(); |
| 4104 } |
4159 function_state.SkipMaterializedLiterals( | 4105 function_state.SkipMaterializedLiterals( |
4160 formal_parameters.materialized_literals_count); | 4106 formal_parameters.materialized_literals_count); |
4161 | 4107 |
4162 Expect(Token::ARROW, CHECK_OK); | 4108 Expect(Token::ARROW, CHECK_OK); |
4163 | 4109 |
4164 if (peek() == Token::LBRACE) { | 4110 if (peek() == Token::LBRACE) { |
4165 // Multiple statement body | 4111 // Multiple statement body |
4166 DCHECK_EQ(scope(), formal_parameters.scope); | 4112 DCHECK_EQ(scope(), formal_parameters.scope); |
4167 if (is_lazy_top_level_function) { | 4113 if (is_lazy_top_level_function) { |
4168 // FIXME(marja): Arrow function parameters will be parsed even if the | 4114 // FIXME(marja): Arrow function parameters will be parsed even if the |
(...skipping 28 matching lines...) Expand all Loading... |
4197 // This is probably an initialization function. Inform the compiler it | 4143 // This is probably an initialization function. Inform the compiler it |
4198 // should also eager-compile this function, and that we expect it to | 4144 // should also eager-compile this function, and that we expect it to |
4199 // be used once. | 4145 // be used once. |
4200 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; | 4146 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; |
4201 should_be_used_once_hint = true; | 4147 should_be_used_once_hint = true; |
4202 } | 4148 } |
4203 } | 4149 } |
4204 if (!is_lazy_top_level_function) { | 4150 if (!is_lazy_top_level_function) { |
4205 Consume(Token::LBRACE); | 4151 Consume(Token::LBRACE); |
4206 body = impl()->NewStatementList(8); | 4152 body = impl()->NewStatementList(8); |
4207 impl()->ParseFunctionBody(body, impl()->EmptyIdentifier(), | 4153 impl()->ParseFunctionBody( |
4208 kNoSourcePosition, formal_parameters, kind, | 4154 body, ¶meter_init_block, impl()->EmptyIdentifier(), |
4209 FunctionLiteral::kAnonymousExpression, | 4155 kNoSourcePosition, formal_parameters, kind, |
4210 CHECK_OK); | 4156 FunctionLiteral::kAnonymousExpression, CHECK_OK); |
4211 materialized_literal_count = | 4157 materialized_literal_count = |
4212 function_state.materialized_literal_count(); | 4158 function_state.materialized_literal_count(); |
4213 expected_property_count = function_state.expected_property_count(); | 4159 expected_property_count = function_state.expected_property_count(); |
4214 } | 4160 } |
4215 } else { | 4161 } else { |
4216 // Single-expression body | 4162 // Single-expression body |
4217 has_braces = false; | 4163 has_braces = false; |
4218 int pos = position(); | |
4219 DCHECK(ReturnExprContext::kInsideValidBlock == | 4164 DCHECK(ReturnExprContext::kInsideValidBlock == |
4220 function_state_->return_expr_context()); | 4165 function_state_->return_expr_context()); |
4221 ReturnExprScope allow_tail_calls( | 4166 ReturnExprScope allow_tail_calls( |
4222 function_state_, ReturnExprContext::kInsideValidReturnStatement); | 4167 function_state_, ReturnExprContext::kInsideValidReturnStatement); |
4223 body = impl()->NewStatementList(1); | 4168 body = impl()->NewStatementList(1); |
4224 impl()->AddParameterInitializationBlock( | 4169 if (!formal_parameters.is_simple) { |
4225 formal_parameters, body, kind == kAsyncArrowFunction, CHECK_OK); | 4170 parameter_init_block = impl()->BuildParameterInitializationBlock( |
| 4171 formal_parameters, CHECK_OK); |
| 4172 } |
4226 ExpressionClassifier classifier(this); | 4173 ExpressionClassifier classifier(this); |
4227 if (kind == kAsyncArrowFunction) { | 4174 ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK); |
4228 ParseAsyncFunctionBody(scope(), body, kAsyncArrowFunction, | 4175 impl()->RewriteNonPattern(CHECK_OK); |
4229 FunctionBodyType::kSingleExpression, accept_IN, | 4176 body->Add( |
4230 pos, CHECK_OK); | 4177 factory()->NewReturnStatement(expression, expression->position()), |
4231 impl()->RewriteNonPattern(CHECK_OK); | 4178 zone()); |
4232 } else { | 4179 if (allow_tailcalls() && !is_sloppy(language_mode()) && |
4233 ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK); | 4180 kind != kAsyncArrowFunction) { |
4234 impl()->RewriteNonPattern(CHECK_OK); | 4181 // ES6 14.6.1 Static Semantics: IsInTailPosition |
4235 body->Add( | 4182 impl()->MarkTailPosition(expression); |
4236 factory()->NewReturnStatement(expression, expression->position()), | |
4237 zone()); | |
4238 if (allow_tailcalls() && !is_sloppy(language_mode())) { | |
4239 // ES6 14.6.1 Static Semantics: IsInTailPosition | |
4240 impl()->MarkTailPosition(expression); | |
4241 } | |
4242 } | 4183 } |
| 4184 |
4243 materialized_literal_count = function_state.materialized_literal_count(); | 4185 materialized_literal_count = function_state.materialized_literal_count(); |
4244 expected_property_count = function_state.expected_property_count(); | 4186 expected_property_count = function_state.expected_property_count(); |
4245 impl()->MarkCollectedTailCallExpressions(); | 4187 impl()->MarkCollectedTailCallExpressions(); |
4246 } | 4188 } |
4247 | 4189 |
4248 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 4190 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
4249 | 4191 |
4250 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 4192 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
4251 // which is not the same as "parameters of a strict function"; it only means | 4193 // which is not the same as "parameters of a strict function"; it only means |
4252 // that duplicates are not allowed. Of course, the arrow function may | 4194 // that duplicates are not allowed. Of course, the arrow function may |
(...skipping 19 matching lines...) Expand all Loading... |
4272 scope->start_position(), scope->end_position()); | 4214 scope->start_position(), scope->end_position()); |
4273 } | 4215 } |
4274 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 4216 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
4275 impl()->EmptyIdentifierString(), formal_parameters.scope, body, | 4217 impl()->EmptyIdentifierString(), formal_parameters.scope, body, |
4276 materialized_literal_count, expected_property_count, | 4218 materialized_literal_count, expected_property_count, |
4277 formal_parameters.num_parameters(), formal_parameters.function_length, | 4219 formal_parameters.num_parameters(), formal_parameters.function_length, |
4278 FunctionLiteral::kNoDuplicateParameters, | 4220 FunctionLiteral::kNoDuplicateParameters, |
4279 FunctionLiteral::kAnonymousExpression, eager_compile_hint, | 4221 FunctionLiteral::kAnonymousExpression, eager_compile_hint, |
4280 formal_parameters.scope->start_position(), has_braces, | 4222 formal_parameters.scope->start_position(), has_braces, |
4281 function_literal_id); | 4223 function_literal_id); |
| 4224 function_literal->set_parameter_init_block(parameter_init_block); |
4282 | 4225 |
4283 function_literal->set_function_token_position( | 4226 function_literal->set_function_token_position( |
4284 formal_parameters.scope->start_position()); | 4227 formal_parameters.scope->start_position()); |
4285 if (should_be_used_once_hint) { | 4228 if (should_be_used_once_hint) { |
4286 function_literal->set_should_be_used_once_hint(); | 4229 function_literal->set_should_be_used_once_hint(); |
4287 } | 4230 } |
4288 | 4231 |
4289 impl()->AddFunctionForNameInference(function_literal); | 4232 impl()->AddFunctionForNameInference(function_literal); |
4290 | 4233 |
4291 return function_literal; | 4234 return function_literal; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4357 impl()->DeclareClassProperty(name, property, property_kind, is_static, | 4300 impl()->DeclareClassProperty(name, property, property_kind, is_static, |
4358 is_constructor, &class_info, CHECK_OK); | 4301 is_constructor, &class_info, CHECK_OK); |
4359 impl()->InferFunctionName(); | 4302 impl()->InferFunctionName(); |
4360 } | 4303 } |
4361 | 4304 |
4362 Expect(Token::RBRACE, CHECK_OK); | 4305 Expect(Token::RBRACE, CHECK_OK); |
4363 return impl()->RewriteClassLiteral(name, &class_info, class_token_pos, ok); | 4306 return impl()->RewriteClassLiteral(name, &class_info, class_token_pos, ok); |
4364 } | 4307 } |
4365 | 4308 |
4366 template <typename Impl> | 4309 template <typename Impl> |
4367 void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope, StatementListT body, | |
4368 FunctionKind kind, | |
4369 FunctionBodyType body_type, | |
4370 bool accept_IN, int pos, | |
4371 bool* ok) { | |
4372 impl()->PrepareAsyncFunctionBody(body, kind, pos); | |
4373 | |
4374 BlockT block = factory()->NewBlock(nullptr, 8, true, kNoSourcePosition); | |
4375 | |
4376 ExpressionT return_value = impl()->EmptyExpression(); | |
4377 if (body_type == FunctionBodyType::kNormal) { | |
4378 ParseStatementList(block->statements(), Token::RBRACE, | |
4379 CHECK_OK_CUSTOM(Void)); | |
4380 return_value = factory()->NewUndefinedLiteral(kNoSourcePosition); | |
4381 } else { | |
4382 return_value = ParseAssignmentExpression(accept_IN, CHECK_OK_CUSTOM(Void)); | |
4383 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(Void)); | |
4384 } | |
4385 | |
4386 impl()->RewriteAsyncFunctionBody(body, block, return_value, | |
4387 CHECK_OK_CUSTOM(Void)); | |
4388 scope->set_end_position(scanner()->location().end_pos); | |
4389 } | |
4390 | |
4391 template <typename Impl> | |
4392 typename ParserBase<Impl>::ExpressionT | 4310 typename ParserBase<Impl>::ExpressionT |
4393 ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) { | 4311 ParserBase<Impl>::ParseAsyncFunctionLiteral(bool* ok) { |
4394 // AsyncFunctionLiteral :: | 4312 // AsyncFunctionLiteral :: |
4395 // async [no LineTerminator here] function ( FormalParameters[Await] ) | 4313 // async [no LineTerminator here] function ( FormalParameters[Await] ) |
4396 // { AsyncFunctionBody } | 4314 // { AsyncFunctionBody } |
4397 // | 4315 // |
4398 // async [no LineTerminator here] function BindingIdentifier[Await] | 4316 // async [no LineTerminator here] function BindingIdentifier[Await] |
4399 // ( FormalParameters[Await] ) { AsyncFunctionBody } | 4317 // ( FormalParameters[Await] ) { AsyncFunctionBody } |
4400 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); | 4318 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); |
4401 int pos = position(); | 4319 int pos = position(); |
(...skipping 1321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5723 return; | 5641 return; |
5724 } | 5642 } |
5725 } | 5643 } |
5726 | 5644 |
5727 #undef CHECK_OK_VOID | 5645 #undef CHECK_OK_VOID |
5728 | 5646 |
5729 } // namespace internal | 5647 } // namespace internal |
5730 } // namespace v8 | 5648 } // namespace v8 |
5731 | 5649 |
5732 #endif // V8_PARSING_PARSER_BASE_H | 5650 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |