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