Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(540)

Side by Side Diff: src/parsing/parser-base.h

Issue 2654423004: [async-functions] support await expressions in finally statements (Closed)
Patch Set: Get everything working (except possibly inspector tests) Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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, &parameter_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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698