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

Side by Side Diff: src/parsing/parser.cc

Issue 2233923003: Desugar async/await to create the resulting Promise upfront (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: format Created 4 years, 3 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
« no previous file with comments | « src/parsing/parser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "src/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/ast/ast-expression-rewriter.h" 10 #include "src/ast/ast-expression-rewriter.h"
(...skipping 2445 matching lines...) Expand 10 before | Expand all | Expand 10 after
2456 // ES6 14.6.1 Static Semantics: IsInTailPosition 2456 // ES6 14.6.1 Static Semantics: IsInTailPosition
2457 function_state_->AddImplicitTailCallExpression(return_value); 2457 function_state_->AddImplicitTailCallExpression(return_value);
2458 } 2458 }
2459 } 2459 }
2460 } 2460 }
2461 ExpectSemicolon(CHECK_OK); 2461 ExpectSemicolon(CHECK_OK);
2462 2462
2463 if (is_generator()) { 2463 if (is_generator()) {
2464 return_value = BuildIteratorResult(return_value, true); 2464 return_value = BuildIteratorResult(return_value, true);
2465 } else if (is_async_function()) { 2465 } else if (is_async_function()) {
2466 return_value = BuildPromiseResolve(return_value, return_value->position()); 2466 return_value = BuildResolvePromise(return_value, return_value->position());
2467 } 2467 }
2468 2468
2469 result = factory()->NewReturnStatement(return_value, loc.beg_pos); 2469 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2470 2470
2471 DeclarationScope* decl_scope = GetDeclarationScope(); 2471 DeclarationScope* decl_scope = GetDeclarationScope();
2472 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) { 2472 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
2473 ReportMessageAt(loc, MessageTemplate::kIllegalReturn); 2473 ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
2474 *ok = false; 2474 *ok = false;
2475 return NULL; 2475 return NULL;
2476 } 2476 }
(...skipping 1308 matching lines...) Expand 10 before | Expand all | Expand 10 after
3785 AddFormalParameter(parameters, expr, initializer, end_pos, is_rest); 3785 AddFormalParameter(parameters, expr, initializer, end_pos, is_rest);
3786 } 3786 }
3787 3787
3788 void Parser::DesugarAsyncFunctionBody(const AstRawString* function_name, 3788 void Parser::DesugarAsyncFunctionBody(const AstRawString* function_name,
3789 Scope* scope, ZoneList<Statement*>* body, 3789 Scope* scope, ZoneList<Statement*>* body,
3790 ExpressionClassifier* classifier, 3790 ExpressionClassifier* classifier,
3791 FunctionKind kind, 3791 FunctionKind kind,
3792 FunctionBodyType body_type, 3792 FunctionBodyType body_type,
3793 bool accept_IN, int pos, bool* ok) { 3793 bool accept_IN, int pos, bool* ok) {
3794 // function async_function() { 3794 // function async_function() {
3795 // try { 3795 // .generator_object = %CreateGeneratorObject();
3796 // .generator_object = %CreateGeneratorObject(); 3796 // BuildRejectPromiseOnException({
3797 // ... function body ... 3797 // ... function body ...
3798 // } catch (e) { 3798 // return %ResolvePromise(.promise, expr), .promise;
3799 // return Promise.reject(e); 3799 // })
3800 // }
3801 // } 3800 // }
3802 scope->ForceContextAllocation(); 3801 scope->ForceContextAllocation();
3803 Variable* temp = 3802 Variable* temp =
3804 NewTemporary(ast_value_factory()->dot_generator_object_string()); 3803 NewTemporary(ast_value_factory()->dot_generator_object_string());
3805 function_state_->set_generator_object_variable(temp); 3804 function_state_->set_generator_object_variable(temp);
3806 3805
3807 Expression* init_generator_variable = factory()->NewAssignment( 3806 Expression* init_generator_variable = factory()->NewAssignment(
3808 Token::INIT, factory()->NewVariableProxy(temp), 3807 Token::INIT, factory()->NewVariableProxy(temp),
3809 BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition); 3808 BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition);
3810 body->Add(factory()->NewExpressionStatement(init_generator_variable, 3809 body->Add(factory()->NewExpressionStatement(init_generator_variable,
3811 kNoSourcePosition), 3810 kNoSourcePosition),
3812 zone()); 3811 zone());
3813 3812
3814 Block* try_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); 3813 Block* block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
3815
3816 ZoneList<Statement*>* inner_body = try_block->statements();
3817 3814
3818 Expression* return_value = nullptr; 3815 Expression* return_value = nullptr;
3819 if (body_type == FunctionBodyType::kNormal) { 3816 if (body_type == FunctionBodyType::kNormal) {
3820 ParseStatementList(inner_body, Token::RBRACE, CHECK_OK_VOID); 3817 ParseStatementList(block->statements(), Token::RBRACE, CHECK_OK_VOID);
3821 return_value = factory()->NewUndefinedLiteral(kNoSourcePosition); 3818 return_value = factory()->NewUndefinedLiteral(kNoSourcePosition);
3822 } else { 3819 } else {
3823 return_value = 3820 return_value =
3824 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK_VOID); 3821 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK_VOID);
3825 RewriteNonPattern(classifier, CHECK_OK_VOID); 3822 RewriteNonPattern(classifier, CHECK_OK_VOID);
3826 } 3823 }
3827 3824
3828 return_value = BuildPromiseResolve(return_value, return_value->position()); 3825 return_value = BuildResolvePromise(return_value, return_value->position());
3829 inner_body->Add( 3826 block->statements()->Add(
3830 factory()->NewReturnStatement(return_value, return_value->position()), 3827 factory()->NewReturnStatement(return_value, return_value->position()),
3831 zone()); 3828 zone());
3832 body->Add(BuildRejectPromiseOnException(try_block), zone()); 3829 block = BuildRejectPromiseOnException(block, CHECK_OK_VOID);
3830 body->Add(block, zone());
3833 scope->set_end_position(scanner()->location().end_pos); 3831 scope->set_end_position(scanner()->location().end_pos);
3834 } 3832 }
3835 3833
3836 DoExpression* Parser::ParseDoExpression(bool* ok) { 3834 DoExpression* Parser::ParseDoExpression(bool* ok) {
3837 // AssignmentExpression :: 3835 // AssignmentExpression ::
3838 // do '{' StatementList '}' 3836 // do '{' StatementList '}'
3839 int pos = peek_position(); 3837 int pos = peek_position();
3840 3838
3841 Expect(Token::DO, CHECK_OK); 3839 Expect(Token::DO, CHECK_OK);
3842 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); 3840 Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
4380 param_scope = block_state.FinalizedBlockScope(); 4378 param_scope = block_state.FinalizedBlockScope();
4381 if (param_scope != nullptr) { 4379 if (param_scope != nullptr) {
4382 CheckConflictingVarDeclarations(param_scope, CHECK_OK); 4380 CheckConflictingVarDeclarations(param_scope, CHECK_OK);
4383 } 4381 }
4384 init_block->statements()->Add(param_block, zone()); 4382 init_block->statements()->Add(param_block, zone());
4385 } 4383 }
4386 } 4384 }
4387 return init_block; 4385 return init_block;
4388 } 4386 }
4389 4387
4390 Block* Parser::BuildRejectPromiseOnException(Block* block) { 4388 Block* Parser::BuildRejectPromiseOnException(Block* inner_block, bool* ok) {
4391 // try { <block> } catch (error) { return Promise.reject(error); } 4389 // var .promise = %CreatePromise();
4392 Block* try_block = block; 4390 // var .debug_is_active = %_DebugIsActive();
4391 // if (.debug_is_active) %DebugPushPromise(.promise);
4392 // try {
4393 // <inner_block>
4394 // } catch (.catch) {
4395 // %RejectPromise(.promise, .catch);
4396 // return .promise;
4397 // } finally {
4398 // if (.debug_is_active) %DebugPopPromise();
4399 // }
4400 Block* result = factory()->NewBlock(nullptr, 4, true, kNoSourcePosition);
4401
4402 // var .promise = %CreatePromise();
4403 Statement* set_promise;
4404 {
4405 DeclareVariable(ast_value_factory()->dot_promise_string(), VAR,
4406 kNoSourcePosition, CHECK_OK);
4407 Expression* create_promise = factory()->NewCallRuntime(
4408 Context::PROMISE_CREATE_INDEX,
4409 new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition);
4410 Assignment* assign_promise = factory()->NewAssignment(
4411 Token::INIT, BuildDotPromise(), create_promise, kNoSourcePosition);
4412 set_promise =
4413 factory()->NewExpressionStatement(assign_promise, kNoSourcePosition);
4414 }
4415 result->statements()->Add(set_promise, zone());
4416
4417 // var .debug_is_active = %_DebugIsActive();
4418 Statement* set_debug_is_active;
4419 {
4420 DeclareVariable(ast_value_factory()->dot_debug_is_active_string(), VAR,
4421 kNoSourcePosition, CHECK_OK);
4422 Expression* debug_is_active = factory()->NewCallRuntime(
4423 Runtime::kInlineDebugIsActive,
4424 new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition);
4425 Assignment* assign_debug_is_active =
4426 factory()->NewAssignment(Token::INIT, BuildDotDebugIsActive(),
4427 debug_is_active, kNoSourcePosition);
4428 set_debug_is_active = factory()->NewExpressionStatement(
4429 assign_debug_is_active, kNoSourcePosition);
4430 }
4431 result->statements()->Add(set_debug_is_active, zone());
4432
4433 // if (.debug_is_active) %DebugPushPromise(.promise);
4434 Statement* conditionally_debug_push_promise;
4435 {
4436 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
4437 args->Add(BuildDotPromise(), zone());
4438 Expression* call_push_promise = factory()->NewCallRuntime(
4439 Runtime::kDebugPushPromise, args, kNoSourcePosition);
4440 Statement* debug_push_promise =
4441 factory()->NewExpressionStatement(call_push_promise, kNoSourcePosition);
4442 conditionally_debug_push_promise = factory()->NewIfStatement(
4443 BuildDotDebugIsActive(), debug_push_promise,
4444 factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition);
4445 }
4446 result->statements()->Add(conditionally_debug_push_promise, zone());
4447
4448 // catch (.catch) { return %RejectPromise(.promise, .catch), .promise }
4393 Scope* catch_scope = NewScope(CATCH_SCOPE); 4449 Scope* catch_scope = NewScope(CATCH_SCOPE);
4394 catch_scope->set_is_hidden(); 4450 catch_scope->set_is_hidden();
4395 Variable* catch_variable = 4451 Variable* catch_variable =
4396 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, 4452 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR,
4397 kCreatedInitialized, Variable::NORMAL); 4453 kCreatedInitialized, Variable::NORMAL);
4398 Block* catch_block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); 4454 Block* catch_block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
4399 4455
4400 Expression* promise_reject = BuildPromiseReject( 4456 Expression* promise_reject = BuildRejectPromise(
4401 factory()->NewVariableProxy(catch_variable), kNoSourcePosition); 4457 factory()->NewVariableProxy(catch_variable), kNoSourcePosition);
4402
4403 ReturnStatement* return_promise_reject = 4458 ReturnStatement* return_promise_reject =
4404 factory()->NewReturnStatement(promise_reject, kNoSourcePosition); 4459 factory()->NewReturnStatement(promise_reject, kNoSourcePosition);
4405 catch_block->statements()->Add(return_promise_reject, zone()); 4460 catch_block->statements()->Add(return_promise_reject, zone());
4461
4406 TryStatement* try_catch_statement = factory()->NewTryCatchStatement( 4462 TryStatement* try_catch_statement = factory()->NewTryCatchStatement(
4407 try_block, catch_scope, catch_variable, catch_block, kNoSourcePosition); 4463 inner_block, catch_scope, catch_variable, catch_block, kNoSourcePosition);
4408 4464
4409 block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); 4465 // There is no TryCatchFinally node, so wrap it in an outer try/finally
4410 block->statements()->Add(try_catch_statement, zone()); 4466 Block* outer_try_block =
4411 return block; 4467 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
4468 outer_try_block->statements()->Add(try_catch_statement, zone());
4469
4470 // finally { if (.debug_is_active) %DebugPopPromise(); }
4471 Block* finally_block =
4472 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
4473 {
4474 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(0, zone());
4475 Expression* call_pop_promise = factory()->NewCallRuntime(
4476 Runtime::kDebugPopPromise, args, kNoSourcePosition);
4477 Statement* debug_pop_promise =
4478 factory()->NewExpressionStatement(call_pop_promise, kNoSourcePosition);
4479 Statement* conditionally_debug_pop_promise = factory()->NewIfStatement(
4480 BuildDotDebugIsActive(), debug_pop_promise,
4481 factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition);
4482 finally_block->statements()->Add(conditionally_debug_pop_promise, zone());
4483 }
4484
4485 Statement* try_finally_statement = factory()->NewTryFinallyStatement(
4486 outer_try_block, finally_block, kNoSourcePosition);
4487
4488 result->statements()->Add(try_finally_statement, zone());
4489 return result;
4412 } 4490 }
4413 4491
4414 Expression* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) { 4492 Expression* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) {
4415 DCHECK_NOT_NULL(function_state_->generator_object_variable()); 4493 DCHECK_NOT_NULL(function_state_->generator_object_variable());
4416 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); 4494 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
4417 args->Add(factory()->NewThisFunction(pos), zone()); 4495 args->Add(factory()->NewThisFunction(pos), zone());
4418 args->Add(IsArrowFunction(kind) ? GetLiteralUndefined(pos) 4496 args->Add(IsArrowFunction(kind) ? GetLiteralUndefined(pos)
4419 : ThisExpression(kNoSourcePosition), 4497 : ThisExpression(kNoSourcePosition),
4420 zone()); 4498 zone());
4421 return factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args, 4499 return factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args,
4422 pos); 4500 pos);
4423 } 4501 }
4424 4502
4425 Expression* Parser::BuildPromiseResolve(Expression* value, int pos) { 4503 Expression* Parser::BuildResolvePromise(Expression* value, int pos) {
4426 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); 4504 // %ResolvePromise(.promise, value), .promise
4505 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
4506 args->Add(BuildDotPromise(), zone());
4427 args->Add(value, zone()); 4507 args->Add(value, zone());
4428 return factory()->NewCallRuntime(Context::PROMISE_CREATE_RESOLVED_INDEX, args, 4508 Expression* call_runtime =
4429 pos); 4509 factory()->NewCallRuntime(Context::PROMISE_RESOLVE_INDEX, args, pos);
4510 return factory()->NewBinaryOperation(Token::COMMA, call_runtime,
4511 BuildDotPromise(), pos);
4430 } 4512 }
4431 4513
4432 Expression* Parser::BuildPromiseReject(Expression* value, int pos) { 4514 Expression* Parser::BuildRejectPromise(Expression* value, int pos) {
4433 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); 4515 // %RejectPromiseNoDebugEvent(.promise, value, true), .promise
4516 // The NoDebugEvent variant disables the additional debug event for the
4517 // rejection since a debug event already happened for the exception that got
4518 // us here.
4519 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
4520 args->Add(BuildDotPromise(), zone());
4434 args->Add(value, zone()); 4521 args->Add(value, zone());
4435 return factory()->NewCallRuntime(Context::PROMISE_CREATE_REJECTED_INDEX, args, 4522 Expression* call_runtime = factory()->NewCallRuntime(
4436 pos); 4523 Context::REJECT_PROMISE_NO_DEBUG_EVENT_INDEX, args, pos);
4524 return factory()->NewBinaryOperation(Token::COMMA, call_runtime,
4525 BuildDotPromise(), pos);
4526 }
4527
4528 VariableProxy* Parser::BuildDotPromise() {
4529 return NewUnresolved(ast_value_factory()->dot_promise_string(), VAR);
4530 }
4531
4532 VariableProxy* Parser::BuildDotDebugIsActive() {
4533 return NewUnresolved(ast_value_factory()->dot_debug_is_active_string(), VAR);
4437 } 4534 }
4438 4535
4439 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( 4536 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
4440 const AstRawString* function_name, int pos, 4537 const AstRawString* function_name, int pos,
4441 const ParserFormalParameters& parameters, FunctionKind kind, 4538 const ParserFormalParameters& parameters, FunctionKind kind,
4442 FunctionLiteral::FunctionType function_type, bool* ok) { 4539 FunctionLiteral::FunctionType function_type, bool* ok) {
4443 // Everything inside an eagerly parsed function will be parsed eagerly 4540 // Everything inside an eagerly parsed function will be parsed eagerly
4444 // (see comment above). 4541 // (see comment above).
4445 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 4542 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
4446 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); 4543 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
4552 DCHECK_EQ(function_scope, inner_scope->outer_scope()); 4649 DCHECK_EQ(function_scope, inner_scope->outer_scope());
4553 DCHECK_EQ(body, inner_block->statements()); 4650 DCHECK_EQ(body, inner_block->statements());
4554 SetLanguageMode(function_scope, inner_scope->language_mode()); 4651 SetLanguageMode(function_scope, inner_scope->language_mode());
4555 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK); 4652 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK);
4556 4653
4557 if (is_sloppy(inner_scope->language_mode())) { 4654 if (is_sloppy(inner_scope->language_mode())) {
4558 InsertSloppyBlockFunctionVarBindings(inner_scope, function_scope, 4655 InsertSloppyBlockFunctionVarBindings(inner_scope, function_scope,
4559 CHECK_OK); 4656 CHECK_OK);
4560 } 4657 }
4561 4658
4659 // TODO(littledan): Merge the two rejection blocks into one
4562 if (IsAsyncFunction(kind)) { 4660 if (IsAsyncFunction(kind)) {
4563 init_block = BuildRejectPromiseOnException(init_block); 4661 init_block = BuildRejectPromiseOnException(init_block, CHECK_OK);
4564 } 4662 }
4565 4663
4566 DCHECK_NOT_NULL(init_block); 4664 DCHECK_NOT_NULL(init_block);
4567 4665
4568 inner_scope->set_end_position(scanner()->location().end_pos); 4666 inner_scope->set_end_position(scanner()->location().end_pos);
4569 if (inner_scope->FinalizeBlockScope() != nullptr) { 4667 if (inner_scope->FinalizeBlockScope() != nullptr) {
4570 CheckConflictingVarDeclarations(inner_scope, CHECK_OK); 4668 CheckConflictingVarDeclarations(inner_scope, CHECK_OK);
4571 InsertShadowingVarBindingInitializers(inner_block); 4669 InsertShadowingVarBindingInitializers(inner_block);
4572 } 4670 }
4573 inner_scope = nullptr; 4671 inner_scope = nullptr;
(...skipping 2075 matching lines...) Expand 10 before | Expand all | Expand 10 after
6649 node->Print(Isolate::Current()); 6747 node->Print(Isolate::Current());
6650 } 6748 }
6651 #endif // DEBUG 6749 #endif // DEBUG
6652 6750
6653 #undef CHECK_OK 6751 #undef CHECK_OK
6654 #undef CHECK_OK_VOID 6752 #undef CHECK_OK_VOID
6655 #undef CHECK_FAILED 6753 #undef CHECK_FAILED
6656 6754
6657 } // namespace internal 6755 } // namespace internal
6658 } // namespace v8 6756 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698