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

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

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

Powered by Google App Engine
This is Rietveld 408576698