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

Side by Side Diff: runtime/vm/parser.cc

Issue 944893005: Implement async* functions in VM (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/ast_transformer.h" 9 #include "vm/ast_transformer.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 3086 matching lines...) Expand 10 before | Expand all | Expand 10 after
3097 AddFormalParamsToScope(&params, current_block_->scope); 3097 AddFormalParamsToScope(&params, current_block_->scope);
3098 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); 3098 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved());
3099 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { 3099 if (!Function::Handle(func.parent_function()).IsGetterFunction()) {
3100 // Parse and discard any formal parameters. They are accessed as 3100 // Parse and discard any formal parameters. They are accessed as
3101 // context variables. 3101 // context variables.
3102 ParamList discarded_params; 3102 ParamList discarded_params;
3103 ParseFormalParameterList(allow_explicit_default_values, 3103 ParseFormalParameterList(allow_explicit_default_values,
3104 false, 3104 false,
3105 &discarded_params); 3105 &discarded_params);
3106 } 3106 }
3107 } else if (func.IsAsyncGenClosure()) {
3108 AddAsyncGenClosureParameters(&params);
3109 SetupDefaultsForOptionalParams(&params, default_parameter_values);
3110 AddFormalParamsToScope(&params, current_block_->scope);
3111 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved());
3112 if (!Function::Handle(func.parent_function()).IsGetterFunction()) {
3113 // Parse and discard any formal parameters. They are accessed as
3114 // context variables.
3115 ParamList discarded_params;
3116 ParseFormalParameterList(allow_explicit_default_values,
3117 false,
3118 &discarded_params);
3119 }
3107 } else { 3120 } else {
3108 ParseFormalParameterList(allow_explicit_default_values, false, &params); 3121 ParseFormalParameterList(allow_explicit_default_values, false, &params);
3109 3122
3110 // The number of parameters and their type are not yet set in local 3123 // The number of parameters and their type are not yet set in local
3111 // functions, since they are not 'top-level' parsed. 3124 // functions, since they are not 'top-level' parsed.
3112 if (func.IsLocalFunction()) { 3125 if (func.IsLocalFunction()) {
3113 AddFormalParamsToFunction(&params, func); 3126 AddFormalParamsToFunction(&params, func);
3114 } 3127 }
3115 SetupDefaultsForOptionalParams(&params, default_parameter_values); 3128 SetupDefaultsForOptionalParams(&params, default_parameter_values);
3116 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); 3129 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3165 ASSERT(func.is_debuggable()); 3178 ASSERT(func.is_debuggable());
3166 OpenAsyncClosure(); 3179 OpenAsyncClosure();
3167 } else if (func.IsSyncGenerator()) { 3180 } else if (func.IsSyncGenerator()) {
3168 // The code of a sync generator is synthesized. Disable debugging. 3181 // The code of a sync generator is synthesized. Disable debugging.
3169 func.set_is_debuggable(false); 3182 func.set_is_debuggable(false);
3170 generated_body_closure = OpenSyncGeneratorFunction(func.token_pos()); 3183 generated_body_closure = OpenSyncGeneratorFunction(func.token_pos());
3171 } else if (func.IsSyncGenClosure()) { 3184 } else if (func.IsSyncGenClosure()) {
3172 // The closure containing the body of a sync generator is debuggable. 3185 // The closure containing the body of a sync generator is debuggable.
3173 ASSERT(func.is_debuggable()); 3186 ASSERT(func.is_debuggable());
3174 async_temp_scope_ = current_block_->scope; 3187 async_temp_scope_ = current_block_->scope;
3188 } else if (func.IsAsyncGenerator()) {
3189 func.set_is_debuggable(false);
3190 generated_body_closure = OpenAsyncGeneratorFunction(func.token_pos());
3191 } else if (func.IsAsyncGenClosure()) {
3192 // The closure containing the body of an async* function is debuggable.
3193 ASSERT(func.is_debuggable());
3194 OpenAsyncGeneratorClosure();
3175 } 3195 }
3176 3196
3177 BoolScope allow_await(&this->await_is_keyword_, 3197 BoolScope allow_await(&this->await_is_keyword_,
3178 func.IsAsyncOrGenerator() || func.is_generated_body()); 3198 func.IsAsyncOrGenerator() || func.is_generated_body());
3179 intptr_t end_token_pos = 0; 3199 intptr_t end_token_pos = 0;
3180 if (CurrentToken() == Token::kLBRACE) { 3200 if (CurrentToken() == Token::kLBRACE) {
3181 ConsumeToken(); 3201 ConsumeToken();
3182 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { 3202 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) {
3183 const Class& owner = Class::Handle(Z, func.Owner()); 3203 const Class& owner = Class::Handle(Z, func.Owner());
3184 if (!owner.IsObjectClass()) { 3204 if (!owner.IsObjectClass()) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3242 if (func.IsAsyncFunction()) { 3262 if (func.IsAsyncFunction()) {
3243 body = CloseAsyncFunction(generated_body_closure, body); 3263 body = CloseAsyncFunction(generated_body_closure, body);
3244 generated_body_closure.set_end_token_pos(end_token_pos); 3264 generated_body_closure.set_end_token_pos(end_token_pos);
3245 } else if (func.IsAsyncClosure()) { 3265 } else if (func.IsAsyncClosure()) {
3246 body = CloseAsyncClosure(body); 3266 body = CloseAsyncClosure(body);
3247 } else if (func.IsSyncGenerator()) { 3267 } else if (func.IsSyncGenerator()) {
3248 body = CloseSyncGenFunction(generated_body_closure, body); 3268 body = CloseSyncGenFunction(generated_body_closure, body);
3249 generated_body_closure.set_end_token_pos(end_token_pos); 3269 generated_body_closure.set_end_token_pos(end_token_pos);
3250 } else if (func.IsSyncGenClosure()) { 3270 } else if (func.IsSyncGenClosure()) {
3251 body->scope()->RecursivelyCaptureAllVariables(); 3271 body->scope()->RecursivelyCaptureAllVariables();
3272 } else if (func.IsAsyncGenerator()) {
3273 body = CloseAsyncGeneratorFunction(generated_body_closure, body);
3274 generated_body_closure.set_end_token_pos(end_token_pos);
3275 } else if (func.IsAsyncGenClosure()) {
3276 body = CloseAsyncGeneratorClosure(body);
3252 } 3277 }
3253 current_block_->statements->Add(body); 3278 current_block_->statements->Add(body);
3254 innermost_function_ = saved_innermost_function.raw(); 3279 innermost_function_ = saved_innermost_function.raw();
3255 last_used_try_index_ = saved_try_index; 3280 last_used_try_index_ = saved_try_index;
3256 async_temp_scope_ = saved_async_temp_scope; 3281 async_temp_scope_ = saved_async_temp_scope;
3257 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx); 3282 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx);
3258 parsed_function()->set_async_saved_try_ctx_name( 3283 parsed_function()->set_async_saved_try_ctx_name(
3259 saved_async_saved_try_ctx_name); 3284 saved_async_saved_try_ctx_name);
3260 return CloseBlock(); 3285 return CloseBlock();
3261 } 3286 }
(...skipping 1980 matching lines...) Expand 10 before | Expand all | Expand 10 after
5242 ExpectSemicolon(); // Reports error. 5267 ExpectSemicolon(); // Reports error.
5243 } 5268 }
5244 } 5269 }
5245 } 5270 }
5246 5271
5247 5272
5248 RawFunction::AsyncModifier Parser::ParseFunctionModifier() { 5273 RawFunction::AsyncModifier Parser::ParseFunctionModifier() {
5249 if (CurrentLiteral()->raw() == Symbols::Async().raw()) { 5274 if (CurrentLiteral()->raw() == Symbols::Async().raw()) {
5250 ConsumeToken(); 5275 ConsumeToken();
5251 if (CurrentToken() == Token::kMUL) { 5276 if (CurrentToken() == Token::kMUL) {
5252 ReportError("async* generator functions are not yet supported"); 5277 const bool enableAsyncStar = true;
5278 if (!enableAsyncStar) {
5279 ReportError("async* generator functions are not yet supported");
5280 }
5253 ConsumeToken(); 5281 ConsumeToken();
5254 return RawFunction::kAsyncGen; 5282 return RawFunction::kAsyncGen;
5255 } else { 5283 } else {
5256 return RawFunction::kAsync; 5284 return RawFunction::kAsync;
5257 } 5285 }
5258 } else if ((CurrentLiteral()->raw() == Symbols::Sync().raw()) && 5286 } else if ((CurrentLiteral()->raw() == Symbols::Sync().raw()) &&
5259 (LookaheadToken(1) == Token::kMUL)) { 5287 (LookaheadToken(1) == Token::kMUL)) {
5260 const bool enableSyncStar = true; 5288 const bool enableSyncStar = true;
5261 if (!enableSyncStar) { 5289 if (!enableSyncStar) {
5262 ReportError("sync* generator functions are not yet supported"); 5290 ReportError("sync* generator functions are not yet supported");
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after
5933 5961
5934 void Parser::OpenAsyncClosure() { 5962 void Parser::OpenAsyncClosure() {
5935 TRACE_PARSER("OpenAsyncClosure"); 5963 TRACE_PARSER("OpenAsyncClosure");
5936 5964
5937 async_temp_scope_ = current_block_->scope; 5965 async_temp_scope_ = current_block_->scope;
5938 5966
5939 OpenAsyncTryBlock(); 5967 OpenAsyncTryBlock();
5940 } 5968 }
5941 5969
5942 5970
5943 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { 5971 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode *body) {
5972 TRACE_PARSER("CloseAsyncGeneratorTryBlock");
5973 // The generated try-catch-finally that wraps the async generator function
5974 // body is the outermost try statement.
5975 ASSERT(try_blocks_list_ != NULL);
5976 ASSERT(try_blocks_list_->outer_try_block() == NULL);
5977 // We only get here when parsing an async generator body.
5978 ASSERT(innermost_function().IsAsyncGenClosure());
5979
5980 // The try-block (closure body code) has been parsed. We are now
5981 // generating the code for the catch block.
5944 try_blocks_list_->enter_catch(); 5982 try_blocks_list_->enter_catch();
5983 OpenBlock(); // Catch handler list.
5984 OpenBlock(); // Catch block.
5945 5985
5946 OpenBlock(); 5986 // Add the exception and stack trace parameters to the scope.
5947 OpenBlock();
5948 const AbstractType& dynamic_type = 5987 const AbstractType& dynamic_type =
5949 AbstractType::ZoneHandle(Z, Type::DynamicType()); 5988 AbstractType::ZoneHandle(Z, Type::DynamicType());
5950 CatchParamDesc exception_param; 5989 CatchParamDesc exception_param;
5951 CatchParamDesc stack_trace_param; 5990 CatchParamDesc stack_trace_param;
5952 exception_param.token_pos = Scanner::kNoSourcePos; 5991 exception_param.token_pos = Scanner::kNoSourcePos;
5953 exception_param.type = &dynamic_type; 5992 exception_param.type = &dynamic_type;
5954 exception_param.name = &Symbols::ExceptionParameter(); 5993 exception_param.name = &Symbols::ExceptionParameter();
5955 stack_trace_param.token_pos = Scanner::kNoSourcePos; 5994 stack_trace_param.token_pos = Scanner::kNoSourcePos;
5956 stack_trace_param.type = &dynamic_type; 5995 stack_trace_param.type = &dynamic_type;
5957 stack_trace_param.name = &Symbols::StackTraceParameter(); 5996 stack_trace_param.name = &Symbols::StackTraceParameter();
5958
5959 AddCatchParamsToScope( 5997 AddCatchParamsToScope(
5960 &exception_param, &stack_trace_param, current_block_->scope); 5998 &exception_param, &stack_trace_param, current_block_->scope);
5961 5999
6000 // Generate code to save the exception object and stack trace
6001 // in local variables.
5962 LocalVariable* context_var = current_block_->scope->LookupVariable( 6002 LocalVariable* context_var = current_block_->scope->LookupVariable(
5963 Symbols::SavedTryContextVar(), false); 6003 Symbols::SavedTryContextVar(), false);
5964 ASSERT(context_var != NULL); 6004 ASSERT(context_var != NULL);
5965 LocalVariable* exception_var = current_block_->scope->LookupVariable( 6005 LocalVariable* exception_var = current_block_->scope->LookupVariable(
5966 Symbols::ExceptionVar(), false); 6006 Symbols::ExceptionVar(), false);
5967 if (exception_param.var != NULL) { 6007 if (exception_param.var != NULL) {
5968 // Generate code to load the exception object (:exception_var) into 6008 // Generate code to load the exception object (:exception_var) into
5969 // the exception variable specified in this block. 6009 // the exception variable specified in this block.
5970 ASSERT(exception_var != NULL); 6010 ASSERT(exception_var != NULL);
5971 current_block_->statements->Add(new(Z) StoreLocalNode( 6011 current_block_->statements->Add(new(Z) StoreLocalNode(
5972 Scanner::kNoSourcePos, 6012 Scanner::kNoSourcePos,
5973 exception_param.var, 6013 exception_param.var,
5974 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); 6014 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var)));
5975 } 6015 }
5976 LocalVariable* stack_trace_var = 6016 LocalVariable* stack_trace_var =
5977 current_block_->scope->LookupVariable(Symbols::StackTraceVar(), false); 6017 current_block_->scope->LookupVariable(Symbols::StackTraceVar(), false);
5978 if (stack_trace_param.var != NULL) { 6018 if (stack_trace_param.var != NULL) {
5979 // A stack trace variable is specified in this block, so generate code 6019 // A stack trace variable is specified in this block, so generate code
5980 // to load the stack trace object (:stack_trace_var) into the stack 6020 // to load the stack trace object (:stack_trace_var) into the stack
5981 // trace variable specified in this block. 6021 // trace variable specified in this block.
5982 ASSERT(stack_trace_var != NULL); 6022 ASSERT(stack_trace_var != NULL);
5983 current_block_->statements->Add(new(Z) StoreLocalNode( 6023 current_block_->statements->Add(new(Z) StoreLocalNode(
5984 Scanner::kNoSourcePos, 6024 Scanner::kNoSourcePos,
5985 stack_trace_param.var, 6025 stack_trace_param.var,
5986 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); 6026 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
5987 } 6027 }
5988 6028
6029 parsed_function()->reset_saved_try_ctx_vars();
6030
6031 // Catch block: add the error to the stream.
6032 // :controller.AddError(:exception, :stack_trace);
6033 // return; // The finally block will close the stream.
6034 LocalVariable* controller =
6035 current_block_->scope->LookupVariable(Symbols::Controller(), false);
6036 ASSERT(controller != NULL);
6037 ArgumentListNode* args =
6038 new(Z) ArgumentListNode(Scanner::kNoSourcePos);
6039 args->Add(new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var));
6040 args->Add(new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var));
6041 current_block_->statements->Add(
6042 new(Z) InstanceCallNode(TokenPos(),
6043 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller),
6044 Symbols::AddError(),
6045 args));
6046 ReturnNode* return_node = new(Z) ReturnNode(Scanner::kNoSourcePos);
6047 current_block_->statements->Add(return_node);
6048 AstNode* catch_block = CloseBlock();
6049 current_block_->statements->Add(catch_block);
6050 SequenceNode* catch_handler_list = CloseBlock();
6051
6052 TryBlocks* try_block = PopTryBlock();
6053 ASSERT(try_blocks_list_ == NULL); // We popped the outermost try block.
6054
6055 // Finally block: closing the stream and returning. (Note: the return
6056 // is necessary otherwise the back-end will append a rethrow of the
6057 // current exception.)
6058 // :controller.close();
6059 // return;
6060 // We need to inline this code in all recorded exit points.
6061 intptr_t node_index = 0;
6062 SequenceNode* finally_clause = NULL;
6063 do {
6064 OpenBlock();
6065 ArgumentListNode* no_args =
6066 new(Z) ArgumentListNode(Scanner::kNoSourcePos);
6067 current_block_->statements->Add(
6068 new(Z) InstanceCallNode(TokenPos(),
6069 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller),
6070 Symbols::Close(),
6071 no_args));
6072
6073 ReturnNode* return_node = new(Z) ReturnNode(Scanner::kNoSourcePos);
6074 current_block_->statements->Add(return_node);
6075
6076 finally_clause = CloseBlock();
6077 AstNode* node_to_inline = try_block->GetNodeToInlineFinally(node_index);
6078 if (node_to_inline != NULL) {
6079 InlinedFinallyNode* node =
6080 new(Z) InlinedFinallyNode(TokenPos(),
6081 finally_clause,
6082 context_var,
6083 // No outer try statement
6084 CatchClauseNode::kInvalidTryIndex);
6085 finally_clause = NULL;
6086 AddFinallyBlockToNode(node_to_inline, node);
6087 node_index++;
6088 }
6089 } while (finally_clause == NULL);
6090
6091 const GrowableObjectArray& handler_types =
6092 GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
6093 handler_types.Add(dynamic_type); // Catch block handles all exceptions.
6094
6095 CatchClauseNode* catch_clause = new(Z) CatchClauseNode(
6096 Scanner::kNoSourcePos,
6097 catch_handler_list,
6098 Array::ZoneHandle(Z, Array::MakeArray(handler_types)),
6099 context_var,
6100 exception_var,
6101 stack_trace_var,
6102 AllocateTryIndex(),
6103 true);
6104
6105 const intptr_t try_index = try_block->try_index();
6106
6107 AstNode* try_catch_node =
6108 new(Z) TryCatchNode(Scanner::kNoSourcePos,
6109 body,
6110 context_var,
6111 catch_clause,
6112 finally_clause,
6113 try_index);
6114 current_block_->statements->Add(try_catch_node);
6115 return CloseBlock();
6116 }
6117
6118
6119 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) {
6120 // This is the outermost try-catch of the function.
5989 ASSERT(try_blocks_list_ != NULL); 6121 ASSERT(try_blocks_list_ != NULL);
5990 ASSERT(innermost_function().IsAsyncClosure() || 6122 ASSERT(try_blocks_list_->outer_try_block() == NULL);
5991 innermost_function().IsAsyncFunction()); 6123 ASSERT(innermost_function().IsAsyncClosure());
5992 if ((try_blocks_list_->outer_try_block() != NULL) && 6124
5993 (try_blocks_list_->outer_try_block()->try_block() 6125 try_blocks_list_->enter_catch();
5994 ->scope->function_level() == 6126
5995 current_block_->scope->function_level())) { 6127 OpenBlock(); // Catch handler list.
5996 // We need to unchain three scope levels: catch clause, catch 6128 OpenBlock(); // Catch block.
5997 // parameters, and the general try block. 6129 const AbstractType& dynamic_type =
5998 RestoreSavedTryContext( 6130 AbstractType::ZoneHandle(Z, Type::DynamicType());
5999 current_block_->scope->parent()->parent()->parent(), 6131 CatchParamDesc exception_param;
6000 try_blocks_list_->outer_try_block()->try_index(), 6132 CatchParamDesc stack_trace_param;
6001 current_block_->statements); 6133 exception_param.token_pos = Scanner::kNoSourcePos;
6002 } else { 6134 exception_param.type = &dynamic_type;
6003 parsed_function()->reset_saved_try_ctx_vars(); 6135 exception_param.name = &Symbols::ExceptionParameter();
6136 stack_trace_param.token_pos = Scanner::kNoSourcePos;
6137 stack_trace_param.type = &dynamic_type;
6138 stack_trace_param.name = &Symbols::StackTraceParameter();
6139
6140 AddCatchParamsToScope(
6141 &exception_param, &stack_trace_param, current_block_->scope);
6142
6143 LocalVariable* context_var = current_block_->scope->LookupVariable(
6144 Symbols::SavedTryContextVar(), false);
6145 ASSERT(context_var != NULL);
6146 LocalVariable* exception_var = current_block_->scope->LookupVariable(
6147 Symbols::ExceptionVar(), false);
6148 if (exception_param.var != NULL) {
6149 // Generate code to load the exception object (:exception_var) into
6150 // the exception variable specified in this block.
6151 ASSERT(exception_var != NULL);
6152 current_block_->statements->Add(new(Z) StoreLocalNode(
6153 Scanner::kNoSourcePos,
6154 exception_param.var,
6155 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var)));
6156 }
6157 LocalVariable* stack_trace_var =
6158 current_block_->scope->LookupVariable(Symbols::StackTraceVar(), false);
6159 if (stack_trace_param.var != NULL) {
6160 // A stack trace variable is specified in this block, so generate code
6161 // to load the stack trace object (:stack_trace_var) into the stack
6162 // trace variable specified in this block.
6163 ASSERT(stack_trace_var != NULL);
6164 current_block_->statements->Add(new(Z) StoreLocalNode(
6165 Scanner::kNoSourcePos,
6166 stack_trace_param.var,
6167 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
6004 } 6168 }
6005 6169
6006 // Complete the async future with an error. 6170 parsed_function()->reset_saved_try_ctx_vars();
6007 // Since we control the catch block there is no need to generate a nested 6171
6008 // if/then/else. 6172 // Complete the async future with an error. This catch block executes
6173 // unconditionally, there is no need to generate a type check for.
6009 LocalVariable* async_completer = current_block_->scope->LookupVariable( 6174 LocalVariable* async_completer = current_block_->scope->LookupVariable(
6010 Symbols::AsyncCompleter(), false); 6175 Symbols::AsyncCompleter(), false);
6011 ASSERT(async_completer != NULL); 6176 ASSERT(async_completer != NULL);
6012 ArgumentListNode* completer_args = 6177 ArgumentListNode* completer_args =
6013 new (Z) ArgumentListNode(Scanner::kNoSourcePos); 6178 new (Z) ArgumentListNode(Scanner::kNoSourcePos);
6014 completer_args->Add( 6179 completer_args->Add(
6015 new (Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var)); 6180 new (Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var));
6016 completer_args->Add( 6181 completer_args->Add(
6017 new (Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var)); 6182 new (Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var));
6018 current_block_->statements->Add(new (Z) InstanceCallNode( 6183 current_block_->statements->Add(new (Z) InstanceCallNode(
(...skipping 24 matching lines...) Expand all
6043 context_var, 6208 context_var,
6044 exception_var, 6209 exception_var,
6045 stack_trace_var, 6210 stack_trace_var,
6046 CatchClauseNode::kInvalidTryIndex, 6211 CatchClauseNode::kInvalidTryIndex,
6047 true); 6212 true);
6048 AstNode* try_catch_node = new (Z) TryCatchNode( 6213 AstNode* try_catch_node = new (Z) TryCatchNode(
6049 Scanner::kNoSourcePos, 6214 Scanner::kNoSourcePos,
6050 try_block, 6215 try_block,
6051 context_var, 6216 context_var,
6052 catch_clause, 6217 catch_clause,
6053 NULL, 6218 NULL, // No finally clause.
6054 try_index); 6219 try_index);
6055 current_block_->statements->Add(try_catch_node); 6220 current_block_->statements->Add(try_catch_node);
6056 return CloseBlock(); 6221 return CloseBlock();
6057 } 6222 }
6058 6223
6059 6224
6225 // Wrap the body of the async or arync* closure in a try/catch block.
6060 void Parser::OpenAsyncTryBlock() { 6226 void Parser::OpenAsyncTryBlock() {
6061 // Manually wrapping the actual body into a try/catch block. 6227 ASSERT(innermost_function().IsAsyncClosure() ||
6228 innermost_function().IsAsyncGenClosure());
6229
6062 LocalVariable* context_var = 6230 LocalVariable* context_var =
6063 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); 6231 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar());
6064 if (context_var == NULL) { 6232 if (context_var == NULL) {
6065 context_var = new(Z) LocalVariable( 6233 context_var = new(Z) LocalVariable(
6066 TokenPos(), 6234 TokenPos(),
6067 Symbols::SavedTryContextVar(), 6235 Symbols::SavedTryContextVar(),
6068 Type::ZoneHandle(Z, Type::DynamicType())); 6236 Type::ZoneHandle(Z, Type::DynamicType()));
6069 current_block_->scope->AddVariable(context_var); 6237 current_block_->scope->AddVariable(context_var);
6070 } 6238 }
6071 LocalVariable* exception_var = 6239 LocalVariable* exception_var =
(...skipping 10 matching lines...) Expand all
6082 if (stack_trace_var == NULL) { 6250 if (stack_trace_var == NULL) {
6083 stack_trace_var = new(Z) LocalVariable( 6251 stack_trace_var = new(Z) LocalVariable(
6084 TokenPos(), 6252 TokenPos(),
6085 Symbols::StackTraceVar(), 6253 Symbols::StackTraceVar(),
6086 Type::ZoneHandle(Z, Type::DynamicType())); 6254 Type::ZoneHandle(Z, Type::DynamicType()));
6087 current_block_->scope->AddVariable(stack_trace_var); 6255 current_block_->scope->AddVariable(stack_trace_var);
6088 } 6256 }
6089 6257
6090 // Open the try block. 6258 // Open the try block.
6091 OpenBlock(); 6259 OpenBlock();
6260 // This is the outermost try-catch in the function.
6261 ASSERT(try_blocks_list_ == NULL);
6092 PushTryBlock(current_block_); 6262 PushTryBlock(current_block_);
6093 6263
6094 if (innermost_function().IsAsyncClosure() || 6264 SetupSavedTryContext(context_var);
6095 innermost_function().IsAsyncFunction() ||
6096 innermost_function().IsSyncGenClosure() ||
6097 innermost_function().IsSyncGenerator()) {
6098 SetupSavedTryContext(context_var);
6099 }
6100 } 6265 }
6101 6266
6102 6267
6103 void Parser::AddSyncGenClosureParameters(ParamList* params) { 6268 void Parser::AddSyncGenClosureParameters(ParamList* params) {
6104 // Create the parameter list for the body closure of a sync generator: 6269 // Create the parameter list for the body closure of a sync generator:
6105 // 1) Implicit closure parameter; 6270 // 1) Implicit closure parameter;
6106 // 2) Iterator 6271 // 2) Iterator
6107 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); 6272 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6108 // Add implicit closure parameter if not already present. 6273 // Add implicit closure parameter if not already present.
6109 if (params->parameters->length() == 0) { 6274 if (params->parameters->length() == 0) {
6110 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type); 6275 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type);
6111 } 6276 }
6112 ParamDesc iterator_param; 6277 ParamDesc iterator_param;
6113 iterator_param.name = &Symbols::IteratorParameter(); 6278 iterator_param.name = &Symbols::IteratorParameter();
6114 iterator_param.type = &dynamic_type; 6279 iterator_param.type = &dynamic_type;
6115 params->parameters->Add(iterator_param); 6280 params->parameters->Add(iterator_param);
6116 params->num_fixed_parameters++; 6281 params->num_fixed_parameters++;
6117 } 6282 }
6118 6283
6119 6284
6285 void Parser::AddAsyncGenClosureParameters(ParamList* params) {
6286 // Create the parameter list for the body closure of a sync generator:
Ivan Posva 2015/02/23 08:23:36 sync?
hausner 2015/02/23 17:12:01 Yes.
6287 // The closure has no explicit parameters.
6288 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6289 // Add implicit closure parameter if not already present.
6290 if (params->parameters->length() == 0) {
6291 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type);
6292 }
6293 }
6294
6295
6120 RawFunction* Parser::OpenSyncGeneratorFunction(intptr_t func_pos) { 6296 RawFunction* Parser::OpenSyncGeneratorFunction(intptr_t func_pos) {
6121 Function& body = Function::Handle(Z); 6297 Function& body = Function::Handle(Z);
6122 String& body_closure_name = String::Handle(Z); 6298 String& body_closure_name = String::Handle(Z);
6123 bool is_new_closure = false; 6299 bool is_new_closure = false;
6124 6300
6125 AddContinuationVariables(); 6301 AddContinuationVariables();
6126 6302
6127 // Check whether a function for the body of this generator 6303 // Check whether a function for the body of this generator
6128 // function has already been created by a previous 6304 // function has already been created by a previous
6129 // compilation. 6305 // compilation.
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
6349 current_block_->scope->CaptureVariable(Symbols::AsyncOperation()); 6525 current_block_->scope->CaptureVariable(Symbols::AsyncOperation());
6350 async_op_var->set_is_captured(); 6526 async_op_var->set_is_captured();
6351 LocalVariable* async_completer = new(Z) LocalVariable( 6527 LocalVariable* async_completer = new(Z) LocalVariable(
6352 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type); 6528 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type);
6353 current_block_->scope->AddVariable(async_completer); 6529 current_block_->scope->AddVariable(async_completer);
6354 current_block_->scope->CaptureVariable(Symbols::AsyncCompleter()); 6530 current_block_->scope->CaptureVariable(Symbols::AsyncCompleter());
6355 async_completer->set_is_captured(); 6531 async_completer->set_is_captured();
6356 } 6532 }
6357 6533
6358 6534
6535 void Parser::AddAsyncGeneratorVariables() {
6536 // Add to current block's scope:
6537 // var :controller;
6538 // This variables is used by the nested async generator closure to
6539 // store the StreamController object to which the yielded expressions
6540 // are added.
6541 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6542 LocalVariable* controller_var = new(Z) LocalVariable(
6543 Scanner::kNoSourcePos, Symbols::Controller(), dynamic_type);
6544 current_block_->scope->AddVariable(controller_var);
6545 current_block_->scope->CaptureVariable(Symbols::Controller());
6546 controller_var->set_is_captured();
6547 }
6548
6549
6550 RawFunction* Parser::OpenAsyncGeneratorFunction(intptr_t async_func_pos) {
6551 TRACE_PARSER("OpenAsyncGeneratorFunction");
6552 AddContinuationVariables();
6553 AddAsyncGeneratorVariables();
6554
6555 Function& closure = Function::Handle(Z);
6556 bool is_new_closure = false;
6557
6558 // Check whether a function for the asynchronous function body of
6559 // this async generator has already been created by a previous
6560 // compilation of this function.
6561 const Function& found_func = Function::Handle(
6562 Z, current_class().LookupClosureFunction(async_func_pos));
6563 if (!found_func.IsNull() &&
6564 (found_func.token_pos() == async_func_pos) &&
6565 (found_func.script() == innermost_function().script()) &&
6566 (found_func.parent_function() == innermost_function().raw())) {
6567 ASSERT(found_func.IsAsyncGenClosure());
6568 closure = found_func.raw();
6569 } else {
6570 // Create the closure containing the body of this async generator function.
6571 const String& async_generator_name =
6572 String::Handle(Z, innermost_function().name());
6573 String& closure_name = String::Handle(Z,
6574 String::NewFormatted("<%s_async_body>",
6575 async_generator_name.ToCString()));
6576 closure = Function::NewClosureFunction(
6577 String::Handle(Z, Symbols::New(closure_name)),
6578 innermost_function(),
6579 async_func_pos);
6580 closure.set_is_generated_body(true);
6581 closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
6582 is_new_closure = true;
6583 }
6584
6585 ParamList closure_params;
6586 AddAsyncGenClosureParameters(&closure_params);
6587
6588 if (is_new_closure) {
6589 // Add the parameters to the newly created closure.
6590 AddFormalParamsToFunction(&closure_params, closure);
6591
6592 // Create and set the signature class of the closure.
6593 const String& sig = String::Handle(Z, closure.Signature());
6594 Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig));
6595 if (sig_cls.IsNull()) {
6596 sig_cls =
6597 Class::NewSignatureClass(sig, closure, script_, closure.token_pos());
6598 library_.AddClass(sig_cls);
6599 }
6600 closure.set_signature_class(sig_cls);
6601 const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType());
6602 if (!sig_type.IsFinalized()) {
6603 ClassFinalizer::FinalizeType(
6604 sig_cls, sig_type, ClassFinalizer::kCanonicalize);
6605 }
6606 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved());
6607 ASSERT(closure.NumParameters() == closure_params.parameters->length());
6608 }
6609
6610 OpenFunctionBlock(closure);
6611 AddFormalParamsToScope(&closure_params, current_block_->scope);
6612 OpenBlock();
6613 async_temp_scope_ = current_block_->scope;
6614 return closure.raw();
6615 }
6616
6617
6618 // Generate the Ast nodes for the implicit code of the async* function.
6619 //
6620 // f(...) async* {
6621 // var :controller;
6622 // var :await_jump_var = -1;
6623 // var :await_context_var;
6624 // f_async_body() {
6625 // ... source code of f ...
6626 // }
6627 // :controller = new _AsyncStarStreamController(f_async_body);
6628 // return :controller.stream;
6629 // }
6630 SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure,
6631 SequenceNode* closure_body) {
6632 TRACE_PARSER("CloseAsyncGeneratorFunction");
6633 ASSERT(!closure.IsNull());
6634 ASSERT(closure_body != NULL);
6635
6636 // The block for the async closure body has already been closed. Close the
6637 // corresponding function block.
6638 CloseBlock();
6639
6640 // Make sure the implicit variables of the async generator function
6641 // are captured.
6642 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
6643 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
6644 closure_body->scope()->LookupVariable(Symbols::Controller(), false);
6645
6646 const Class& controller_class = Class::Handle(Z,
6647 Library::LookupCoreClass(Symbols::_AsyncStarStreamController()));
6648 ASSERT(!controller_class.IsNull());
6649 const Function& controller_constructor = Function::ZoneHandle(Z,
6650 controller_class.LookupConstructorAllowPrivate(
6651 Symbols::_AsyncStarStreamControllerConstructor()));
6652
6653 // :await_jump_var = -1;
6654 LocalVariable* jump_var =
6655 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false);
6656 LiteralNode* init_value =
6657 new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1)));
6658 current_block_->statements->Add(
6659 new(Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value));
6660
6661 // :controller = new _AsyncStarStreamController(body_closure);
6662 ArgumentListNode* arguments = new(Z) ArgumentListNode(Scanner::kNoSourcePos);
6663 ClosureNode* closure_obj = new(Z) ClosureNode(
6664 Scanner::kNoSourcePos, closure, NULL, closure_body->scope());
6665 arguments->Add(closure_obj);
6666 ConstructorCallNode* controller_constructor_call =
6667 new(Z) ConstructorCallNode(Scanner::kNoSourcePos,
6668 TypeArguments::ZoneHandle(Z),
6669 controller_constructor,
6670 arguments);
6671 LocalVariable* controller_var =
6672 current_block_->scope->LookupVariable(Symbols::Controller(), false);
6673 StoreLocalNode* store_controller =
6674 new(Z) StoreLocalNode(Scanner::kNoSourcePos,
6675 controller_var,
6676 controller_constructor_call);
6677 current_block_->statements->Add(store_controller);
6678
6679 // return :controller.stream;
6680 ReturnNode* return_node = new(Z) ReturnNode(Scanner::kNoSourcePos,
6681 new(Z) InstanceGetterNode(Scanner::kNoSourcePos,
6682 new(Z) LoadLocalNode(Scanner::kNoSourcePos,
6683 controller_var),
6684 Symbols::ControllerStream()));
6685 current_block_->statements->Add(return_node);
6686 return CloseBlock();
6687 }
6688
6689
6690 void Parser::OpenAsyncGeneratorClosure() {
6691 async_temp_scope_ = current_block_->scope;
6692 OpenAsyncTryBlock();
6693 }
6694
6695
6696 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) {
6697 // TODO(hausner): Is the temporary expression necessary?
6698 // We need a temporary expression to store intermediate return values.
6699 parsed_function()->EnsureExpressionTemp();
6700
6701 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body);
6702 ASSERT(new_body != NULL);
6703 ASSERT(new_body->scope() != NULL);
6704
6705 // Implicitly mark those variables below as captured. We currently mark all
6706 // variables of all scopes as captured, but as soon as we do something
6707 // smarter we rely on these internal variables to be available.
6708 new_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
6709 new_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
6710 new_body->scope()->LookupVariable(Symbols::Controller(), false);
6711 new_body->scope()->RecursivelyCaptureAllVariables();
6712 return new_body;
6713 }
6714
6715
6359 SequenceNode* Parser::CloseBlock() { 6716 SequenceNode* Parser::CloseBlock() {
6360 SequenceNode* statements = current_block_->statements; 6717 SequenceNode* statements = current_block_->statements;
6361 if (current_block_->scope != NULL) { 6718 if (current_block_->scope != NULL) {
6362 // Record the begin and end token index of the scope. 6719 // Record the begin and end token index of the scope.
6363 ASSERT(statements != NULL); 6720 ASSERT(statements != NULL);
6364 current_block_->scope->set_begin_token_pos(statements->token_pos()); 6721 current_block_->scope->set_begin_token_pos(statements->token_pos());
6365 current_block_->scope->set_end_token_pos(TokenPos()); 6722 current_block_->scope->set_end_token_pos(TokenPos());
6366 } 6723 }
6367 current_block_ = current_block_->parent; 6724 current_block_ = current_block_->parent;
6368 return statements; 6725 return statements;
(...skipping 1395 matching lines...) Expand 10 before | Expand all | Expand 10 after
7764 AstNode* Parser::ParseAwaitForStatement(String* label_name) { 8121 AstNode* Parser::ParseAwaitForStatement(String* label_name) {
7765 TRACE_PARSER("ParseAwaitForStatement"); 8122 TRACE_PARSER("ParseAwaitForStatement");
7766 ASSERT(IsAwaitKeyword()); 8123 ASSERT(IsAwaitKeyword());
7767 const intptr_t await_for_pos = TokenPos(); 8124 const intptr_t await_for_pos = TokenPos();
7768 ConsumeToken(); // await. 8125 ConsumeToken(); // await.
7769 ASSERT(CurrentToken() == Token::kFOR); 8126 ASSERT(CurrentToken() == Token::kFOR);
7770 ConsumeToken(); // for. 8127 ConsumeToken(); // for.
7771 ExpectToken(Token::kLPAREN); 8128 ExpectToken(Token::kLPAREN);
7772 8129
7773 if (!innermost_function().IsAsyncFunction() && 8130 if (!innermost_function().IsAsyncFunction() &&
7774 !innermost_function().IsAsyncClosure()) { 8131 !innermost_function().IsAsyncClosure() &&
8132 !innermost_function().IsAsyncGenerator() &&
8133 !innermost_function().IsAsyncGenClosure()) {
7775 ReportError(await_for_pos, 8134 ReportError(await_for_pos,
7776 "await for loop is only allowed in async function"); 8135 "await for loop is only allowed in an asynchronous function");
7777 } 8136 }
7778 8137
7779 // Parse loop variable. 8138 // Parse loop variable.
7780 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); 8139 bool loop_var_is_final = (CurrentToken() == Token::kFINAL);
7781 if (CurrentToken() == Token::kCONST) { 8140 if (CurrentToken() == Token::kCONST) {
7782 ReportError("Loop variable cannot be 'const'"); 8141 ReportError("Loop variable cannot be 'const'");
7783 } 8142 }
7784 bool new_loop_var = false; 8143 bool new_loop_var = false;
7785 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); 8144 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z);
7786 if (LookaheadToken(1) != Token::kIN) { 8145 if (LookaheadToken(1) != Token::kIN) {
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
8205 TRACE_PARSER("ParseFinallyBlock"); 8564 TRACE_PARSER("ParseFinallyBlock");
8206 OpenBlock(); 8565 OpenBlock();
8207 ExpectToken(Token::kLBRACE); 8566 ExpectToken(Token::kLBRACE);
8208 8567
8209 // In case of async closures we need to restore the saved try index of an 8568 // In case of async closures we need to restore the saved try index of an
8210 // outer try block (if it exists). The current try block has already been 8569 // outer try block (if it exists). The current try block has already been
8211 // removed from the stack of try blocks. 8570 // removed from the stack of try blocks.
8212 if ((innermost_function().IsAsyncClosure() || 8571 if ((innermost_function().IsAsyncClosure() ||
8213 innermost_function().IsAsyncFunction() || 8572 innermost_function().IsAsyncFunction() ||
8214 innermost_function().IsSyncGenClosure() || 8573 innermost_function().IsSyncGenClosure() ||
8215 innermost_function().IsSyncGenerator()) && 8574 innermost_function().IsSyncGenerator() ||
8575 innermost_function().IsAsyncGenerator() ||
8576 innermost_function().IsAsyncGenClosure()) &&
8216 (try_blocks_list_ != NULL)) { 8577 (try_blocks_list_ != NULL)) {
8217 // We need two unchain two scopes: finally clause, and the try block level. 8578 // We need two unchain two scopes: finally clause, and the try block level.
8218 RestoreSavedTryContext(current_block_->scope->parent()->parent(), 8579 RestoreSavedTryContext(current_block_->scope->parent()->parent(),
8219 try_blocks_list_->try_index(), 8580 try_blocks_list_->try_index(),
8220 current_block_->statements); 8581 current_block_->statements);
8221 } else { 8582 } else {
8222 parsed_function()->reset_saved_try_ctx_vars(); 8583 parsed_function()->reset_saved_try_ctx_vars();
8223 } 8584 }
8224 8585
8225 ParseStatementSequence(); 8586 ParseStatementSequence();
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
8314 } else { 8675 } else {
8315 exception_param.type = &AbstractType::ZoneHandle(Z, Type::DynamicType()); 8676 exception_param.type = &AbstractType::ZoneHandle(Z, Type::DynamicType());
8316 } 8677 }
8317 if (CurrentToken() == Token::kCATCH) { 8678 if (CurrentToken() == Token::kCATCH) {
8318 ConsumeToken(); // Consume the 'catch'. 8679 ConsumeToken(); // Consume the 'catch'.
8319 ExpectToken(Token::kLPAREN); 8680 ExpectToken(Token::kLPAREN);
8320 exception_param.token_pos = TokenPos(); 8681 exception_param.token_pos = TokenPos();
8321 exception_param.name = ExpectIdentifier("identifier expected"); 8682 exception_param.name = ExpectIdentifier("identifier expected");
8322 if (CurrentToken() == Token::kCOMMA) { 8683 if (CurrentToken() == Token::kCOMMA) {
8323 ConsumeToken(); 8684 ConsumeToken();
8324 // TODO(hausner): Make implicit type be StackTrace, not dynamic.
8325 stack_trace_param.type = 8685 stack_trace_param.type =
8326 &AbstractType::ZoneHandle(Z, Type::DynamicType()); 8686 &AbstractType::ZoneHandle(Z, Type::DynamicType());
8327 stack_trace_param.token_pos = TokenPos(); 8687 stack_trace_param.token_pos = TokenPos();
8328 stack_trace_param.name = ExpectIdentifier("identifier expected"); 8688 stack_trace_param.name = ExpectIdentifier("identifier expected");
8329 } 8689 }
8330 ExpectToken(Token::kRPAREN); 8690 ExpectToken(Token::kRPAREN);
8331 } 8691 }
8332 8692
8333 // Create a block containing the catch clause parameters and the 8693 // Create a block containing the catch clause parameters and the
8334 // following code: 8694 // following code:
(...skipping 16 matching lines...) Expand all
8351 // A stack trace variable is specified in this block, so generate code 8711 // A stack trace variable is specified in this block, so generate code
8352 // to load the stack trace object (:stack_trace_var) into the stack 8712 // to load the stack trace object (:stack_trace_var) into the stack
8353 // trace variable specified in this block. 8713 // trace variable specified in this block.
8354 *needs_stack_trace = true; 8714 *needs_stack_trace = true;
8355 ASSERT(stack_trace_var != NULL); 8715 ASSERT(stack_trace_var != NULL);
8356 current_block_->statements->Add(new(Z) StoreLocalNode( 8716 current_block_->statements->Add(new(Z) StoreLocalNode(
8357 catch_pos, stack_trace_param.var, new(Z) LoadLocalNode( 8717 catch_pos, stack_trace_param.var, new(Z) LoadLocalNode(
8358 catch_pos, stack_trace_var))); 8718 catch_pos, stack_trace_var)));
8359 } 8719 }
8360 8720
8361 // Add nested block with user-defined code. This blocks allows 8721 // Add nested block with user-defined code. This block allows
8362 // declarations in the body to shadow the catch parameters. 8722 // declarations in the body to shadow the catch parameters.
8363 CheckToken(Token::kLBRACE); 8723 CheckToken(Token::kLBRACE);
8364 8724
8365 // In case of async closures we need to restore the saved try index of an 8725 // In case of async closures we need to restore the saved try index of an
8366 // outer try block (if it exists). 8726 // outer try block (if it exists).
8367 ASSERT(try_blocks_list_ != NULL); 8727 ASSERT(try_blocks_list_ != NULL);
8368 if (innermost_function().IsAsyncClosure() || 8728 if (innermost_function().IsAsyncClosure() ||
8369 innermost_function().IsAsyncFunction() || 8729 innermost_function().IsAsyncFunction() ||
8370 innermost_function().IsSyncGenClosure() || 8730 innermost_function().IsSyncGenClosure() ||
8371 innermost_function().IsSyncGenerator()) { 8731 innermost_function().IsSyncGenerator() ||
8732 innermost_function().IsAsyncGenerator() ||
8733 innermost_function().IsAsyncGenClosure()) {
8372 if ((try_blocks_list_->outer_try_block() != NULL) && 8734 if ((try_blocks_list_->outer_try_block() != NULL) &&
8373 (try_blocks_list_->outer_try_block()->try_block() 8735 (try_blocks_list_->outer_try_block()->try_block()
8374 ->scope->function_level() == 8736 ->scope->function_level() ==
8375 current_block_->scope->function_level())) { 8737 current_block_->scope->function_level())) {
8376 // We need to unchain three scope levels: catch clause, catch 8738 // We need to unchain three scope levels: catch clause, catch
8377 // parameters, and the general try block. 8739 // parameters, and the general try block.
8378 RestoreSavedTryContext( 8740 RestoreSavedTryContext(
8379 current_block_->scope->parent()->parent()->parent(), 8741 current_block_->scope->parent()->parent()->parent(),
8380 try_blocks_list_->outer_try_block()->try_index(), 8742 try_blocks_list_->outer_try_block()->try_index(),
8381 current_block_->statements); 8743 current_block_->statements);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
8471 while (!type_tests.is_empty()) { 8833 while (!type_tests.is_empty()) {
8472 AstNode* type_test = type_tests.RemoveLast(); 8834 AstNode* type_test = type_tests.RemoveLast();
8473 SequenceNode* catch_block = catch_blocks.RemoveLast(); 8835 SequenceNode* catch_block = catch_blocks.RemoveLast();
8474 8836
8475 // In case of async closures we need to restore the saved try index of an 8837 // In case of async closures we need to restore the saved try index of an
8476 // outer try block (if it exists). 8838 // outer try block (if it exists).
8477 ASSERT(try_blocks_list_ != NULL); 8839 ASSERT(try_blocks_list_ != NULL);
8478 if (innermost_function().IsAsyncClosure() || 8840 if (innermost_function().IsAsyncClosure() ||
8479 innermost_function().IsAsyncFunction() || 8841 innermost_function().IsAsyncFunction() ||
8480 innermost_function().IsSyncGenClosure() || 8842 innermost_function().IsSyncGenClosure() ||
8481 innermost_function().IsSyncGenerator()) { 8843 innermost_function().IsSyncGenerator() ||
8844 innermost_function().IsAsyncGenerator() ||
8845 innermost_function().IsAsyncGenClosure()) {
8482 if ((try_blocks_list_->outer_try_block() != NULL) && 8846 if ((try_blocks_list_->outer_try_block() != NULL) &&
8483 (try_blocks_list_->outer_try_block()->try_block() 8847 (try_blocks_list_->outer_try_block()->try_block()
8484 ->scope->function_level() == 8848 ->scope->function_level() ==
8485 current_block_->scope->function_level())) { 8849 current_block_->scope->function_level())) {
8486 // We need to unchain three scope levels: catch clause, catch 8850 // We need to unchain three scope levels: catch clause, catch
8487 // parameters, and the general try block. 8851 // parameters, and the general try block.
8488 RestoreSavedTryContext( 8852 RestoreSavedTryContext(
8489 current_block_->scope->parent()->parent(), 8853 current_block_->scope->parent()->parent(),
8490 try_blocks_list_->outer_try_block()->try_index(), 8854 try_blocks_list_->outer_try_block()->try_index(),
8491 current_block_->statements); 8855 current_block_->statements);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
8610 } 8974 }
8611 8975
8612 // Now parse the 'try' block. 8976 // Now parse the 'try' block.
8613 OpenBlock(); 8977 OpenBlock();
8614 PushTryBlock(current_block_); 8978 PushTryBlock(current_block_);
8615 ExpectToken(Token::kLBRACE); 8979 ExpectToken(Token::kLBRACE);
8616 8980
8617 if (innermost_function().IsAsyncClosure() || 8981 if (innermost_function().IsAsyncClosure() ||
8618 innermost_function().IsAsyncFunction() || 8982 innermost_function().IsAsyncFunction() ||
8619 innermost_function().IsSyncGenClosure() || 8983 innermost_function().IsSyncGenClosure() ||
8620 innermost_function().IsSyncGenerator()) { 8984 innermost_function().IsSyncGenerator() ||
8985 innermost_function().IsAsyncGenerator() ||
8986 innermost_function().IsAsyncGenClosure()) {
8621 SetupSavedTryContext(context_var); 8987 SetupSavedTryContext(context_var);
8622 } 8988 }
8623 8989
8624 ParseStatementSequence(); 8990 ParseStatementSequence();
8625 ExpectToken(Token::kRBRACE); 8991 ExpectToken(Token::kRBRACE);
8626 SequenceNode* try_block = CloseBlock(); 8992 SequenceNode* try_block = CloseBlock();
8627 8993
8628 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && 8994 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") &&
8629 (CurrentToken() != Token::kFINALLY)) { 8995 (CurrentToken() != Token::kFINALLY)) {
8630 ReportError("catch or finally clause expected"); 8996 ReportError("catch or finally clause expected");
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
8754 ReportError(jump_pos, "'break' to case clause label is illegal"); 9120 ReportError(jump_pos, "'break' to case clause label is illegal");
8755 } 9121 }
8756 if (target->FunctionLevel() != current_block_->scope->function_level()) { 9122 if (target->FunctionLevel() != current_block_->scope->function_level()) {
8757 ReportError(jump_pos, "'%s' target must be in same function context", 9123 ReportError(jump_pos, "'%s' target must be in same function context",
8758 Token::Str(jump_kind)); 9124 Token::Str(jump_kind));
8759 } 9125 }
8760 return new(Z) JumpNode(jump_pos, jump_kind, target); 9126 return new(Z) JumpNode(jump_pos, jump_kind, target);
8761 } 9127 }
8762 9128
8763 9129
9130 AstNode* Parser::ParseYieldStatement() {
9131 bool is_yield_each = false;
9132 const intptr_t yield_pos = TokenPos();
9133 ConsumeToken(); // yield reserved word.
9134 ASSERT(innermost_function().IsGenerator() ||
9135 innermost_function().IsSyncGenClosure() ||
9136 innermost_function().IsAsyncGenerator() ||
9137 innermost_function().IsAsyncGenClosure());
9138 if (CurrentToken() == Token::kMUL) {
9139 is_yield_each = true;
9140 ConsumeToken();
9141 }
9142 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
9143
9144 LetNode* yield = new(Z) LetNode(yield_pos);
9145 if (innermost_function().IsSyncGenerator() ||
9146 innermost_function().IsSyncGenClosure()) {
9147 // Yield statement in sync* function.
9148
9149 LocalVariable* iterator_param =
9150 LookupLocalScope(Symbols::IteratorParameter());
9151 ASSERT(iterator_param != NULL);
9152 // Generate :iterator.current = expr;
9153 AstNode* iterator =
9154 new(Z) LoadLocalNode(Scanner::kNoSourcePos, iterator_param);
9155 AstNode* store_current =
9156 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
9157 iterator,
9158 String::ZoneHandle(Symbols::Current().raw()),
9159 expr);
9160 yield->AddNode(store_current);
9161 if (is_yield_each) {
9162 // Generate :iterator.isYieldEach = true;
9163 AstNode* set_is_yield_each =
9164 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
9165 iterator,
9166 String::ZoneHandle(Symbols::IsYieldEach().raw()),
9167 new(Z) LiteralNode(TokenPos(), Bool::True()));
9168 yield->AddNode(set_is_yield_each);
9169 }
9170 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
9171 await_marker->set_scope(current_block_->scope);
9172 yield->AddNode(await_marker);
9173 // Return true to indicate that a value has been generated.
9174 ReturnNode* return_true = new(Z) ReturnNode(yield_pos,
9175 new(Z) LiteralNode(TokenPos(), Bool::True()));
9176 return_true->set_return_type(ReturnNode::kContinuationTarget);
9177 yield->AddNode(return_true);
9178
9179 // If this expression is part of a try block, also append the code for
9180 // restoring the saved try context that lives on the stack.
9181 const String& async_saved_try_ctx_name =
9182 String::Handle(Z, parsed_function()->async_saved_try_ctx_name());
9183 if (!async_saved_try_ctx_name.IsNull()) {
9184 LocalVariable* async_saved_try_ctx =
9185 current_block_->scope->LookupVariable(async_saved_try_ctx_name,
9186 false);
9187 ASSERT(async_saved_try_ctx != NULL);
9188 yield->AddNode(new (Z) StoreLocalNode(
9189 Scanner::kNoSourcePos,
9190 parsed_function()->saved_try_ctx(),
9191 new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_saved_try_ctx)));
9192 }
9193 } else {
9194 // yield statement in async* function.
9195 ASSERT(innermost_function().IsAsyncGenerator() ||
9196 innermost_function().IsAsyncGenClosure());
9197
9198 LocalVariable* controller_var = LookupLocalScope(Symbols::Controller());
9199 ASSERT(controller_var != NULL);
9200 // :controller.add[Stream](expr);
9201 ArgumentListNode* add_args = new(Z) ArgumentListNode(yield_pos);
9202 add_args->Add(expr);
9203 AstNode* add_call =
9204 new(Z) InstanceCallNode(yield_pos,
9205 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller_var),
9206 is_yield_each ? Symbols::AddStream() : Symbols::add(),
9207 add_args);
9208
9209 // if (:controller.isPaused) {
9210 // await_marker;
9211 // continuation_return;
9212 // }
9213 /*
9214 AstNode* is_paused = new(Z) InstanceGetterNode(
9215 Scanner::kNoSourcePos,
9216 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller_var),
9217 Symbols::isPaused());*/
9218
9219 SequenceNode* true_branch =
9220 new(Z) SequenceNode(Scanner::kNoSourcePos, current_block_->scope);
9221 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
9222 await_marker->set_scope(current_block_->scope);
9223 true_branch->Add(await_marker);
9224 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos);
9225 continuation_return->set_return_type(ReturnNode::kContinuationTarget);
9226 true_branch->Add(continuation_return);
9227
9228 AstNode* if_is_paused =
9229 new(Z) IfNode(Scanner::kNoSourcePos, add_call, true_branch, NULL);
9230 yield->AddNode(if_is_paused);
9231 }
9232 return yield;
9233 }
9234
9235
8764 AstNode* Parser::ParseStatement() { 9236 AstNode* Parser::ParseStatement() {
8765 TRACE_PARSER("ParseStatement"); 9237 TRACE_PARSER("ParseStatement");
8766 AstNode* statement = NULL; 9238 AstNode* statement = NULL;
8767 intptr_t label_pos = 0; 9239 intptr_t label_pos = 0;
8768 String* label_name = NULL; 9240 String* label_name = NULL;
8769 if (IsIdentifier()) { 9241 if (IsIdentifier()) {
8770 if (LookaheadToken(1) == Token::kCOLON) { 9242 if (LookaheadToken(1) == Token::kCOLON) {
8771 // Statement starts with a label. 9243 // Statement starts with a label.
8772 label_name = CurrentLiteral(); 9244 label_name = CurrentLiteral();
8773 label_pos = TokenPos(); 9245 label_pos = TokenPos();
(...skipping 19 matching lines...) Expand all
8793 statement = ParseTryStatement(label_name); 9265 statement = ParseTryStatement(label_name);
8794 } else if (token == Token::kRETURN) { 9266 } else if (token == Token::kRETURN) {
8795 const intptr_t return_pos = TokenPos(); 9267 const intptr_t return_pos = TokenPos();
8796 ConsumeToken(); 9268 ConsumeToken();
8797 if (CurrentToken() != Token::kSEMICOLON) { 9269 if (CurrentToken() != Token::kSEMICOLON) {
8798 const intptr_t expr_pos = TokenPos(); 9270 const intptr_t expr_pos = TokenPos();
8799 if (current_function().IsGenerativeConstructor() && 9271 if (current_function().IsGenerativeConstructor() &&
8800 (current_block_->scope->function_level() == 0)) { 9272 (current_block_->scope->function_level() == 0)) {
8801 ReportError(expr_pos, 9273 ReportError(expr_pos,
8802 "return of a value is not allowed in constructors"); 9274 "return of a value is not allowed in constructors");
8803 } else if (current_function().IsGenerator()) { 9275 } else if (current_function().IsGeneratorClosure() &&
9276 (current_block_->scope->function_level() == 0)) {
8804 ReportError(expr_pos, "generator functions may not return a value"); 9277 ReportError(expr_pos, "generator functions may not return a value");
8805 } 9278 }
8806 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); 9279 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
8807 statement = new(Z) ReturnNode(statement_pos, expr); 9280 statement = new(Z) ReturnNode(statement_pos, expr);
8808 } else { 9281 } else {
8809 if (current_function().IsSyncGenClosure() && 9282 if (current_function().IsSyncGenClosure() &&
8810 (current_block_->scope->function_level() == 0)) { 9283 (current_block_->scope->function_level() == 0)) {
8811 // In a synchronous generator, return without an expression 9284 // In a synchronous generator, return without an expression
8812 // returns false, signaling that the iterator terminates and 9285 // returns false, signaling that the iterator terminates and
8813 // did not yield a value. 9286 // did not yield a value.
8814 statement = new(Z) ReturnNode(statement_pos, 9287 statement = new(Z) ReturnNode(statement_pos,
8815 new(Z) LiteralNode(return_pos, Bool::False())); 9288 new(Z) LiteralNode(return_pos, Bool::False()));
8816 } else { 9289 } else {
8817 statement = new(Z) ReturnNode(statement_pos); 9290 statement = new(Z) ReturnNode(statement_pos);
8818 } 9291 }
8819 } 9292 }
8820 AddNodeForFinallyInlining(statement); 9293 AddNodeForFinallyInlining(statement);
8821 ExpectSemicolon(); 9294 ExpectSemicolon();
8822 } else if (IsYieldKeyword()) { 9295 } else if (IsYieldKeyword()) {
8823 bool is_yield_each = false; 9296 statement = ParseYieldStatement();
8824 ConsumeToken();
8825 ASSERT(innermost_function().IsGenerator() ||
8826 innermost_function().IsSyncGenClosure());
8827 if (CurrentToken() == Token::kMUL) {
8828 is_yield_each = true;
8829 ConsumeToken();
8830 }
8831 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
8832 LocalVariable* iterator_param =
8833 LookupLocalScope(Symbols::IteratorParameter());
8834 ASSERT(iterator_param != NULL);
8835 // Generate :iterator.current = expr;
8836 AstNode* iterator =
8837 new(Z) LoadLocalNode(Scanner::kNoSourcePos, iterator_param);
8838 AstNode* store_current =
8839 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
8840 iterator,
8841 String::ZoneHandle(Symbols::Current().raw()),
8842 expr);
8843 LetNode* yield = new(Z) LetNode(statement_pos);
8844 yield->AddNode(store_current);
8845 if (is_yield_each) {
8846 // Generate :iterator.isYieldEach = true;
8847 AstNode* set_is_yield_each =
8848 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
8849 iterator,
8850 String::ZoneHandle(Symbols::IsYieldEach().raw()),
8851 new(Z) LiteralNode(TokenPos(), Bool::True()));
8852 yield->AddNode(set_is_yield_each);
8853 }
8854 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
8855 await_marker->set_scope(current_block_->scope);
8856 yield->AddNode(await_marker);
8857 // Return true to indicate that a value has been generated.
8858 ReturnNode* return_true = new(Z) ReturnNode(statement_pos,
8859 new(Z) LiteralNode(TokenPos(), Bool::True()));
8860 return_true->set_return_type(ReturnNode::kContinuationTarget);
8861 yield->AddNode(return_true);
8862
8863 // If this expression is part of a try block, also append the code for
8864 // restoring the saved try context that lives on the stack.
8865 const String& async_saved_try_ctx_name =
8866 String::Handle(Z, parsed_function()->async_saved_try_ctx_name());
8867 if (!async_saved_try_ctx_name.IsNull()) {
8868 LocalVariable* async_saved_try_ctx =
8869 current_block_->scope->LookupVariable(async_saved_try_ctx_name,
8870 false);
8871 ASSERT(async_saved_try_ctx != NULL);
8872 yield->AddNode(new (Z) StoreLocalNode(
8873 Scanner::kNoSourcePos,
8874 parsed_function()->saved_try_ctx(),
8875 new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_saved_try_ctx)));
8876 }
8877
8878 statement = yield;
8879 ExpectSemicolon(); 9297 ExpectSemicolon();
8880 } else if (token == Token::kIF) { 9298 } else if (token == Token::kIF) {
8881 statement = ParseIfStatement(label_name); 9299 statement = ParseIfStatement(label_name);
8882 } else if (token == Token::kASSERT) { 9300 } else if (token == Token::kASSERT) {
8883 statement = ParseAssertStatement(); 9301 statement = ParseAssertStatement();
8884 ExpectSemicolon(); 9302 ExpectSemicolon();
8885 } else if (IsVariableDeclaration()) { 9303 } else if (IsVariableDeclaration()) {
8886 statement = ParseVariableDeclarationList(); 9304 statement = ParseVariableDeclarationList();
8887 ExpectSemicolon(); 9305 ExpectSemicolon();
8888 } else if (IsFunctionDeclaration()) { 9306 } else if (IsFunctionDeclaration()) {
(...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after
9719 } 10137 }
9720 10138
9721 10139
9722 AstNode* Parser::ParseUnaryExpr() { 10140 AstNode* Parser::ParseUnaryExpr() {
9723 TRACE_PARSER("ParseUnaryExpr"); 10141 TRACE_PARSER("ParseUnaryExpr");
9724 AstNode* expr = NULL; 10142 AstNode* expr = NULL;
9725 const intptr_t op_pos = TokenPos(); 10143 const intptr_t op_pos = TokenPos();
9726 if (IsAwaitKeyword()) { 10144 if (IsAwaitKeyword()) {
9727 TRACE_PARSER("ParseAwaitExpr"); 10145 TRACE_PARSER("ParseAwaitExpr");
9728 if (!innermost_function().IsAsyncFunction() && 10146 if (!innermost_function().IsAsyncFunction() &&
9729 !innermost_function().IsAsyncClosure()) { 10147 !innermost_function().IsAsyncClosure() &&
9730 ReportError("await operator is only allowed in async function"); 10148 !innermost_function().IsAsyncGenerator() &&
10149 !innermost_function().IsAsyncGenClosure()) {
10150 ReportError("await operator is only allowed in an asynchronous function");
9731 } 10151 }
9732 ConsumeToken(); 10152 ConsumeToken();
9733 parsed_function()->record_await(); 10153 parsed_function()->record_await();
9734 expr = new (Z) AwaitNode(op_pos, ParseUnaryExpr()); 10154 expr = new (Z) AwaitNode(op_pos, ParseUnaryExpr());
9735 } else if (IsPrefixOperator(CurrentToken())) { 10155 } else if (IsPrefixOperator(CurrentToken())) {
9736 Token::Kind unary_op = CurrentToken(); 10156 Token::Kind unary_op = CurrentToken();
9737 if (unary_op == Token::kSUB) { 10157 if (unary_op == Token::kSUB) {
9738 unary_op = Token::kNEGATE; 10158 unary_op = Token::kNEGATE;
9739 } 10159 }
9740 ConsumeToken(); 10160 ConsumeToken();
(...skipping 2816 matching lines...) Expand 10 before | Expand all | Expand 10 after
12557 void Parser::SkipQualIdent() { 12977 void Parser::SkipQualIdent() {
12558 ASSERT(IsIdentifier()); 12978 ASSERT(IsIdentifier());
12559 ConsumeToken(); 12979 ConsumeToken();
12560 if (CurrentToken() == Token::kPERIOD) { 12980 if (CurrentToken() == Token::kPERIOD) {
12561 ConsumeToken(); // Consume the kPERIOD token. 12981 ConsumeToken(); // Consume the kPERIOD token.
12562 ExpectIdentifier("identifier expected after '.'"); 12982 ExpectIdentifier("identifier expected after '.'");
12563 } 12983 }
12564 } 12984 }
12565 12985
12566 } // namespace dart 12986 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698