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

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, 9 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
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 3092 matching lines...) Expand 10 before | Expand all | Expand 10 after
3103 AddFormalParamsToScope(&params, current_block_->scope); 3103 AddFormalParamsToScope(&params, current_block_->scope);
3104 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); 3104 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved());
3105 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { 3105 if (!Function::Handle(func.parent_function()).IsGetterFunction()) {
3106 // Parse and discard any formal parameters. They are accessed as 3106 // Parse and discard any formal parameters. They are accessed as
3107 // context variables. 3107 // context variables.
3108 ParamList discarded_params; 3108 ParamList discarded_params;
3109 ParseFormalParameterList(allow_explicit_default_values, 3109 ParseFormalParameterList(allow_explicit_default_values,
3110 false, 3110 false,
3111 &discarded_params); 3111 &discarded_params);
3112 } 3112 }
3113 } else if (func.IsAsyncGenClosure()) {
3114 AddAsyncGenClosureParameters(&params);
3115 SetupDefaultsForOptionalParams(&params, default_parameter_values);
3116 AddFormalParamsToScope(&params, current_block_->scope);
3117 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved());
3118 ASSERT(func.NumParameters() == params.parameters->length());
3119 if (!Function::Handle(func.parent_function()).IsGetterFunction()) {
3120 // Parse and discard any formal parameters. They are accessed as
3121 // context variables.
3122 ParamList discarded_params;
3123 ParseFormalParameterList(allow_explicit_default_values,
3124 false,
3125 &discarded_params);
3126 }
3113 } else { 3127 } else {
3114 ParseFormalParameterList(allow_explicit_default_values, false, &params); 3128 ParseFormalParameterList(allow_explicit_default_values, false, &params);
3115 3129
3116 // The number of parameters and their type are not yet set in local 3130 // The number of parameters and their type are not yet set in local
3117 // functions, since they are not 'top-level' parsed. 3131 // functions, since they are not 'top-level' parsed.
3118 if (func.IsLocalFunction()) { 3132 if (func.IsLocalFunction()) {
3119 AddFormalParamsToFunction(&params, func); 3133 AddFormalParamsToFunction(&params, func);
3120 } 3134 }
3121 SetupDefaultsForOptionalParams(&params, default_parameter_values); 3135 SetupDefaultsForOptionalParams(&params, default_parameter_values);
3122 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); 3136 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3171 ASSERT(func.is_debuggable()); 3185 ASSERT(func.is_debuggable());
3172 OpenAsyncClosure(); 3186 OpenAsyncClosure();
3173 } else if (func.IsSyncGenerator()) { 3187 } else if (func.IsSyncGenerator()) {
3174 // The code of a sync generator is synthesized. Disable debugging. 3188 // The code of a sync generator is synthesized. Disable debugging.
3175 func.set_is_debuggable(false); 3189 func.set_is_debuggable(false);
3176 generated_body_closure = OpenSyncGeneratorFunction(func.token_pos()); 3190 generated_body_closure = OpenSyncGeneratorFunction(func.token_pos());
3177 } else if (func.IsSyncGenClosure()) { 3191 } else if (func.IsSyncGenClosure()) {
3178 // The closure containing the body of a sync generator is debuggable. 3192 // The closure containing the body of a sync generator is debuggable.
3179 ASSERT(func.is_debuggable()); 3193 ASSERT(func.is_debuggable());
3180 async_temp_scope_ = current_block_->scope; 3194 async_temp_scope_ = current_block_->scope;
3195 } else if (func.IsAsyncGenerator()) {
3196 func.set_is_debuggable(false);
3197 generated_body_closure = OpenAsyncGeneratorFunction(func.token_pos());
3198 } else if (func.IsAsyncGenClosure()) {
3199 // The closure containing the body of an async* function is debuggable.
3200 ASSERT(func.is_debuggable());
3201 OpenAsyncGeneratorClosure();
3181 } 3202 }
3182 3203
3183 BoolScope allow_await(&this->await_is_keyword_, 3204 BoolScope allow_await(&this->await_is_keyword_,
3184 func.IsAsyncOrGenerator() || func.is_generated_body()); 3205 func.IsAsyncOrGenerator() || func.is_generated_body());
3185 intptr_t end_token_pos = 0; 3206 intptr_t end_token_pos = 0;
3186 if (CurrentToken() == Token::kLBRACE) { 3207 if (CurrentToken() == Token::kLBRACE) {
3187 ConsumeToken(); 3208 ConsumeToken();
3188 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { 3209 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) {
3189 const Class& owner = Class::Handle(Z, func.Owner()); 3210 const Class& owner = Class::Handle(Z, func.Owner());
3190 if (!owner.IsObjectClass()) { 3211 if (!owner.IsObjectClass()) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3248 if (func.IsAsyncFunction()) { 3269 if (func.IsAsyncFunction()) {
3249 body = CloseAsyncFunction(generated_body_closure, body); 3270 body = CloseAsyncFunction(generated_body_closure, body);
3250 generated_body_closure.set_end_token_pos(end_token_pos); 3271 generated_body_closure.set_end_token_pos(end_token_pos);
3251 } else if (func.IsAsyncClosure()) { 3272 } else if (func.IsAsyncClosure()) {
3252 body = CloseAsyncClosure(body); 3273 body = CloseAsyncClosure(body);
3253 } else if (func.IsSyncGenerator()) { 3274 } else if (func.IsSyncGenerator()) {
3254 body = CloseSyncGenFunction(generated_body_closure, body); 3275 body = CloseSyncGenFunction(generated_body_closure, body);
3255 generated_body_closure.set_end_token_pos(end_token_pos); 3276 generated_body_closure.set_end_token_pos(end_token_pos);
3256 } else if (func.IsSyncGenClosure()) { 3277 } else if (func.IsSyncGenClosure()) {
3257 body->scope()->RecursivelyCaptureAllVariables(); 3278 body->scope()->RecursivelyCaptureAllVariables();
3279 } else if (func.IsAsyncGenerator()) {
3280 body = CloseAsyncGeneratorFunction(generated_body_closure, body);
3281 generated_body_closure.set_end_token_pos(end_token_pos);
3282 } else if (func.IsAsyncGenClosure()) {
3283 body = CloseAsyncGeneratorClosure(body);
3258 } 3284 }
3259 current_block_->statements->Add(body); 3285 current_block_->statements->Add(body);
3260 innermost_function_ = saved_innermost_function.raw(); 3286 innermost_function_ = saved_innermost_function.raw();
3261 last_used_try_index_ = saved_try_index; 3287 last_used_try_index_ = saved_try_index;
3262 async_temp_scope_ = saved_async_temp_scope; 3288 async_temp_scope_ = saved_async_temp_scope;
3263 return CloseBlock(); 3289 return CloseBlock();
3264 } 3290 }
3265 3291
3266 3292
3267 void Parser::AddEqualityNullCheck() { 3293 void Parser::AddEqualityNullCheck() {
(...skipping 1977 matching lines...) Expand 10 before | Expand all | Expand 10 after
5245 ExpectSemicolon(); // Reports error. 5271 ExpectSemicolon(); // Reports error.
5246 } 5272 }
5247 } 5273 }
5248 } 5274 }
5249 5275
5250 5276
5251 RawFunction::AsyncModifier Parser::ParseFunctionModifier() { 5277 RawFunction::AsyncModifier Parser::ParseFunctionModifier() {
5252 if (CurrentLiteral()->raw() == Symbols::Async().raw()) { 5278 if (CurrentLiteral()->raw() == Symbols::Async().raw()) {
5253 ConsumeToken(); 5279 ConsumeToken();
5254 if (CurrentToken() == Token::kMUL) { 5280 if (CurrentToken() == Token::kMUL) {
5255 ReportError("async* generator functions are not yet supported"); 5281 const bool enableAsyncStar = true;
5282 if (!enableAsyncStar) {
5283 ReportError("async* generator functions are not yet supported");
5284 }
5256 ConsumeToken(); 5285 ConsumeToken();
5257 return RawFunction::kAsyncGen; 5286 return RawFunction::kAsyncGen;
5258 } else { 5287 } else {
5259 return RawFunction::kAsync; 5288 return RawFunction::kAsync;
5260 } 5289 }
5261 } else if ((CurrentLiteral()->raw() == Symbols::Sync().raw()) && 5290 } else if ((CurrentLiteral()->raw() == Symbols::Sync().raw()) &&
5262 (LookaheadToken(1) == Token::kMUL)) { 5291 (LookaheadToken(1) == Token::kMUL)) {
5263 const bool enableSyncStar = true; 5292 const bool enableSyncStar = true;
5264 if (!enableSyncStar) { 5293 if (!enableSyncStar) {
5265 ReportError("sync* generator functions are not yet supported"); 5294 ReportError("sync* generator functions are not yet supported");
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after
5936 5965
5937 void Parser::OpenAsyncClosure() { 5966 void Parser::OpenAsyncClosure() {
5938 TRACE_PARSER("OpenAsyncClosure"); 5967 TRACE_PARSER("OpenAsyncClosure");
5939 5968
5940 async_temp_scope_ = current_block_->scope; 5969 async_temp_scope_ = current_block_->scope;
5941 5970
5942 OpenAsyncTryBlock(); 5971 OpenAsyncTryBlock();
5943 } 5972 }
5944 5973
5945 5974
5946 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { 5975 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode *body) {
5976 TRACE_PARSER("CloseAsyncGeneratorTryBlock");
5977 // The generated try-catch-finally that wraps the async generator function
5978 // body is the outermost try statement.
5979 ASSERT(try_blocks_list_ != NULL);
5980 ASSERT(try_blocks_list_->outer_try_block() == NULL);
5981 // We only get here when parsing an async generator body.
5982 ASSERT(innermost_function().IsAsyncGenClosure());
5983
5984 const intptr_t try_end_pos = innermost_function().end_token_pos();
5985
5986 // The try-block (closure body code) has been parsed. We are now
5987 // generating the code for the catch block.
5947 try_blocks_list_->enter_catch(); 5988 try_blocks_list_->enter_catch();
5989 OpenBlock(); // Catch handler list.
5990 OpenBlock(); // Catch block.
5948 5991
5949 OpenBlock(); 5992 // Add the exception and stack trace parameters to the scope.
5950 OpenBlock();
5951 const AbstractType& dynamic_type = 5993 const AbstractType& dynamic_type =
5952 AbstractType::ZoneHandle(Z, Type::DynamicType()); 5994 AbstractType::ZoneHandle(Z, Type::DynamicType());
5953 CatchParamDesc exception_param; 5995 CatchParamDesc exception_param;
5954 CatchParamDesc stack_trace_param; 5996 CatchParamDesc stack_trace_param;
5955 exception_param.token_pos = Scanner::kNoSourcePos; 5997 exception_param.token_pos = Scanner::kNoSourcePos;
5956 exception_param.type = &dynamic_type; 5998 exception_param.type = &dynamic_type;
5957 exception_param.name = &Symbols::ExceptionParameter(); 5999 exception_param.name = &Symbols::ExceptionParameter();
5958 stack_trace_param.token_pos = Scanner::kNoSourcePos; 6000 stack_trace_param.token_pos = Scanner::kNoSourcePos;
5959 stack_trace_param.type = &dynamic_type; 6001 stack_trace_param.type = &dynamic_type;
5960 stack_trace_param.name = &Symbols::StackTraceParameter(); 6002 stack_trace_param.name = &Symbols::StackTraceParameter();
5961 6003
5962 AddCatchParamsToScope( 6004 AddCatchParamsToScope(
5963 &exception_param, &stack_trace_param, current_block_->scope); 6005 &exception_param, &stack_trace_param, current_block_->scope);
5964 6006
6007 // Generate code to save the exception object and stack trace
6008 // in local variables.
5965 LocalVariable* context_var = current_block_->scope->LookupVariable( 6009 LocalVariable* context_var = current_block_->scope->LookupVariable(
5966 Symbols::SavedTryContextVar(), false); 6010 Symbols::SavedTryContextVar(), false);
5967 ASSERT(context_var != NULL); 6011 ASSERT(context_var != NULL);
5968 6012
5969 LocalVariable* exception_var = current_block_->scope->LookupVariable( 6013 LocalVariable* exception_var = current_block_->scope->LookupVariable(
5970 Symbols::ExceptionVar(), false); 6014 Symbols::ExceptionVar(), false);
5971 ASSERT(exception_var != NULL); 6015 ASSERT(exception_var != NULL);
5972 if (exception_param.var != NULL) { 6016 if (exception_param.var != NULL) {
5973 // Generate code to load the exception object (:exception_var) into 6017 // Generate code to load the exception object (:exception_var) into
5974 // the exception variable specified in this block. 6018 // the exception variable specified in this block.
(...skipping 11 matching lines...) Expand all
5986 // to load the stack trace object (:stack_trace_var) into the stack 6030 // to load the stack trace object (:stack_trace_var) into the stack
5987 // trace variable specified in this block. 6031 // trace variable specified in this block.
5988 current_block_->statements->Add(new(Z) StoreLocalNode( 6032 current_block_->statements->Add(new(Z) StoreLocalNode(
5989 Scanner::kNoSourcePos, 6033 Scanner::kNoSourcePos,
5990 stack_trace_param.var, 6034 stack_trace_param.var,
5991 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); 6035 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
5992 } 6036 }
5993 6037
5994 SaveExceptionAndStacktrace(exception_var, stack_trace_var); 6038 SaveExceptionAndStacktrace(exception_var, stack_trace_var);
5995 6039
6040 // Catch block: add the error to the stream.
6041 // :controller.AddError(:exception, :stack_trace);
6042 // return; // The finally block will close the stream.
6043 LocalVariable* controller =
6044 current_block_->scope->LookupVariable(Symbols::Controller(), false);
6045 ASSERT(controller != NULL);
6046 ArgumentListNode* args =
6047 new(Z) ArgumentListNode(Scanner::kNoSourcePos);
6048 args->Add(new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var));
6049 args->Add(new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var));
6050 current_block_->statements->Add(
6051 new(Z) InstanceCallNode(try_end_pos,
6052 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller),
6053 Symbols::AddError(),
6054 args));
6055 ReturnNode* return_node = new(Z) ReturnNode(Scanner::kNoSourcePos);
6056 AddNodeForFinallyInlining(return_node);
6057 current_block_->statements->Add(return_node);
6058 AstNode* catch_block = CloseBlock();
6059 current_block_->statements->Add(catch_block);
6060 SequenceNode* catch_handler_list = CloseBlock();
6061
6062 TryBlocks* try_block = PopTryBlock();
6063 ASSERT(try_blocks_list_ == NULL); // We popped the outermost try block.
6064
6065 // Finally block: closing the stream and returning. (Note: the return
6066 // is necessary otherwise the back-end will append a rethrow of the
6067 // current exception.)
6068 // :controller.close();
6069 // return;
6070 // We need to inline this code in all recorded exit points.
6071 intptr_t node_index = 0;
6072 SequenceNode* finally_clause = NULL;
6073 do {
6074 OpenBlock();
6075 ArgumentListNode* no_args =
6076 new(Z) ArgumentListNode(Scanner::kNoSourcePos);
6077 current_block_->statements->Add(
6078 new(Z) InstanceCallNode(try_end_pos,
6079 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller),
6080 Symbols::Close(),
6081 no_args));
6082
6083 ReturnNode* return_node = new(Z) ReturnNode(Scanner::kNoSourcePos);
6084 current_block_->statements->Add(return_node);
6085
6086 finally_clause = CloseBlock();
6087 AstNode* node_to_inline = try_block->GetNodeToInlineFinally(node_index);
6088 if (node_to_inline != NULL) {
6089 InlinedFinallyNode* node =
6090 new(Z) InlinedFinallyNode(try_end_pos,
6091 finally_clause,
6092 context_var,
6093 // No outer try statement
6094 CatchClauseNode::kInvalidTryIndex);
6095 finally_clause = NULL;
6096 AddFinallyBlockToNode(node_to_inline, node);
6097 node_index++;
6098 }
6099 } while (finally_clause == NULL);
6100
6101 const GrowableObjectArray& handler_types =
6102 GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
6103 handler_types.Add(dynamic_type); // Catch block handles all exceptions.
6104
6105 CatchClauseNode* catch_clause = new(Z) CatchClauseNode(
6106 Scanner::kNoSourcePos,
6107 catch_handler_list,
6108 Array::ZoneHandle(Z, Array::MakeArray(handler_types)),
6109 context_var,
6110 exception_var,
6111 stack_trace_var,
6112 AllocateTryIndex(),
6113 true);
6114
6115 const intptr_t try_index = try_block->try_index();
6116
6117 AstNode* try_catch_node =
6118 new(Z) TryCatchNode(Scanner::kNoSourcePos,
6119 body,
6120 context_var,
6121 catch_clause,
6122 finally_clause,
6123 try_index);
6124 current_block_->statements->Add(try_catch_node);
6125 return CloseBlock();
6126 }
6127
6128
6129 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) {
6130 // This is the outermost try-catch of the function.
5996 ASSERT(try_blocks_list_ != NULL); 6131 ASSERT(try_blocks_list_ != NULL);
5997 ASSERT(innermost_function().IsAsyncClosure() || 6132 ASSERT(try_blocks_list_->outer_try_block() == NULL);
5998 innermost_function().IsAsyncFunction()); 6133 ASSERT(innermost_function().IsAsyncClosure());
5999 const TryBlocks* outer_try_block = try_blocks_list_->outer_try_block(); 6134
6000 if (outer_try_block != NULL) { 6135 try_blocks_list_->enter_catch();
6001 LocalScope* scope = outer_try_block->try_block()->scope; 6136
6002 if (scope->function_level() == current_block_->scope->function_level()) { 6137 OpenBlock(); // Catch handler list.
6003 current_block_->statements->Add( 6138 OpenBlock(); // Catch block.
6004 AwaitTransformer::RestoreSavedTryContext( 6139 const AbstractType& dynamic_type =
6005 Z, scope->parent(), outer_try_block->try_index())); 6140 AbstractType::ZoneHandle(Z, Type::DynamicType());
6006 } 6141 CatchParamDesc exception_param;
6142 CatchParamDesc stack_trace_param;
6143 exception_param.token_pos = Scanner::kNoSourcePos;
6144 exception_param.type = &dynamic_type;
6145 exception_param.name = &Symbols::ExceptionParameter();
6146 stack_trace_param.token_pos = Scanner::kNoSourcePos;
6147 stack_trace_param.type = &dynamic_type;
6148 stack_trace_param.name = &Symbols::StackTraceParameter();
6149
6150 AddCatchParamsToScope(
6151 &exception_param, &stack_trace_param, current_block_->scope);
6152
6153 LocalVariable* context_var = current_block_->scope->LookupVariable(
6154 Symbols::SavedTryContextVar(), false);
6155 ASSERT(context_var != NULL);
6156
6157 LocalVariable* exception_var = current_block_->scope->LookupVariable(
6158 Symbols::ExceptionVar(), false);
6159 if (exception_param.var != NULL) {
6160 // Generate code to load the exception object (:exception_var) into
6161 // the exception variable specified in this block.
6162 ASSERT(exception_var != NULL);
6163 current_block_->statements->Add(new(Z) StoreLocalNode(
6164 Scanner::kNoSourcePos,
6165 exception_param.var,
6166 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var)));
6007 } 6167 }
6008 6168
6009 // Complete the async future with an error. 6169 LocalVariable* stack_trace_var =
6010 // Since we control the catch block there is no need to generate a nested 6170 current_block_->scope->LookupVariable(Symbols::StackTraceVar(), false);
6011 // if/then/else. 6171 if (stack_trace_param.var != NULL) {
6172 // A stack trace variable is specified in this block, so generate code
6173 // to load the stack trace object (:stack_trace_var) into the stack
6174 // trace variable specified in this block.
6175 ASSERT(stack_trace_var != NULL);
6176 current_block_->statements->Add(new(Z) StoreLocalNode(
6177 Scanner::kNoSourcePos,
6178 stack_trace_param.var,
6179 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
6180 }
6181
6182 SaveExceptionAndStacktrace(exception_var, stack_trace_var);
6183
6184 // Complete the async future with an error. This catch block executes
6185 // unconditionally, there is no need to generate a type check for.
6012 LocalVariable* async_completer = current_block_->scope->LookupVariable( 6186 LocalVariable* async_completer = current_block_->scope->LookupVariable(
6013 Symbols::AsyncCompleter(), false); 6187 Symbols::AsyncCompleter(), false);
6014 ASSERT(async_completer != NULL); 6188 ASSERT(async_completer != NULL);
6015 ArgumentListNode* completer_args = 6189 ArgumentListNode* completer_args =
6016 new (Z) ArgumentListNode(Scanner::kNoSourcePos); 6190 new (Z) ArgumentListNode(Scanner::kNoSourcePos);
6017 completer_args->Add( 6191 completer_args->Add(
6018 new (Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var)); 6192 new (Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var));
6019 completer_args->Add( 6193 completer_args->Add(
6020 new (Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var)); 6194 new (Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var));
6021 current_block_->statements->Add(new (Z) InstanceCallNode( 6195 current_block_->statements->Add(new (Z) InstanceCallNode(
(...skipping 24 matching lines...) Expand all
6046 context_var, 6220 context_var,
6047 exception_var, 6221 exception_var,
6048 stack_trace_var, 6222 stack_trace_var,
6049 CatchClauseNode::kInvalidTryIndex, 6223 CatchClauseNode::kInvalidTryIndex,
6050 true); 6224 true);
6051 AstNode* try_catch_node = new (Z) TryCatchNode( 6225 AstNode* try_catch_node = new (Z) TryCatchNode(
6052 Scanner::kNoSourcePos, 6226 Scanner::kNoSourcePos,
6053 try_block, 6227 try_block,
6054 context_var, 6228 context_var,
6055 catch_clause, 6229 catch_clause,
6056 NULL, 6230 NULL, // No finally clause.
6057 try_index); 6231 try_index);
6058 current_block_->statements->Add(try_catch_node); 6232 current_block_->statements->Add(try_catch_node);
6059 return CloseBlock(); 6233 return CloseBlock();
6060 } 6234 }
6061 6235
6062 6236
6237 // Wrap the body of the async or arync* closure in a try/catch block.
6063 void Parser::OpenAsyncTryBlock() { 6238 void Parser::OpenAsyncTryBlock() {
6064 // Manually wrapping the actual body into a try/catch block. 6239 ASSERT(innermost_function().IsAsyncClosure() ||
6240 innermost_function().IsAsyncGenClosure());
6241
6065 LocalVariable* context_var = 6242 LocalVariable* context_var =
6066 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); 6243 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar());
6067 if (context_var == NULL) { 6244 if (context_var == NULL) {
6068 context_var = new(Z) LocalVariable( 6245 context_var = new(Z) LocalVariable(
6069 TokenPos(), 6246 TokenPos(),
6070 Symbols::SavedTryContextVar(), 6247 Symbols::SavedTryContextVar(),
6071 Type::ZoneHandle(Z, Type::DynamicType())); 6248 Type::ZoneHandle(Z, Type::DynamicType()));
6072 current_block_->scope->AddVariable(context_var); 6249 current_block_->scope->AddVariable(context_var);
6073 } 6250 }
6074 LocalVariable* exception_var = 6251 LocalVariable* exception_var =
(...skipping 12 matching lines...) Expand all
6087 TokenPos(), 6264 TokenPos(),
6088 Symbols::StackTraceVar(), 6265 Symbols::StackTraceVar(),
6089 Type::ZoneHandle(Z, Type::DynamicType())); 6266 Type::ZoneHandle(Z, Type::DynamicType()));
6090 current_block_->scope->AddVariable(stack_trace_var); 6267 current_block_->scope->AddVariable(stack_trace_var);
6091 } 6268 }
6092 6269
6093 SetupSavedExceptionAndStacktrace(); 6270 SetupSavedExceptionAndStacktrace();
6094 6271
6095 // Open the try block. 6272 // Open the try block.
6096 OpenBlock(); 6273 OpenBlock();
6274 // This is the outermost try-catch in the function.
6275 ASSERT(try_blocks_list_ == NULL);
6097 PushTryBlock(current_block_); 6276 PushTryBlock(current_block_);
6098 6277
6099 SetupSavedTryContext(context_var); 6278 SetupSavedTryContext(context_var);
6100 } 6279 }
6101 6280
6102 6281
6103 void Parser::AddSyncGenClosureParameters(ParamList* params) { 6282 void Parser::AddSyncGenClosureParameters(ParamList* params) {
6104 // Create the parameter list for the body closure of a sync generator: 6283 // Create the parameter list for the body closure of a sync generator:
6105 // 1) Implicit closure parameter; 6284 // 1) Implicit closure parameter;
6106 // 2) Iterator 6285 // 2) Iterator
6107 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); 6286 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6108 // Add implicit closure parameter if not already present. 6287 // Add implicit closure parameter if not already present.
6109 if (params->parameters->length() == 0) { 6288 if (params->parameters->length() == 0) {
6110 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type); 6289 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type);
6111 } 6290 }
6112 ParamDesc iterator_param; 6291 ParamDesc iterator_param;
6113 iterator_param.name = &Symbols::IteratorParameter(); 6292 iterator_param.name = &Symbols::IteratorParameter();
6114 iterator_param.type = &dynamic_type; 6293 iterator_param.type = &dynamic_type;
6115 params->parameters->Add(iterator_param); 6294 params->parameters->Add(iterator_param);
6116 params->num_fixed_parameters++; 6295 params->num_fixed_parameters++;
6117 } 6296 }
6118 6297
6119 6298
6299 void Parser::AddAsyncGenClosureParameters(ParamList* params) {
6300 // Create the parameter list for the body closure of an async generator.
6301 // The closure has the same parameters as an asynchronous non-generator.
6302 AddAsyncClosureParameters(params);
6303 }
6304
6305
6120 RawFunction* Parser::OpenSyncGeneratorFunction(intptr_t func_pos) { 6306 RawFunction* Parser::OpenSyncGeneratorFunction(intptr_t func_pos) {
6121 Function& body = Function::Handle(Z); 6307 Function& body = Function::Handle(Z);
6122 String& body_closure_name = String::Handle(Z); 6308 String& body_closure_name = String::Handle(Z);
6123 bool is_new_closure = false; 6309 bool is_new_closure = false;
6124 6310
6125 AddContinuationVariables(); 6311 AddContinuationVariables();
6126 6312
6127 // Check whether a function for the body of this generator 6313 // Check whether a function for the body of this generator
6128 // function has already been created by a previous 6314 // function has already been created by a previous
6129 // compilation. 6315 // compilation.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
6220 iterable_constructor, 6406 iterable_constructor,
6221 arguments); 6407 arguments);
6222 ReturnNode* return_node = 6408 ReturnNode* return_node =
6223 new (Z) ReturnNode(Scanner::kNoSourcePos, new_iterable); 6409 new (Z) ReturnNode(Scanner::kNoSourcePos, new_iterable);
6224 current_block_->statements->Add(return_node); 6410 current_block_->statements->Add(return_node);
6225 return CloseBlock(); 6411 return CloseBlock();
6226 } 6412 }
6227 6413
6228 6414
6229 void Parser::AddAsyncClosureParameters(ParamList* params) { 6415 void Parser::AddAsyncClosureParameters(ParamList* params) {
6230 // Async closures have two optional parameters: 6416 // Async closures have three optional parameters:
6231 // * A continuation result. 6417 // * A continuation result.
6232 // * A continuation error. 6418 // * A continuation error.
6233 // * A continuation stack trace. 6419 // * A continuation stack trace.
6234 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); 6420 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6235 // Add implicit closure parameter if not yet present. 6421 // Add implicit closure parameter if not yet present.
6236 if (params->parameters->length() == 0) { 6422 if (params->parameters->length() == 0) {
Ivan Posva 2015/03/03 01:05:52 We should assert that params->parameters->length()
hausner 2015/03/03 17:51:28 Done.
6237 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type); 6423 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type);
6238 } 6424 }
6239 ParamDesc result_param; 6425 ParamDesc result_param;
6240 result_param.name = &Symbols::AsyncOperationParam(); 6426 result_param.name = &Symbols::AsyncOperationParam();
6241 result_param.default_value = &Object::null_instance(); 6427 result_param.default_value = &Object::null_instance();
6242 result_param.type = &dynamic_type; 6428 result_param.type = &dynamic_type;
6243 params->parameters->Add(result_param); 6429 params->parameters->Add(result_param);
6244 ParamDesc error_param; 6430 ParamDesc error_param;
6245 error_param.name = &Symbols::AsyncOperationErrorParam(); 6431 error_param.name = &Symbols::AsyncOperationErrorParam();
6246 error_param.default_value = &Object::null_instance(); 6432 error_param.default_value = &Object::null_instance();
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
6349 current_block_->scope->CaptureVariable(Symbols::AsyncOperation()); 6535 current_block_->scope->CaptureVariable(Symbols::AsyncOperation());
6350 async_op_var->set_is_captured(); 6536 async_op_var->set_is_captured();
6351 LocalVariable* async_completer = new(Z) LocalVariable( 6537 LocalVariable* async_completer = new(Z) LocalVariable(
6352 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type); 6538 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type);
6353 current_block_->scope->AddVariable(async_completer); 6539 current_block_->scope->AddVariable(async_completer);
6354 current_block_->scope->CaptureVariable(Symbols::AsyncCompleter()); 6540 current_block_->scope->CaptureVariable(Symbols::AsyncCompleter());
6355 async_completer->set_is_captured(); 6541 async_completer->set_is_captured();
6356 } 6542 }
6357 6543
6358 6544
6545 void Parser::AddAsyncGeneratorVariables() {
6546 // Add to current block's scope:
6547 // var :controller;
Ivan Posva 2015/03/03 01:05:52 // var :async_op;?
hausner 2015/03/03 17:51:28 Done.
6548 // This variable is used by the nested async generator closure to
6549 // store the StreamController object to which the yielded expressions
6550 // are added.
6551 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6552 LocalVariable* controller_var = new(Z) LocalVariable(
6553 Scanner::kNoSourcePos, Symbols::Controller(), dynamic_type);
6554 current_block_->scope->AddVariable(controller_var);
6555 current_block_->scope->CaptureVariable(Symbols::Controller());
6556 controller_var->set_is_captured();
6557
6558 LocalVariable* async_op_var = new(Z) LocalVariable(
6559 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
6560 current_block_->scope->AddVariable(async_op_var);
6561 current_block_->scope->CaptureVariable(Symbols::AsyncOperation());
6562 async_op_var->set_is_captured();
6563 }
6564
6565
6566 RawFunction* Parser::OpenAsyncGeneratorFunction(intptr_t async_func_pos) {
6567 TRACE_PARSER("OpenAsyncGeneratorFunction");
6568 AddContinuationVariables();
6569 AddAsyncGeneratorVariables();
6570
6571 Function& closure = Function::Handle(Z);
6572 bool is_new_closure = false;
6573
6574 // Check whether a function for the asynchronous function body of
6575 // this async generator has already been created by a previous
6576 // compilation of this function.
6577 const Function& found_func = Function::Handle(
6578 Z, current_class().LookupClosureFunction(async_func_pos));
6579 if (!found_func.IsNull() &&
6580 (found_func.token_pos() == async_func_pos) &&
6581 (found_func.script() == innermost_function().script()) &&
6582 (found_func.parent_function() == innermost_function().raw())) {
6583 ASSERT(found_func.IsAsyncGenClosure());
6584 closure = found_func.raw();
6585 } else {
6586 // Create the closure containing the body of this async generator function.
6587 const String& async_generator_name =
6588 String::Handle(Z, innermost_function().name());
6589 String& closure_name = String::Handle(Z,
6590 String::NewFormatted("<%s_async_gen_body>",
6591 async_generator_name.ToCString()));
6592 closure = Function::NewClosureFunction(
6593 String::Handle(Z, Symbols::New(closure_name)),
6594 innermost_function(),
6595 async_func_pos);
6596 closure.set_is_generated_body(true);
6597 closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
6598 is_new_closure = true;
6599 }
6600
6601 ParamList closure_params;
6602 AddAsyncGenClosureParameters(&closure_params);
6603
6604 if (is_new_closure) {
6605 // Add the parameters to the newly created closure.
6606 AddFormalParamsToFunction(&closure_params, closure);
6607
6608 // Create and set the signature class of the closure.
6609 const String& sig = String::Handle(Z, closure.Signature());
6610 Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig));
6611 if (sig_cls.IsNull()) {
6612 sig_cls =
6613 Class::NewSignatureClass(sig, closure, script_, closure.token_pos());
6614 library_.AddClass(sig_cls);
6615 }
6616 closure.set_signature_class(sig_cls);
6617 const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType());
6618 if (!sig_type.IsFinalized()) {
6619 ClassFinalizer::FinalizeType(
6620 sig_cls, sig_type, ClassFinalizer::kCanonicalize);
6621 }
6622 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved());
6623 ASSERT(closure.NumParameters() == closure_params.parameters->length());
6624 }
6625
6626 OpenFunctionBlock(closure);
6627 AddFormalParamsToScope(&closure_params, current_block_->scope);
6628 OpenBlock();
6629 async_temp_scope_ = current_block_->scope;
6630 return closure.raw();
6631 }
6632
6633
6634 // Generate the Ast nodes for the implicit code of the async* function.
6635 //
6636 // f(...) async* {
6637 // var :controller;
6638 // var :await_jump_var = -1;
6639 // var :await_context_var;
Ivan Posva 2015/03/03 01:05:52 // var :async_op;
hausner 2015/03/03 17:51:28 Done.
6640 // f_async_body() {
6641 // ... source code of f ...
6642 // }
6643 // :controller = new _AsyncStarStreamController(f_async_body);
6644 // return :controller.stream;
6645 // }
6646 SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure,
6647 SequenceNode* closure_body) {
6648 TRACE_PARSER("CloseAsyncGeneratorFunction");
6649 ASSERT(!closure.IsNull());
6650 ASSERT(closure_body != NULL);
6651
6652 // The block for the async closure body has already been closed. Close the
6653 // corresponding function block.
6654 CloseBlock();
6655
6656 // Make sure the implicit variables of the async generator function
6657 // are captured.
6658 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
6659 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
6660 closure_body->scope()->LookupVariable(Symbols::Controller(), false);
Ivan Posva 2015/03/03 01:05:52 Force capture :async_op?
hausner 2015/03/03 17:51:28 Done.
6661
6662 const Class& controller_class = Class::Handle(Z,
6663 Library::LookupCoreClass(Symbols::_AsyncStarStreamController()));
6664 ASSERT(!controller_class.IsNull());
6665 const Function& controller_constructor = Function::ZoneHandle(Z,
6666 controller_class.LookupConstructorAllowPrivate(
6667 Symbols::_AsyncStarStreamControllerConstructor()));
6668
6669 // :await_jump_var = -1;
6670 LocalVariable* jump_var =
6671 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false);
6672 LiteralNode* init_value =
6673 new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1)));
6674 current_block_->statements->Add(
6675 new(Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value));
6676
6677 // Add to AST:
6678 // :async_op = <closure>; (containing the original body)
6679 LocalVariable* async_op_var =
6680 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false);
6681 ClosureNode* cn = new(Z) ClosureNode(
6682 Scanner::kNoSourcePos, closure, NULL, closure_body->scope());
6683 StoreLocalNode* store_async_op = new (Z) StoreLocalNode(
6684 Scanner::kNoSourcePos,
6685 async_op_var,
6686 cn);
6687 current_block_->statements->Add(store_async_op);
6688
6689 // :controller = new _AsyncStarStreamController(body_closure);
6690 ArgumentListNode* arguments = new(Z) ArgumentListNode(Scanner::kNoSourcePos);
6691 ClosureNode* closure_obj = new(Z) ClosureNode(
6692 Scanner::kNoSourcePos, closure, NULL, closure_body->scope());
6693 arguments->Add(closure_obj);
6694 ConstructorCallNode* controller_constructor_call =
6695 new(Z) ConstructorCallNode(Scanner::kNoSourcePos,
6696 TypeArguments::ZoneHandle(Z),
6697 controller_constructor,
6698 arguments);
6699 LocalVariable* controller_var =
6700 current_block_->scope->LookupVariable(Symbols::Controller(), false);
6701 StoreLocalNode* store_controller =
6702 new(Z) StoreLocalNode(Scanner::kNoSourcePos,
6703 controller_var,
6704 controller_constructor_call);
6705 current_block_->statements->Add(store_controller);
6706
6707 // return :controller.stream;
6708 ReturnNode* return_node = new(Z) ReturnNode(Scanner::kNoSourcePos,
6709 new(Z) InstanceGetterNode(Scanner::kNoSourcePos,
6710 new(Z) LoadLocalNode(Scanner::kNoSourcePos,
6711 controller_var),
6712 Symbols::Stream()));
6713 current_block_->statements->Add(return_node);
6714 return CloseBlock();
6715 }
6716
6717
6718 void Parser::OpenAsyncGeneratorClosure() {
6719 async_temp_scope_ = current_block_->scope;
6720 OpenAsyncTryBlock();
6721 }
6722
6723
6724 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) {
6725 // TODO(hausner): Is the temporary expression necessary?
Ivan Posva 2015/03/03 01:05:52 Remove TODO
hausner 2015/03/03 17:51:28 Done.
6726 // We need a temporary expression to store intermediate return values.
6727 parsed_function()->EnsureExpressionTemp();
6728
6729 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body);
6730 ASSERT(new_body != NULL);
6731 ASSERT(new_body->scope() != NULL);
6732
6733 // Implicitly mark those variables below as captured. We currently mark all
6734 // variables of all scopes as captured, but as soon as we do something
6735 // smarter we rely on these internal variables to be available.
6736 new_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
6737 new_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
6738 new_body->scope()->LookupVariable(Symbols::Controller(), false);
6739 new_body->scope()->LookupVariable(Symbols::AsyncOperationParam(), false);
6740 new_body->scope()->LookupVariable(Symbols::AsyncOperationErrorParam(), false);
6741 new_body->scope()->LookupVariable(
6742 Symbols::AsyncOperationStackTraceParam(), false);
6743 new_body->scope()->RecursivelyCaptureAllVariables();
6744 return new_body;
6745 }
6746
6747
6359 SequenceNode* Parser::CloseBlock() { 6748 SequenceNode* Parser::CloseBlock() {
6360 SequenceNode* statements = current_block_->statements; 6749 SequenceNode* statements = current_block_->statements;
6361 if (current_block_->scope != NULL) { 6750 if (current_block_->scope != NULL) {
6362 // Record the begin and end token index of the scope. 6751 // Record the begin and end token index of the scope.
6363 ASSERT(statements != NULL); 6752 ASSERT(statements != NULL);
6364 current_block_->scope->set_begin_token_pos(statements->token_pos()); 6753 current_block_->scope->set_begin_token_pos(statements->token_pos());
6365 current_block_->scope->set_end_token_pos(TokenPos()); 6754 current_block_->scope->set_end_token_pos(TokenPos());
6366 } 6755 }
6367 current_block_ = current_block_->parent; 6756 current_block_ = current_block_->parent;
6368 return statements; 6757 return statements;
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after
7794 *outer_try_index = try_blocks_list_->outer_try_block()->try_index(); 8183 *outer_try_index = try_blocks_list_->outer_try_block()->try_index();
7795 } 8184 }
7796 } 8185 }
7797 } 8186 }
7798 } 8187 }
7799 // An async or async* has an implicitly created try-catch around the 8188 // An async or async* has an implicitly created try-catch around the
7800 // function body, so the await or yield inside the async closure should always 8189 // function body, so the await or yield inside the async closure should always
7801 // be created with a try scope. 8190 // be created with a try scope.
7802 ASSERT((*try_scope != NULL) || 8191 ASSERT((*try_scope != NULL) ||
7803 innermost_function().IsAsyncFunction() || 8192 innermost_function().IsAsyncFunction() ||
8193 innermost_function().IsAsyncGenerator() ||
7804 innermost_function().IsSyncGenClosure() || 8194 innermost_function().IsSyncGenClosure() ||
7805 innermost_function().IsSyncGenerator()); 8195 innermost_function().IsSyncGenerator());
7806 } 8196 }
7807 8197
7808 8198
7809 AstNode* Parser::ParseAwaitForStatement(String* label_name) { 8199 AstNode* Parser::ParseAwaitForStatement(String* label_name) {
7810 TRACE_PARSER("ParseAwaitForStatement"); 8200 TRACE_PARSER("ParseAwaitForStatement");
7811 ASSERT(IsAwaitKeyword()); 8201 ASSERT(IsAwaitKeyword());
7812 const intptr_t await_for_pos = TokenPos(); 8202 const intptr_t await_for_pos = TokenPos();
7813 ConsumeToken(); // await. 8203 ConsumeToken(); // await.
7814 ASSERT(CurrentToken() == Token::kFOR); 8204 ASSERT(CurrentToken() == Token::kFOR);
7815 ConsumeToken(); // for. 8205 ConsumeToken(); // for.
7816 ExpectToken(Token::kLPAREN); 8206 ExpectToken(Token::kLPAREN);
7817 8207
7818 if (!innermost_function().IsAsyncFunction() && 8208 if (!innermost_function().IsAsyncFunction() &&
7819 !innermost_function().IsAsyncClosure()) { 8209 !innermost_function().IsAsyncClosure() &&
8210 !innermost_function().IsAsyncGenerator() &&
8211 !innermost_function().IsAsyncGenClosure()) {
7820 ReportError(await_for_pos, 8212 ReportError(await_for_pos,
7821 "await for loop is only allowed in async function"); 8213 "await for loop is only allowed in an asynchronous function");
7822 } 8214 }
7823 8215
7824 // Parse loop variable. 8216 // Parse loop variable.
7825 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); 8217 bool loop_var_is_final = (CurrentToken() == Token::kFINAL);
7826 if (CurrentToken() == Token::kCONST) { 8218 if (CurrentToken() == Token::kCONST) {
7827 ReportError("Loop variable cannot be 'const'"); 8219 ReportError("Loop variable cannot be 'const'");
7828 } 8220 }
7829 bool new_loop_var = false; 8221 bool new_loop_var = false;
7830 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); 8222 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z);
7831 if (LookaheadToken(1) != Token::kIN) { 8223 if (LookaheadToken(1) != Token::kIN) {
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
8256 } 8648 }
8257 } 8649 }
8258 8650
8259 8651
8260 // Populate current scope of the try block with the saved exception and saved 8652 // Populate current scope of the try block with the saved exception and saved
8261 // stack trace. 8653 // stack trace.
8262 void Parser::SetupSavedExceptionAndStacktrace() { 8654 void Parser::SetupSavedExceptionAndStacktrace() {
8263 ASSERT(innermost_function().IsAsyncClosure() || 8655 ASSERT(innermost_function().IsAsyncClosure() ||
8264 innermost_function().IsAsyncFunction() || 8656 innermost_function().IsAsyncFunction() ||
8265 innermost_function().IsSyncGenClosure() || 8657 innermost_function().IsSyncGenClosure() ||
8266 innermost_function().IsSyncGenerator()); 8658 innermost_function().IsSyncGenerator() ||
8659 innermost_function().IsAsyncGenerator() ||
8660 innermost_function().IsAsyncGenClosure());
8267 // Add :saved_exception_var and :saved_stack_trace_var to current scope. 8661 // Add :saved_exception_var and :saved_stack_trace_var to current scope.
8268 // They will automatically get captured. 8662 // They will automatically get captured.
8269 // Parallel try statements share the same set of variables. 8663 // Parallel try statements share the same set of variables.
8270 LocalVariable* saved_exception_var = 8664 LocalVariable* saved_exception_var =
8271 current_block_->scope->LocalLookupVariable(Symbols::SavedExceptionVar()); 8665 current_block_->scope->LocalLookupVariable(Symbols::SavedExceptionVar());
8272 if (saved_exception_var == NULL) { 8666 if (saved_exception_var == NULL) {
8273 saved_exception_var = new (Z) LocalVariable( 8667 saved_exception_var = new (Z) LocalVariable(
8274 Scanner::kNoSourcePos, 8668 Scanner::kNoSourcePos,
8275 Symbols::SavedExceptionVar(), 8669 Symbols::SavedExceptionVar(),
8276 Type::ZoneHandle(Z, Type::DynamicType())); 8670 Type::ZoneHandle(Z, Type::DynamicType()));
(...skipping 13 matching lines...) Expand all
8290 } 8684 }
8291 8685
8292 8686
8293 // Generate code to load the exception object (:exception_var) into 8687 // Generate code to load the exception object (:exception_var) into
8294 // the saved exception variable (:saved_exception_var) used to rethrow. 8688 // the saved exception variable (:saved_exception_var) used to rethrow.
8295 void Parser::SaveExceptionAndStacktrace(LocalVariable* exception_var, 8689 void Parser::SaveExceptionAndStacktrace(LocalVariable* exception_var,
8296 LocalVariable* stack_trace_var) { 8690 LocalVariable* stack_trace_var) {
8297 ASSERT(innermost_function().IsAsyncClosure() || 8691 ASSERT(innermost_function().IsAsyncClosure() ||
8298 innermost_function().IsAsyncFunction() || 8692 innermost_function().IsAsyncFunction() ||
8299 innermost_function().IsSyncGenClosure() || 8693 innermost_function().IsSyncGenClosure() ||
8300 innermost_function().IsSyncGenerator()); 8694 innermost_function().IsSyncGenerator() ||
8695 innermost_function().IsAsyncGenClosure() ||
8696 innermost_function().IsAsyncGenerator());
8301 LocalVariable* saved_exception_var = current_block_->scope->LookupVariable( 8697 LocalVariable* saved_exception_var = current_block_->scope->LookupVariable(
8302 Symbols::SavedExceptionVar(), false); 8698 Symbols::SavedExceptionVar(), false);
8303 ASSERT(saved_exception_var != NULL); 8699 ASSERT(saved_exception_var != NULL);
8304 ASSERT(exception_var != NULL); 8700 ASSERT(exception_var != NULL);
8305 current_block_->statements->Add(new(Z) StoreLocalNode( 8701 current_block_->statements->Add(new(Z) StoreLocalNode(
8306 Scanner::kNoSourcePos, 8702 Scanner::kNoSourcePos,
8307 saved_exception_var, 8703 saved_exception_var,
8308 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); 8704 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var)));
8309 8705
8310 // Generate code to load the stack trace object (:stack_trace_var) into 8706 // Generate code to load the stack trace object (:stack_trace_var) into
(...skipping 13 matching lines...) Expand all
8324 TRACE_PARSER("ParseFinallyBlock"); 8720 TRACE_PARSER("ParseFinallyBlock");
8325 OpenBlock(); 8721 OpenBlock();
8326 ExpectToken(Token::kLBRACE); 8722 ExpectToken(Token::kLBRACE);
8327 8723
8328 // In case of async closures we need to restore the saved try index of an 8724 // In case of async closures we need to restore the saved try index of an
8329 // outer try block (if it exists). The current try block has already been 8725 // outer try block (if it exists). The current try block has already been
8330 // removed from the stack of try blocks. 8726 // removed from the stack of try blocks.
8331 if ((innermost_function().IsAsyncClosure() || 8727 if ((innermost_function().IsAsyncClosure() ||
8332 innermost_function().IsAsyncFunction() || 8728 innermost_function().IsAsyncFunction() ||
8333 innermost_function().IsSyncGenClosure() || 8729 innermost_function().IsSyncGenClosure() ||
8334 innermost_function().IsSyncGenerator()) && 8730 innermost_function().IsSyncGenerator() ||
8731 innermost_function().IsAsyncGenerator() ||
8732 innermost_function().IsAsyncGenClosure()) &&
8335 (try_blocks_list_ != NULL)) { 8733 (try_blocks_list_ != NULL)) {
8336 LocalScope* scope = try_blocks_list_->try_block()->scope; 8734 LocalScope* scope = try_blocks_list_->try_block()->scope;
8337 if (scope->function_level() == current_block_->scope->function_level()) { 8735 if (scope->function_level() == current_block_->scope->function_level()) {
8338 current_block_->statements->Add( 8736 current_block_->statements->Add(
8339 AwaitTransformer::RestoreSavedTryContext( 8737 AwaitTransformer::RestoreSavedTryContext(
8340 Z, scope->parent(), try_blocks_list_->try_index())); 8738 Z, scope->parent(), try_blocks_list_->try_index()));
8341 } 8739 }
8342 } 8740 }
8343 8741
8344 ParseStatementSequence(); 8742 ParseStatementSequence();
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
8433 } else { 8831 } else {
8434 exception_param.type = &AbstractType::ZoneHandle(Z, Type::DynamicType()); 8832 exception_param.type = &AbstractType::ZoneHandle(Z, Type::DynamicType());
8435 } 8833 }
8436 if (CurrentToken() == Token::kCATCH) { 8834 if (CurrentToken() == Token::kCATCH) {
8437 ConsumeToken(); // Consume the 'catch'. 8835 ConsumeToken(); // Consume the 'catch'.
8438 ExpectToken(Token::kLPAREN); 8836 ExpectToken(Token::kLPAREN);
8439 exception_param.token_pos = TokenPos(); 8837 exception_param.token_pos = TokenPos();
8440 exception_param.name = ExpectIdentifier("identifier expected"); 8838 exception_param.name = ExpectIdentifier("identifier expected");
8441 if (CurrentToken() == Token::kCOMMA) { 8839 if (CurrentToken() == Token::kCOMMA) {
8442 ConsumeToken(); 8840 ConsumeToken();
8443 // TODO(hausner): Make implicit type be StackTrace, not dynamic.
8444 stack_trace_param.type = 8841 stack_trace_param.type =
8445 &AbstractType::ZoneHandle(Z, Type::DynamicType()); 8842 &AbstractType::ZoneHandle(Z, Type::DynamicType());
8446 stack_trace_param.token_pos = TokenPos(); 8843 stack_trace_param.token_pos = TokenPos();
8447 stack_trace_param.name = ExpectIdentifier("identifier expected"); 8844 stack_trace_param.name = ExpectIdentifier("identifier expected");
8448 } 8845 }
8449 ExpectToken(Token::kRPAREN); 8846 ExpectToken(Token::kRPAREN);
8450 } 8847 }
8451 8848
8452 // Create a block containing the catch clause parameters and the 8849 // Create a block containing the catch clause parameters and the
8453 // following code: 8850 // following code:
(...skipping 18 matching lines...) Expand all
8472 // A stack trace variable is specified in this block, so generate code 8869 // A stack trace variable is specified in this block, so generate code
8473 // to load the stack trace object (:stack_trace_var) into the stack 8870 // to load the stack trace object (:stack_trace_var) into the stack
8474 // trace variable specified in this block. 8871 // trace variable specified in this block.
8475 *needs_stack_trace = true; 8872 *needs_stack_trace = true;
8476 ASSERT(stack_trace_var != NULL); 8873 ASSERT(stack_trace_var != NULL);
8477 current_block_->statements->Add(new(Z) StoreLocalNode( 8874 current_block_->statements->Add(new(Z) StoreLocalNode(
8478 catch_pos, stack_trace_param.var, new(Z) LoadLocalNode( 8875 catch_pos, stack_trace_param.var, new(Z) LoadLocalNode(
8479 catch_pos, stack_trace_var))); 8876 catch_pos, stack_trace_var)));
8480 } 8877 }
8481 8878
8482 // Add nested block with user-defined code. This blocks allows 8879 // Add nested block with user-defined code. This block allows
8483 // declarations in the body to shadow the catch parameters. 8880 // declarations in the body to shadow the catch parameters.
8484 CheckToken(Token::kLBRACE); 8881 CheckToken(Token::kLBRACE);
8485 8882
8486 // In case of async closures we need to restore the saved try index of an 8883 // In case of async closures we need to restore the saved try index of an
8487 // outer try block (if it exists). 8884 // outer try block (if it exists).
8488 ASSERT(try_blocks_list_ != NULL); 8885 ASSERT(try_blocks_list_ != NULL);
8489 if (innermost_function().IsAsyncClosure() || 8886 if (innermost_function().IsAsyncClosure() ||
8490 innermost_function().IsAsyncFunction() || 8887 innermost_function().IsAsyncFunction() ||
8491 innermost_function().IsSyncGenClosure() || 8888 innermost_function().IsSyncGenClosure() ||
8492 innermost_function().IsSyncGenerator()) { 8889 innermost_function().IsSyncGenerator() ||
8890 innermost_function().IsAsyncGenerator() ||
8891 innermost_function().IsAsyncGenClosure()) {
8493 const TryBlocks* try_block = try_blocks_list_->outer_try_block(); 8892 const TryBlocks* try_block = try_blocks_list_->outer_try_block();
8494 if (try_block != NULL) { 8893 if (try_block != NULL) {
8495 LocalScope* scope = try_block->try_block()->scope; 8894 LocalScope* scope = try_block->try_block()->scope;
8496 if (scope->function_level() == 8895 if (scope->function_level() ==
8497 current_block_->scope->function_level()) { 8896 current_block_->scope->function_level()) {
8498 current_block_->statements->Add( 8897 current_block_->statements->Add(
8499 AwaitTransformer::RestoreSavedTryContext( 8898 AwaitTransformer::RestoreSavedTryContext(
8500 Z, scope->parent(), try_block->try_index())); 8899 Z, scope->parent(), try_block->try_index()));
8501 } 8900 }
8502 } 8901 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
8595 current_block_->statements->Add(new(Z) IfNode( 8994 current_block_->statements->Add(new(Z) IfNode(
8596 type_test->token_pos(), type_test, catch_block, current)); 8995 type_test->token_pos(), type_test, catch_block, current));
8597 current = CloseBlock(); 8996 current = CloseBlock();
8598 } 8997 }
8599 // Restore :saved_try_context_var before executing the catch clauses. 8998 // Restore :saved_try_context_var before executing the catch clauses.
8600 if (current != NULL) { 8999 if (current != NULL) {
8601 ASSERT(try_blocks_list_ != NULL); 9000 ASSERT(try_blocks_list_ != NULL);
8602 if (innermost_function().IsAsyncClosure() || 9001 if (innermost_function().IsAsyncClosure() ||
8603 innermost_function().IsAsyncFunction() || 9002 innermost_function().IsAsyncFunction() ||
8604 innermost_function().IsSyncGenClosure() || 9003 innermost_function().IsSyncGenClosure() ||
8605 innermost_function().IsSyncGenerator()) { 9004 innermost_function().IsSyncGenerator() ||
9005 innermost_function().IsAsyncGenerator() ||
9006 innermost_function().IsAsyncGenClosure()) {
8606 const TryBlocks* try_block = try_blocks_list_->outer_try_block(); 9007 const TryBlocks* try_block = try_blocks_list_->outer_try_block();
8607 if (try_block != NULL) { 9008 if (try_block != NULL) {
8608 LocalScope* scope = try_block->try_block()->scope; 9009 LocalScope* scope = try_block->try_block()->scope;
8609 if (scope->function_level() == 9010 if (scope->function_level() ==
8610 current_block_->scope->function_level()) { 9011 current_block_->scope->function_level()) {
8611 SequenceNode* restore_code = new(Z) SequenceNode(handler_pos, NULL); 9012 SequenceNode* restore_code = new(Z) SequenceNode(handler_pos, NULL);
8612 restore_code->Add( 9013 restore_code->Add(
8613 AwaitTransformer::RestoreSavedTryContext( 9014 AwaitTransformer::RestoreSavedTryContext(
8614 Z, scope->parent(), try_block->try_index())); 9015 Z, scope->parent(), try_block->try_index()));
8615 restore_code->Add(current); 9016 restore_code->Add(current);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
8687 stack_trace_var = new(Z) LocalVariable( 9088 stack_trace_var = new(Z) LocalVariable(
8688 TokenPos(), 9089 TokenPos(),
8689 Symbols::StackTraceVar(), 9090 Symbols::StackTraceVar(),
8690 Type::ZoneHandle(Z, Type::DynamicType())); 9091 Type::ZoneHandle(Z, Type::DynamicType()));
8691 current_block_->scope->AddVariable(stack_trace_var); 9092 current_block_->scope->AddVariable(stack_trace_var);
8692 } 9093 }
8693 9094
8694 if (innermost_function().IsAsyncClosure() || 9095 if (innermost_function().IsAsyncClosure() ||
8695 innermost_function().IsAsyncFunction() || 9096 innermost_function().IsAsyncFunction() ||
8696 innermost_function().IsSyncGenClosure() || 9097 innermost_function().IsSyncGenClosure() ||
8697 innermost_function().IsSyncGenerator()) { 9098 innermost_function().IsSyncGenerator() ||
9099 innermost_function().IsAsyncGenClosure() ||
9100 innermost_function().IsAsyncGenerator()) {
8698 SetupSavedExceptionAndStacktrace(); 9101 SetupSavedExceptionAndStacktrace();
8699 } 9102 }
8700 9103
8701 const intptr_t try_pos = TokenPos(); 9104 const intptr_t try_pos = TokenPos();
8702 ConsumeToken(); // Consume the 'try'. 9105 ConsumeToken(); // Consume the 'try'.
8703 9106
8704 SourceLabel* try_label = NULL; 9107 SourceLabel* try_label = NULL;
8705 if (label_name != NULL) { 9108 if (label_name != NULL) {
8706 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); 9109 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement);
8707 OpenBlock(); 9110 OpenBlock();
8708 current_block_->scope->AddLabel(try_label); 9111 current_block_->scope->AddLabel(try_label);
8709 } 9112 }
8710 9113
8711 // Now parse the 'try' block. 9114 // Now parse the 'try' block.
8712 OpenBlock(); 9115 OpenBlock();
8713 PushTryBlock(current_block_); 9116 PushTryBlock(current_block_);
8714 ExpectToken(Token::kLBRACE); 9117 ExpectToken(Token::kLBRACE);
8715 9118
8716 if (innermost_function().IsAsyncClosure() || 9119 if (innermost_function().IsAsyncClosure() ||
8717 innermost_function().IsAsyncFunction() || 9120 innermost_function().IsAsyncFunction() ||
8718 innermost_function().IsSyncGenClosure() || 9121 innermost_function().IsSyncGenClosure() ||
8719 innermost_function().IsSyncGenerator()) { 9122 innermost_function().IsSyncGenerator() ||
9123 innermost_function().IsAsyncGenerator() ||
9124 innermost_function().IsAsyncGenClosure()) {
8720 SetupSavedTryContext(context_var); 9125 SetupSavedTryContext(context_var);
8721 } 9126 }
8722 9127
8723 ParseStatementSequence(); 9128 ParseStatementSequence();
8724 ExpectToken(Token::kRBRACE); 9129 ExpectToken(Token::kRBRACE);
8725 SequenceNode* try_block = CloseBlock(); 9130 SequenceNode* try_block = CloseBlock();
8726 9131
8727 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && 9132 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") &&
8728 (CurrentToken() != Token::kFINALLY)) { 9133 (CurrentToken() != Token::kFINALLY)) {
8729 ReportError("catch or finally clause expected"); 9134 ReportError("catch or finally clause expected");
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
8853 ReportError(jump_pos, "'break' to case clause label is illegal"); 9258 ReportError(jump_pos, "'break' to case clause label is illegal");
8854 } 9259 }
8855 if (target->FunctionLevel() != current_block_->scope->function_level()) { 9260 if (target->FunctionLevel() != current_block_->scope->function_level()) {
8856 ReportError(jump_pos, "'%s' target must be in same function context", 9261 ReportError(jump_pos, "'%s' target must be in same function context",
8857 Token::Str(jump_kind)); 9262 Token::Str(jump_kind));
8858 } 9263 }
8859 return new(Z) JumpNode(jump_pos, jump_kind, target); 9264 return new(Z) JumpNode(jump_pos, jump_kind, target);
8860 } 9265 }
8861 9266
8862 9267
9268 AstNode* Parser::ParseYieldStatement() {
9269 bool is_yield_each = false;
9270 const intptr_t yield_pos = TokenPos();
9271 ConsumeToken(); // yield reserved word.
9272 ASSERT(innermost_function().IsGenerator() ||
9273 innermost_function().IsSyncGenClosure() ||
9274 innermost_function().IsAsyncGenerator() ||
9275 innermost_function().IsAsyncGenClosure());
9276 if (CurrentToken() == Token::kMUL) {
9277 is_yield_each = true;
9278 ConsumeToken();
9279 }
9280 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
9281
9282 LetNode* yield = new(Z) LetNode(yield_pos);
9283 if (innermost_function().IsSyncGenerator() ||
9284 innermost_function().IsSyncGenClosure()) {
9285 // Yield statement in sync* function.
9286
9287 LocalVariable* iterator_param =
9288 LookupLocalScope(Symbols::IteratorParameter());
9289 ASSERT(iterator_param != NULL);
9290 // Generate :iterator.current = expr;
9291 AstNode* iterator =
9292 new(Z) LoadLocalNode(Scanner::kNoSourcePos, iterator_param);
9293 AstNode* store_current =
9294 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
9295 iterator,
9296 String::ZoneHandle(Symbols::Current().raw()),
9297 expr);
9298 yield->AddNode(store_current);
9299 if (is_yield_each) {
9300 // Generate :iterator.isYieldEach = true;
9301 AstNode* set_is_yield_each =
9302 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
9303 iterator,
9304 String::ZoneHandle(Symbols::IsYieldEach().raw()),
9305 new(Z) LiteralNode(TokenPos(), Bool::True()));
9306 yield->AddNode(set_is_yield_each);
9307 }
9308 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
9309 await_marker->set_scope(current_block_->scope);
9310 yield->AddNode(await_marker);
9311 // Return true to indicate that a value has been generated.
9312 ReturnNode* return_true = new(Z) ReturnNode(yield_pos,
9313 new(Z) LiteralNode(TokenPos(), Bool::True()));
9314 return_true->set_return_type(ReturnNode::kContinuationTarget);
9315 yield->AddNode(return_true);
9316
9317 // If this expression is part of a try block, also append the code for
9318 // restoring the saved try context that lives on the stack and possibly the
9319 // saved try context of the outer try block.
9320 LocalScope* try_scope;
9321 int16_t try_index;
9322 LocalScope* outer_try_scope;
9323 int16_t outer_try_index;
9324 CheckAsyncOpInTryBlock(&try_scope, &try_index,
9325 &outer_try_scope, &outer_try_index);
9326 if (try_scope != NULL) {
9327 yield->AddNode(
9328 AwaitTransformer::RestoreSavedTryContext(Z,
9329 try_scope,
9330 try_index));
9331 if (outer_try_scope != NULL) {
9332 yield->AddNode(
9333 AwaitTransformer::RestoreSavedTryContext(Z,
9334 outer_try_scope,
9335 outer_try_index));
9336 }
9337 } else {
9338 ASSERT(outer_try_scope == NULL);
9339 }
9340 } else {
9341 // yield statement in async* function.
9342 ASSERT(innermost_function().IsAsyncGenerator() ||
9343 innermost_function().IsAsyncGenClosure());
9344
9345 LocalVariable* controller_var = LookupLocalScope(Symbols::Controller());
9346 ASSERT(controller_var != NULL);
9347 // :controller.add[Stream](expr);
9348 ArgumentListNode* add_args = new(Z) ArgumentListNode(yield_pos);
9349 add_args->Add(expr);
9350 AstNode* add_call =
9351 new(Z) InstanceCallNode(yield_pos,
9352 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller_var),
9353 is_yield_each ? Symbols::AddStream() : Symbols::add(),
9354 add_args);
9355
9356
9357 // if (:controller.add[Stream](expr)) {
9358 // return;
9359 // }
9360 // await_marker;
9361 // continuation_return;
9362 // restore saved_try_context
9363
9364 SequenceNode* true_branch =
9365 new(Z) SequenceNode(Scanner::kNoSourcePos, current_block_->scope);
9366 AstNode* return_from_generator = new(Z) ReturnNode(yield_pos);
9367 true_branch->Add(return_from_generator);
9368 AddNodeForFinallyInlining(return_from_generator);
9369 AstNode* if_is_cancelled =
9370 new(Z) IfNode(Scanner::kNoSourcePos, add_call, true_branch, NULL);
9371 yield->AddNode(if_is_cancelled);
9372
9373 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
9374 await_marker->set_scope(current_block_->scope);
9375 yield->AddNode(await_marker);
9376 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos);
9377 continuation_return->set_return_type(ReturnNode::kContinuationTarget);
9378 yield->AddNode(continuation_return);
9379
9380 // If this expression is part of a try block, also append the code for
9381 // restoring the saved try context that lives on the stack and possibly the
9382 // saved try context of the outer try block.
9383 LocalScope* try_scope;
9384 int16_t try_index;
9385 LocalScope* outer_try_scope;
9386 int16_t outer_try_index;
9387 CheckAsyncOpInTryBlock(&try_scope, &try_index,
9388 &outer_try_scope, &outer_try_index);
9389 if (try_scope != NULL) {
9390 yield->AddNode(
9391 AwaitTransformer::RestoreSavedTryContext(Z,
9392 try_scope,
9393 try_index));
9394 if (outer_try_scope != NULL) {
9395 yield->AddNode(
9396 AwaitTransformer::RestoreSavedTryContext(Z,
9397 outer_try_scope,
9398 outer_try_index));
9399 }
9400 } else {
9401 ASSERT(outer_try_scope == NULL);
9402 }
9403 }
9404 return yield;
9405 }
9406
9407
8863 AstNode* Parser::ParseStatement() { 9408 AstNode* Parser::ParseStatement() {
8864 TRACE_PARSER("ParseStatement"); 9409 TRACE_PARSER("ParseStatement");
8865 AstNode* statement = NULL; 9410 AstNode* statement = NULL;
8866 intptr_t label_pos = 0; 9411 intptr_t label_pos = 0;
8867 String* label_name = NULL; 9412 String* label_name = NULL;
8868 if (IsIdentifier()) { 9413 if (IsIdentifier()) {
8869 if (LookaheadToken(1) == Token::kCOLON) { 9414 if (LookaheadToken(1) == Token::kCOLON) {
8870 // Statement starts with a label. 9415 // Statement starts with a label.
8871 label_name = CurrentLiteral(); 9416 label_name = CurrentLiteral();
8872 label_pos = TokenPos(); 9417 label_pos = TokenPos();
(...skipping 19 matching lines...) Expand all
8892 statement = ParseTryStatement(label_name); 9437 statement = ParseTryStatement(label_name);
8893 } else if (token == Token::kRETURN) { 9438 } else if (token == Token::kRETURN) {
8894 const intptr_t return_pos = TokenPos(); 9439 const intptr_t return_pos = TokenPos();
8895 ConsumeToken(); 9440 ConsumeToken();
8896 if (CurrentToken() != Token::kSEMICOLON) { 9441 if (CurrentToken() != Token::kSEMICOLON) {
8897 const intptr_t expr_pos = TokenPos(); 9442 const intptr_t expr_pos = TokenPos();
8898 if (current_function().IsGenerativeConstructor() && 9443 if (current_function().IsGenerativeConstructor() &&
8899 (current_block_->scope->function_level() == 0)) { 9444 (current_block_->scope->function_level() == 0)) {
8900 ReportError(expr_pos, 9445 ReportError(expr_pos,
8901 "return of a value is not allowed in constructors"); 9446 "return of a value is not allowed in constructors");
8902 } else if (current_function().IsGenerator()) { 9447 } else if (current_function().IsGeneratorClosure() &&
9448 (current_block_->scope->function_level() == 0)) {
8903 ReportError(expr_pos, "generator functions may not return a value"); 9449 ReportError(expr_pos, "generator functions may not return a value");
8904 } 9450 }
8905 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); 9451 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
8906 statement = new(Z) ReturnNode(statement_pos, expr); 9452 statement = new(Z) ReturnNode(statement_pos, expr);
8907 } else { 9453 } else {
8908 if (current_function().IsSyncGenClosure() && 9454 if (current_function().IsSyncGenClosure() &&
8909 (current_block_->scope->function_level() == 0)) { 9455 (current_block_->scope->function_level() == 0)) {
8910 // In a synchronous generator, return without an expression 9456 // In a synchronous generator, return without an expression
8911 // returns false, signaling that the iterator terminates and 9457 // returns false, signaling that the iterator terminates and
8912 // did not yield a value. 9458 // did not yield a value.
8913 statement = new(Z) ReturnNode(statement_pos, 9459 statement = new(Z) ReturnNode(statement_pos,
8914 new(Z) LiteralNode(return_pos, Bool::False())); 9460 new(Z) LiteralNode(return_pos, Bool::False()));
8915 } else { 9461 } else {
8916 statement = new(Z) ReturnNode(statement_pos); 9462 statement = new(Z) ReturnNode(statement_pos);
8917 } 9463 }
8918 } 9464 }
8919 AddNodeForFinallyInlining(statement); 9465 AddNodeForFinallyInlining(statement);
8920 ExpectSemicolon(); 9466 ExpectSemicolon();
8921 } else if (IsYieldKeyword()) { 9467 } else if (IsYieldKeyword()) {
8922 bool is_yield_each = false; 9468 statement = ParseYieldStatement();
8923 ConsumeToken();
8924 ASSERT(innermost_function().IsGenerator() ||
8925 innermost_function().IsSyncGenClosure());
8926 if (CurrentToken() == Token::kMUL) {
8927 is_yield_each = true;
8928 ConsumeToken();
8929 }
8930 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
8931 LocalVariable* iterator_param =
8932 LookupLocalScope(Symbols::IteratorParameter());
8933 ASSERT(iterator_param != NULL);
8934 // Generate :iterator.current = expr;
8935 AstNode* iterator =
8936 new(Z) LoadLocalNode(Scanner::kNoSourcePos, iterator_param);
8937 AstNode* store_current =
8938 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
8939 iterator,
8940 String::ZoneHandle(Symbols::Current().raw()),
8941 expr);
8942 LetNode* yield = new(Z) LetNode(statement_pos);
8943 yield->AddNode(store_current);
8944 if (is_yield_each) {
8945 // Generate :iterator.isYieldEach = true;
8946 AstNode* set_is_yield_each =
8947 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
8948 iterator,
8949 String::ZoneHandle(Symbols::IsYieldEach().raw()),
8950 new(Z) LiteralNode(TokenPos(), Bool::True()));
8951 yield->AddNode(set_is_yield_each);
8952 }
8953 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
8954 await_marker->set_scope(current_block_->scope);
8955 yield->AddNode(await_marker);
8956 // Return true to indicate that a value has been generated.
8957 ReturnNode* return_true = new(Z) ReturnNode(statement_pos,
8958 new(Z) LiteralNode(TokenPos(), Bool::True()));
8959 return_true->set_return_type(ReturnNode::kContinuationTarget);
8960 yield->AddNode(return_true);
8961
8962 // If this expression is part of a try block, also append the code for
8963 // restoring the saved try context that lives on the stack and possibly the
8964 // saved try context of the outer try block.
8965 LocalScope* try_scope;
8966 int16_t try_index;
8967 LocalScope* outer_try_scope;
8968 int16_t outer_try_index;
8969 CheckAsyncOpInTryBlock(&try_scope, &try_index,
8970 &outer_try_scope, &outer_try_index);
8971 if (try_scope != NULL) {
8972 yield->AddNode(
8973 AwaitTransformer::RestoreSavedTryContext(Z,
8974 try_scope,
8975 try_index));
8976 if (outer_try_scope != NULL) {
8977 yield->AddNode(
8978 AwaitTransformer::RestoreSavedTryContext(Z,
8979 outer_try_scope,
8980 outer_try_index));
8981 }
8982 } else {
8983 ASSERT(outer_try_scope == NULL);
8984 }
8985
8986 statement = yield;
8987 ExpectSemicolon(); 9469 ExpectSemicolon();
8988 } else if (token == Token::kIF) { 9470 } else if (token == Token::kIF) {
8989 statement = ParseIfStatement(label_name); 9471 statement = ParseIfStatement(label_name);
8990 } else if (token == Token::kASSERT) { 9472 } else if (token == Token::kASSERT) {
8991 statement = ParseAssertStatement(); 9473 statement = ParseAssertStatement();
8992 ExpectSemicolon(); 9474 ExpectSemicolon();
8993 } else if (IsVariableDeclaration()) { 9475 } else if (IsVariableDeclaration()) {
8994 statement = ParseVariableDeclarationList(); 9476 statement = ParseVariableDeclarationList();
8995 ExpectSemicolon(); 9477 ExpectSemicolon();
8996 } else if (IsFunctionDeclaration()) { 9478 } else if (IsFunctionDeclaration()) {
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after
9837 } 10319 }
9838 10320
9839 10321
9840 AstNode* Parser::ParseUnaryExpr() { 10322 AstNode* Parser::ParseUnaryExpr() {
9841 TRACE_PARSER("ParseUnaryExpr"); 10323 TRACE_PARSER("ParseUnaryExpr");
9842 AstNode* expr = NULL; 10324 AstNode* expr = NULL;
9843 const intptr_t op_pos = TokenPos(); 10325 const intptr_t op_pos = TokenPos();
9844 if (IsAwaitKeyword()) { 10326 if (IsAwaitKeyword()) {
9845 TRACE_PARSER("ParseAwaitExpr"); 10327 TRACE_PARSER("ParseAwaitExpr");
9846 if (!innermost_function().IsAsyncFunction() && 10328 if (!innermost_function().IsAsyncFunction() &&
9847 !innermost_function().IsAsyncClosure()) { 10329 !innermost_function().IsAsyncClosure() &&
9848 ReportError("await operator is only allowed in async function"); 10330 !innermost_function().IsAsyncGenerator() &&
10331 !innermost_function().IsAsyncGenClosure()) {
10332 ReportError("await operator is only allowed in an asynchronous function");
9849 } 10333 }
9850 ConsumeToken(); 10334 ConsumeToken();
9851 parsed_function()->record_await(); 10335 parsed_function()->record_await();
9852 10336
9853 LocalScope* try_scope; 10337 LocalScope* try_scope;
9854 int16_t try_index; 10338 int16_t try_index;
9855 LocalScope* outer_try_scope; 10339 LocalScope* outer_try_scope;
9856 int16_t outer_try_index; 10340 int16_t outer_try_index;
9857 CheckAsyncOpInTryBlock(&try_scope, &try_index, 10341 CheckAsyncOpInTryBlock(&try_scope, &try_index,
9858 &outer_try_scope, &outer_try_index); 10342 &outer_try_scope, &outer_try_index);
(...skipping 1810 matching lines...) Expand 10 before | Expand all | Expand 10 after
11669 // them here. 12153 // them here.
11670 // Map and List interfaces do not declare bounds on their type parameters, so 12154 // Map and List interfaces do not declare bounds on their type parameters, so
11671 // we will not see malbounded type arguments here. 12155 // we will not see malbounded type arguments here.
11672 AstNode* primary = NULL; 12156 AstNode* primary = NULL;
11673 if ((CurrentToken() == Token::kLBRACK) || 12157 if ((CurrentToken() == Token::kLBRACK) ||
11674 (CurrentToken() == Token::kINDEX)) { 12158 (CurrentToken() == Token::kINDEX)) {
11675 primary = ParseListLiteral(type_pos, is_const, type_arguments); 12159 primary = ParseListLiteral(type_pos, is_const, type_arguments);
11676 } else if (CurrentToken() == Token::kLBRACE) { 12160 } else if (CurrentToken() == Token::kLBRACE) {
11677 primary = ParseMapLiteral(type_pos, is_const, type_arguments); 12161 primary = ParseMapLiteral(type_pos, is_const, type_arguments);
11678 } else { 12162 } else {
11679 ReportError("unexpected token %s", Token::Str(CurrentToken())); 12163 UnexpectedToken();
11680 } 12164 }
11681 return primary; 12165 return primary;
11682 } 12166 }
11683 12167
11684 12168
11685 AstNode* Parser::ParseSymbolLiteral() { 12169 AstNode* Parser::ParseSymbolLiteral() {
11686 ASSERT(CurrentToken() == Token::kHASH); 12170 ASSERT(CurrentToken() == Token::kHASH);
11687 ConsumeToken(); 12171 ConsumeToken();
11688 intptr_t symbol_pos = TokenPos(); 12172 intptr_t symbol_pos = TokenPos();
11689 String& symbol = String::Handle(Z); 12173 String& symbol = String::Handle(Z);
(...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after
12688 void Parser::SkipQualIdent() { 13172 void Parser::SkipQualIdent() {
12689 ASSERT(IsIdentifier()); 13173 ASSERT(IsIdentifier());
12690 ConsumeToken(); 13174 ConsumeToken();
12691 if (CurrentToken() == Token::kPERIOD) { 13175 if (CurrentToken() == Token::kPERIOD) {
12692 ConsumeToken(); // Consume the kPERIOD token. 13176 ConsumeToken(); // Consume the kPERIOD token.
12693 ExpectIdentifier("identifier expected after '.'"); 13177 ExpectIdentifier("identifier expected after '.'");
12694 } 13178 }
12695 } 13179 }
12696 13180
12697 } // namespace dart 13181 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698