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

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: Better approach for bailing out on stack overflow in the appropriate place in fullcodegen Created 4 years, 4 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
« src/full-codegen/full-codegen.cc ('K') | « 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.h" 10 #include "src/ast/ast.h"
(...skipping 2768 matching lines...) Expand 10 before | Expand all | Expand 10 after
2779 // ES6 14.6.1 Static Semantics: IsInTailPosition 2779 // ES6 14.6.1 Static Semantics: IsInTailPosition
2780 function_state_->AddImplicitTailCallExpression(return_value); 2780 function_state_->AddImplicitTailCallExpression(return_value);
2781 } 2781 }
2782 } 2782 }
2783 } 2783 }
2784 ExpectSemicolon(CHECK_OK); 2784 ExpectSemicolon(CHECK_OK);
2785 2785
2786 if (is_generator()) { 2786 if (is_generator()) {
2787 return_value = BuildIteratorResult(return_value, true); 2787 return_value = BuildIteratorResult(return_value, true);
2788 } else if (is_async_function()) { 2788 } else if (is_async_function()) {
2789 return_value = BuildPromiseResolve(return_value, return_value->position()); 2789 return_value = BuildResolvePromise(return_value, return_value->position());
2790 } 2790 }
2791 2791
2792 result = factory()->NewReturnStatement(return_value, loc.beg_pos); 2792 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2793 2793
2794 DeclarationScope* decl_scope = GetDeclarationScope(); 2794 DeclarationScope* decl_scope = GetDeclarationScope();
2795 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) { 2795 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
2796 ReportMessageAt(loc, MessageTemplate::kIllegalReturn); 2796 ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
2797 *ok = false; 2797 *ok = false;
2798 return NULL; 2798 return NULL;
2799 } 2799 }
(...skipping 1323 matching lines...) Expand 10 before | Expand all | Expand 10 after
4123 classifier, kAsyncArrowFunction, FunctionBody::SingleExpression, 4123 classifier, kAsyncArrowFunction, FunctionBody::SingleExpression,
4124 accept_IN, pos, ok); 4124 accept_IN, pos, ok);
4125 } 4125 }
4126 4126
4127 void Parser::DesugarAsyncFunctionBody(const AstRawString* function_name, 4127 void Parser::DesugarAsyncFunctionBody(const AstRawString* function_name,
4128 Scope* scope, ZoneList<Statement*>* body, 4128 Scope* scope, ZoneList<Statement*>* body,
4129 ExpressionClassifier* classifier, 4129 ExpressionClassifier* classifier,
4130 FunctionKind kind, FunctionBody body_type, 4130 FunctionKind kind, FunctionBody body_type,
4131 bool accept_IN, int pos, bool* ok) { 4131 bool accept_IN, int pos, bool* ok) {
4132 // function async_function() { 4132 // function async_function() {
4133 // try { 4133 // BuildRejectPromiseOnException({
4134 // .generator_object = %CreateGeneratorObject(); 4134 // .generator_object = %CreateGeneratorObject();
4135 // ... function body ... 4135 // ... function body ...
4136 // } catch (e) { 4136 // return %ResolvePromise(.promise, expr), .promise;
4137 // return Promise.reject(e); 4137 // })
4138 // }
4139 // } 4138 // }
4140 scope->ForceContextAllocation(); 4139 scope->ForceContextAllocation();
4141 Variable* temp = 4140 Variable* temp =
4142 NewTemporary(ast_value_factory()->dot_generator_object_string()); 4141 NewTemporary(ast_value_factory()->dot_generator_object_string());
4143 function_state_->set_generator_object_variable(temp); 4142 function_state_->set_generator_object_variable(temp);
4144 4143
4145 Expression* init_generator_variable = factory()->NewAssignment( 4144 Expression* init_generator_variable = factory()->NewAssignment(
4146 Token::INIT, factory()->NewVariableProxy(temp), 4145 Token::INIT, factory()->NewVariableProxy(temp),
4147 BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition); 4146 BuildCreateJSGeneratorObject(pos, kind), kNoSourcePosition);
4148 body->Add(factory()->NewExpressionStatement(init_generator_variable, 4147 body->Add(factory()->NewExpressionStatement(init_generator_variable,
4149 kNoSourcePosition), 4148 kNoSourcePosition),
4150 zone()); 4149 zone());
4151 4150
4152 Block* try_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); 4151 Block* try_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition);
4153 4152
4154 ZoneList<Statement*>* inner_body = try_block->statements(); 4153 ZoneList<Statement*>* inner_body = try_block->statements();
4155 4154
4156 Expression* return_value = nullptr; 4155 Expression* return_value = nullptr;
4157 if (body_type == FunctionBody::Normal) { 4156 if (body_type == FunctionBody::Normal) {
4158 ParseStatementList(inner_body, Token::RBRACE, CHECK_OK_VOID); 4157 ParseStatementList(inner_body, Token::RBRACE, CHECK_OK_VOID);
4159 return_value = factory()->NewUndefinedLiteral(kNoSourcePosition); 4158 return_value = factory()->NewUndefinedLiteral(kNoSourcePosition);
4160 } else { 4159 } else {
4161 return_value = 4160 return_value =
4162 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK_VOID); 4161 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK_VOID);
4163 ParserTraits::RewriteNonPattern(classifier, CHECK_OK_VOID); 4162 ParserTraits::RewriteNonPattern(classifier, CHECK_OK_VOID);
4164 } 4163 }
4165 4164
4166 return_value = BuildPromiseResolve(return_value, return_value->position()); 4165 return_value = BuildResolvePromise(return_value, return_value->position());
4167 inner_body->Add( 4166 inner_body->Add(
4168 factory()->NewReturnStatement(return_value, return_value->position()), 4167 factory()->NewReturnStatement(return_value, return_value->position()),
4169 zone()); 4168 zone());
4170 body->Add(BuildRejectPromiseOnException(try_block), zone()); 4169 Statement* block = BuildRejectPromiseOnException(try_block, CHECK_OK_VOID);
4170 body->Add(block, zone());
4171 scope->set_end_position(scanner()->location().end_pos); 4171 scope->set_end_position(scanner()->location().end_pos);
4172 } 4172 }
4173 4173
4174 DoExpression* Parser::ParseDoExpression(bool* ok) { 4174 DoExpression* Parser::ParseDoExpression(bool* ok) {
4175 // AssignmentExpression :: 4175 // AssignmentExpression ::
4176 // do '{' StatementList '}' 4176 // do '{' StatementList '}'
4177 int pos = peek_position(); 4177 int pos = peek_position();
4178 4178
4179 Expect(Token::DO, CHECK_OK); 4179 Expect(Token::DO, CHECK_OK);
4180 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); 4180 Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
4727 param_scope = block_state.FinalizedBlockScope(); 4727 param_scope = block_state.FinalizedBlockScope();
4728 if (param_scope != nullptr) { 4728 if (param_scope != nullptr) {
4729 CheckConflictingVarDeclarations(param_scope, CHECK_OK); 4729 CheckConflictingVarDeclarations(param_scope, CHECK_OK);
4730 } 4730 }
4731 init_block->statements()->Add(param_block, zone()); 4731 init_block->statements()->Add(param_block, zone());
4732 } 4732 }
4733 } 4733 }
4734 return init_block; 4734 return init_block;
4735 } 4735 }
4736 4736
4737 Block* Parser::BuildRejectPromiseOnException(Block* block) { 4737 Block* Parser::BuildRejectPromiseOnException(Block* inner_block, bool* ok) {
4738 // try { <block> } catch (error) { return Promise.reject(error); } 4738 // var .promise = %CreatePromise();
4739 Block* try_block = block; 4739 // var .debug_is_active = %_DebugIsActive() !== 0;
4740 // try {
4741 // if (.debug_is_active) %DebugPushPromise(.promise);
4742 // <block>
4743 // } catch (.catch) {
4744 // %RejectPromise(.promise, .catch);
4745 // return .promise;
4746 // } finally {
4747 // if (.debug_is_active) %DebugPopPromise();
4748 // }
4749 Block* block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
4750
4751 // var .promise = %CreatePromise();
4752 Statement* set_promise;
4753 {
4754 DeclareVariable(ast_value_factory()->dot_promise_string(), VAR,
4755 kNoSourcePosition, CHECK_OK);
4756 Expression* create_promise = factory()->NewCallRuntime(
4757 Context::PROMISE_CREATE_INDEX,
4758 new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition);
4759 Assignment* assign_promise = factory()->NewAssignment(
4760 Token::INIT, BuildDotPromise(), create_promise, kNoSourcePosition);
4761 set_promise =
4762 factory()->NewExpressionStatement(assign_promise, kNoSourcePosition);
4763 }
4764 block->statements()->Add(set_promise, zone());
4765
4766 // var .debug_is_active = %_DebugIsActive() != 0;
4767 Statement* set_debug_is_active;
4768 {
4769 DeclareVariable(ast_value_factory()->dot_debug_is_active_string(), VAR,
4770 kNoSourcePosition, CHECK_OK);
4771 Expression* debug_is_active_num = factory()->NewCallRuntime(
4772 Runtime::kInlineDebugIsActive,
4773 new (zone()) ZoneList<Expression*>(0, zone()), kNoSourcePosition);
4774 Expression* debug_is_active = factory()->NewCompareOperation(
4775 Token::EQ_STRICT, debug_is_active_num,
4776 factory()->NewSmiLiteral(0, kNoSourcePosition), kNoSourcePosition);
4777 debug_is_active = factory()->NewUnaryOperation(Token::NOT, debug_is_active,
4778 kNoSourcePosition);
4779 Assignment* assign_debug_is_active = factory()->NewAssignment(
4780 Token::INIT, BuildDebugIsActive(), debug_is_active, kNoSourcePosition);
4781 set_debug_is_active = factory()->NewExpressionStatement(
4782 assign_debug_is_active, kNoSourcePosition);
4783 }
4784 block->statements()->Add(set_debug_is_active, zone());
4785
4786 Block* try_block = factory()->NewBlock(nullptr, 2, true, kNoSourcePosition);
4787 // if (.debug_is_active) %DebugPushPromise(.promise);
4788 Statement* conditionally_debug_push_promise;
4789 {
4790 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
4791 args->Add(BuildDotPromise(), zone());
4792 Expression* call_push_promise = factory()->NewCallRuntime(
4793 Runtime::kDebugPushPromise, args, kNoSourcePosition);
4794 Statement* debug_push_promise =
4795 factory()->NewExpressionStatement(call_push_promise, kNoSourcePosition);
4796 conditionally_debug_push_promise = factory()->NewIfStatement(
4797 BuildDebugIsActive(), debug_push_promise,
4798 factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition);
4799 }
4800 try_block->statements()->Add(conditionally_debug_push_promise, zone());
4801 try_block->statements()->Add(inner_block, zone());
4802
4803 // catch (.catch) { return %RejectPromise(.promise, .catch), .promise }
4740 Scope* catch_scope = NewScope(CATCH_SCOPE); 4804 Scope* catch_scope = NewScope(CATCH_SCOPE);
4741 catch_scope->set_is_hidden(); 4805 catch_scope->set_is_hidden();
4742 Variable* catch_variable = 4806 Variable* catch_variable =
4743 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR, 4807 catch_scope->DeclareLocal(ast_value_factory()->dot_catch_string(), VAR,
4744 kCreatedInitialized, Variable::NORMAL); 4808 kCreatedInitialized, Variable::NORMAL);
4745 Block* catch_block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); 4809 Block* catch_block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
4746 4810
4747 Expression* promise_reject = BuildPromiseReject( 4811 Expression* promise_reject = BuildRejectPromise(
4748 factory()->NewVariableProxy(catch_variable), kNoSourcePosition); 4812 factory()->NewVariableProxy(catch_variable), kNoSourcePosition);
4749
4750 ReturnStatement* return_promise_reject = 4813 ReturnStatement* return_promise_reject =
4751 factory()->NewReturnStatement(promise_reject, kNoSourcePosition); 4814 factory()->NewReturnStatement(promise_reject, kNoSourcePosition);
4752 catch_block->statements()->Add(return_promise_reject, zone()); 4815 catch_block->statements()->Add(return_promise_reject, zone());
4816
4753 TryStatement* try_catch_statement = factory()->NewTryCatchStatement( 4817 TryStatement* try_catch_statement = factory()->NewTryCatchStatement(
4754 try_block, catch_scope, catch_variable, catch_block, kNoSourcePosition); 4818 try_block, catch_scope, catch_variable, catch_block, kNoSourcePosition);
4755 4819
4756 block = factory()->NewBlock(nullptr, 1, true, kNoSourcePosition); 4820 // There is no TryCatchFinally node, so wrap it in an outer try/finally
4757 block->statements()->Add(try_catch_statement, zone()); 4821 Block* outer_try_block =
4822 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
4823 outer_try_block->statements()->Add(try_catch_statement, zone());
4824
4825 // finally { if (.debug_is_active) %DebugPopPromise(); }
4826 Block* finally_block =
4827 factory()->NewBlock(nullptr, 1, true, kNoSourcePosition);
4828 {
4829 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(0, zone());
4830 Expression* call_pop_promise = factory()->NewCallRuntime(
4831 Runtime::kDebugPopPromise, args, kNoSourcePosition);
4832 Statement* debug_pop_promise =
4833 factory()->NewExpressionStatement(call_pop_promise, kNoSourcePosition);
4834 Statement* conditionally_debug_pop_promise = factory()->NewIfStatement(
4835 BuildDebugIsActive(), debug_pop_promise,
4836 factory()->NewEmptyStatement(kNoSourcePosition), kNoSourcePosition);
4837 finally_block->statements()->Add(conditionally_debug_pop_promise, zone());
4838 }
4839
4840 Statement* try_finally_statement = factory()->NewTryFinallyStatement(
4841 outer_try_block, finally_block, kNoSourcePosition);
4842
4843 block->statements()->Add(try_finally_statement, zone());
4758 return block; 4844 return block;
4759 } 4845 }
4760 4846
4761 Expression* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) { 4847 Expression* Parser::BuildCreateJSGeneratorObject(int pos, FunctionKind kind) {
4762 DCHECK_NOT_NULL(function_state_->generator_object_variable()); 4848 DCHECK_NOT_NULL(function_state_->generator_object_variable());
4763 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); 4849 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
4764 args->Add(factory()->NewThisFunction(pos), zone()); 4850 args->Add(factory()->NewThisFunction(pos), zone());
4765 args->Add(IsArrowFunction(kind) 4851 args->Add(IsArrowFunction(kind)
4766 ? GetLiteralUndefined(pos) 4852 ? GetLiteralUndefined(pos)
4767 : ThisExpression(factory(), kNoSourcePosition), 4853 : ThisExpression(factory(), kNoSourcePosition),
4768 zone()); 4854 zone());
4769 return factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args, 4855 return factory()->NewCallRuntime(Runtime::kCreateJSGeneratorObject, args,
4770 pos); 4856 pos);
4771 } 4857 }
4772 4858
4773 Expression* Parser::BuildPromiseResolve(Expression* value, int pos) { 4859 Expression* Parser::BuildResolvePromise(Expression* value, int pos) {
4774 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); 4860 // %ResolvePromise(.promise, value), .promise
4861 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
4862 args->Add(BuildDotPromise(), zone());
4775 args->Add(value, zone()); 4863 args->Add(value, zone());
4776 return factory()->NewCallRuntime(Context::PROMISE_CREATE_RESOLVED_INDEX, args, 4864 Expression* call_runtime =
4777 pos); 4865 factory()->NewCallRuntime(Context::PROMISE_RESOLVE_INDEX, args, pos);
4866 return factory()->NewBinaryOperation(Token::COMMA, call_runtime,
4867 BuildDotPromise(), pos);
4778 } 4868 }
4779 4869
4780 Expression* Parser::BuildPromiseReject(Expression* value, int pos) { 4870 Expression* Parser::BuildRejectPromise(Expression* value, int pos) {
4781 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); 4871 // %RejectPromise(.promise, value, true), .promise
4872 // The 'true' flag disables the additional debug event for the rejection
4873 // since a debug event already happened for the exception that got us here.
4874 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(3, zone());
4875 args->Add(BuildDotPromise(), zone());
4782 args->Add(value, zone()); 4876 args->Add(value, zone());
4783 return factory()->NewCallRuntime(Context::PROMISE_CREATE_REJECTED_INDEX, args, 4877 args->Add(factory()->NewBooleanLiteral(true, pos), zone());
4784 pos); 4878 Expression* call_runtime =
4879 factory()->NewCallRuntime(Context::PROMISE_REJECT_INDEX, args, pos);
4880 return factory()->NewBinaryOperation(Token::COMMA, call_runtime,
4881 BuildDotPromise(), pos);
4882 }
4883
4884 VariableProxy* Parser::BuildDotPromise() {
4885 return NewUnresolved(ast_value_factory()->dot_promise_string(), VAR);
4886 }
4887
4888 VariableProxy* Parser::BuildDebugIsActive() {
4889 return NewUnresolved(ast_value_factory()->dot_debug_is_active_string(), VAR);
4785 } 4890 }
4786 4891
4787 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( 4892 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
4788 const AstRawString* function_name, int pos, 4893 const AstRawString* function_name, int pos,
4789 const ParserFormalParameters& parameters, FunctionKind kind, 4894 const ParserFormalParameters& parameters, FunctionKind kind,
4790 FunctionLiteral::FunctionType function_type, bool* ok) { 4895 FunctionLiteral::FunctionType function_type, bool* ok) {
4791 // Everything inside an eagerly parsed function will be parsed eagerly 4896 // Everything inside an eagerly parsed function will be parsed eagerly
4792 // (see comment above). 4897 // (see comment above).
4793 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 4898 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
4794 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); 4899 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
4900 DCHECK_EQ(function_scope, inner_scope->outer_scope()); 5005 DCHECK_EQ(function_scope, inner_scope->outer_scope());
4901 DCHECK_EQ(body, inner_block->statements()); 5006 DCHECK_EQ(body, inner_block->statements());
4902 SetLanguageMode(function_scope, inner_scope->language_mode()); 5007 SetLanguageMode(function_scope, inner_scope->language_mode());
4903 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK); 5008 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK);
4904 5009
4905 if (is_sloppy(inner_scope->language_mode())) { 5010 if (is_sloppy(inner_scope->language_mode())) {
4906 InsertSloppyBlockFunctionVarBindings(inner_scope, function_scope, 5011 InsertSloppyBlockFunctionVarBindings(inner_scope, function_scope,
4907 CHECK_OK); 5012 CHECK_OK);
4908 } 5013 }
4909 5014
5015 // TODO(littledan): Merge the two rejection blocks into one
4910 if (IsAsyncFunction(kind)) { 5016 if (IsAsyncFunction(kind)) {
4911 init_block = BuildRejectPromiseOnException(init_block); 5017 init_block = BuildRejectPromiseOnException(init_block, CHECK_OK);
4912 } 5018 }
4913 5019
4914 DCHECK_NOT_NULL(init_block); 5020 DCHECK_NOT_NULL(init_block);
4915 5021
4916 inner_scope->set_end_position(scanner()->location().end_pos); 5022 inner_scope->set_end_position(scanner()->location().end_pos);
4917 if (inner_scope->FinalizeBlockScope() != nullptr) { 5023 if (inner_scope->FinalizeBlockScope() != nullptr) {
4918 CheckConflictingVarDeclarations(inner_scope, CHECK_OK); 5024 CheckConflictingVarDeclarations(inner_scope, CHECK_OK);
4919 InsertShadowingVarBindingInitializers(inner_block); 5025 InsertShadowingVarBindingInitializers(inner_block);
4920 } 5026 }
4921 inner_scope = nullptr; 5027 inner_scope = nullptr;
(...skipping 2161 matching lines...) Expand 10 before | Expand all | Expand 10 after
7083 node->Print(Isolate::Current()); 7189 node->Print(Isolate::Current());
7084 } 7190 }
7085 #endif // DEBUG 7191 #endif // DEBUG
7086 7192
7087 #undef CHECK_OK 7193 #undef CHECK_OK
7088 #undef CHECK_OK_VOID 7194 #undef CHECK_OK_VOID
7089 #undef CHECK_FAILED 7195 #undef CHECK_FAILED
7090 7196
7091 } // namespace internal 7197 } // namespace internal
7092 } // namespace v8 7198 } // namespace v8
OLDNEW
« src/full-codegen/full-codegen.cc ('K') | « src/parsing/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698