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

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());
6421 ASSERT(params->parameters->length() <= 1);
6235 // Add implicit closure parameter if not yet present. 6422 // Add implicit closure parameter if not yet present.
6236 if (params->parameters->length() == 0) { 6423 if (params->parameters->length() == 0) {
6237 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type); 6424 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type);
6238 } 6425 }
6239 ParamDesc result_param; 6426 ParamDesc result_param;
6240 result_param.name = &Symbols::AsyncOperationParam(); 6427 result_param.name = &Symbols::AsyncOperationParam();
6241 result_param.default_value = &Object::null_instance(); 6428 result_param.default_value = &Object::null_instance();
6242 result_param.type = &dynamic_type; 6429 result_param.type = &dynamic_type;
6243 params->parameters->Add(result_param); 6430 params->parameters->Add(result_param);
6244 ParamDesc error_param; 6431 ParamDesc error_param;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
6349 current_block_->scope->CaptureVariable(Symbols::AsyncOperation()); 6536 current_block_->scope->CaptureVariable(Symbols::AsyncOperation());
6350 async_op_var->set_is_captured(); 6537 async_op_var->set_is_captured();
6351 LocalVariable* async_completer = new(Z) LocalVariable( 6538 LocalVariable* async_completer = new(Z) LocalVariable(
6352 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type); 6539 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type);
6353 current_block_->scope->AddVariable(async_completer); 6540 current_block_->scope->AddVariable(async_completer);
6354 current_block_->scope->CaptureVariable(Symbols::AsyncCompleter()); 6541 current_block_->scope->CaptureVariable(Symbols::AsyncCompleter());
6355 async_completer->set_is_captured(); 6542 async_completer->set_is_captured();
6356 } 6543 }
6357 6544
6358 6545
6546 void Parser::AddAsyncGeneratorVariables() {
6547 // Add to current block's scope:
6548 // var :controller;
6549 // The :controller variable is used by the async generator closure to
6550 // store the StreamController object to which the yielded expressions
6551 // are added.
6552 // var :async_op;
6553 // This variable is used to store the async generator closure containing
6554 // the body of the async* function. It is used by the await operator.
6555 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6556 LocalVariable* controller_var = new(Z) LocalVariable(
6557 Scanner::kNoSourcePos, Symbols::Controller(), dynamic_type);
6558 current_block_->scope->AddVariable(controller_var);
6559 current_block_->scope->CaptureVariable(Symbols::Controller());
6560 controller_var->set_is_captured();
6561
6562 LocalVariable* async_op_var = new(Z) LocalVariable(
6563 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
6564 current_block_->scope->AddVariable(async_op_var);
6565 current_block_->scope->CaptureVariable(Symbols::AsyncOperation());
6566 async_op_var->set_is_captured();
6567 }
6568
6569
6570 RawFunction* Parser::OpenAsyncGeneratorFunction(intptr_t async_func_pos) {
6571 TRACE_PARSER("OpenAsyncGeneratorFunction");
6572 AddContinuationVariables();
6573 AddAsyncGeneratorVariables();
6574
6575 Function& closure = Function::Handle(Z);
6576 bool is_new_closure = false;
6577
6578 // Check whether a function for the asynchronous function body of
6579 // this async generator has already been created by a previous
6580 // compilation of this function.
6581 const Function& found_func = Function::Handle(
6582 Z, current_class().LookupClosureFunction(async_func_pos));
6583 if (!found_func.IsNull() &&
6584 (found_func.token_pos() == async_func_pos) &&
6585 (found_func.script() == innermost_function().script()) &&
6586 (found_func.parent_function() == innermost_function().raw())) {
6587 ASSERT(found_func.IsAsyncGenClosure());
6588 closure = found_func.raw();
6589 } else {
6590 // Create the closure containing the body of this async generator function.
6591 const String& async_generator_name =
6592 String::Handle(Z, innermost_function().name());
6593 String& closure_name = String::Handle(Z,
6594 String::NewFormatted("<%s_async_gen_body>",
6595 async_generator_name.ToCString()));
6596 closure = Function::NewClosureFunction(
6597 String::Handle(Z, Symbols::New(closure_name)),
6598 innermost_function(),
6599 async_func_pos);
6600 closure.set_is_generated_body(true);
6601 closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
6602 is_new_closure = true;
6603 }
6604
6605 ParamList closure_params;
6606 AddAsyncGenClosureParameters(&closure_params);
6607
6608 if (is_new_closure) {
6609 // Add the parameters to the newly created closure.
6610 AddFormalParamsToFunction(&closure_params, closure);
6611
6612 // Create and set the signature class of the closure.
6613 const String& sig = String::Handle(Z, closure.Signature());
6614 Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig));
6615 if (sig_cls.IsNull()) {
6616 sig_cls =
6617 Class::NewSignatureClass(sig, closure, script_, closure.token_pos());
6618 library_.AddClass(sig_cls);
6619 }
6620 closure.set_signature_class(sig_cls);
6621 const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType());
6622 if (!sig_type.IsFinalized()) {
6623 ClassFinalizer::FinalizeType(
6624 sig_cls, sig_type, ClassFinalizer::kCanonicalize);
6625 }
6626 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved());
6627 ASSERT(closure.NumParameters() == closure_params.parameters->length());
6628 }
6629
6630 OpenFunctionBlock(closure);
6631 AddFormalParamsToScope(&closure_params, current_block_->scope);
6632 OpenBlock();
6633 async_temp_scope_ = current_block_->scope;
6634 return closure.raw();
6635 }
6636
6637
6638 // Generate the Ast nodes for the implicit code of the async* function.
6639 //
6640 // f(...) async* {
6641 // var :controller;
6642 // var :await_jump_var = -1;
6643 // var :await_context_var;
6644 // f_async_body() {
6645 // ... source code of f ...
6646 // }
6647 // var :async_op = f_async_body;
6648 // :controller = new _AsyncStarStreamController(f_async_body);
6649 // return :controller.stream;
6650 // }
6651 SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure,
6652 SequenceNode* closure_body) {
6653 TRACE_PARSER("CloseAsyncGeneratorFunction");
6654 ASSERT(!closure.IsNull());
6655 ASSERT(closure_body != NULL);
6656
6657 // The block for the async closure body has already been closed. Close the
6658 // corresponding function block.
6659 CloseBlock();
6660
6661 // Make sure the implicit variables of the async generator function
6662 // are captured.
6663 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
6664 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
6665 closure_body->scope()->LookupVariable(Symbols::Controller(), false);
6666 closure_body->scope()->LookupVariable(Symbols::AsyncOperation(), false);
6667
6668 const Class& controller_class = Class::Handle(Z,
6669 Library::LookupCoreClass(Symbols::_AsyncStarStreamController()));
6670 ASSERT(!controller_class.IsNull());
6671 const Function& controller_constructor = Function::ZoneHandle(Z,
6672 controller_class.LookupConstructorAllowPrivate(
6673 Symbols::_AsyncStarStreamControllerConstructor()));
6674
6675 // :await_jump_var = -1;
6676 LocalVariable* jump_var =
6677 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false);
6678 LiteralNode* init_value =
6679 new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1)));
6680 current_block_->statements->Add(
6681 new(Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value));
6682
6683 // Add to AST:
6684 // :async_op = <closure>; (containing the original body)
6685 LocalVariable* async_op_var =
6686 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false);
6687 ClosureNode* cn = new(Z) ClosureNode(
6688 Scanner::kNoSourcePos, closure, NULL, closure_body->scope());
6689 StoreLocalNode* store_async_op = new (Z) StoreLocalNode(
6690 Scanner::kNoSourcePos,
6691 async_op_var,
6692 cn);
6693 current_block_->statements->Add(store_async_op);
6694
6695 // :controller = new _AsyncStarStreamController(body_closure);
6696 ArgumentListNode* arguments = new(Z) ArgumentListNode(Scanner::kNoSourcePos);
6697 ClosureNode* closure_obj = new(Z) ClosureNode(
6698 Scanner::kNoSourcePos, closure, NULL, closure_body->scope());
6699 arguments->Add(closure_obj);
6700 ConstructorCallNode* controller_constructor_call =
6701 new(Z) ConstructorCallNode(Scanner::kNoSourcePos,
6702 TypeArguments::ZoneHandle(Z),
6703 controller_constructor,
6704 arguments);
6705 LocalVariable* controller_var =
6706 current_block_->scope->LookupVariable(Symbols::Controller(), false);
6707 StoreLocalNode* store_controller =
6708 new(Z) StoreLocalNode(Scanner::kNoSourcePos,
6709 controller_var,
6710 controller_constructor_call);
6711 current_block_->statements->Add(store_controller);
6712
6713 // return :controller.stream;
6714 ReturnNode* return_node = new(Z) ReturnNode(Scanner::kNoSourcePos,
6715 new(Z) InstanceGetterNode(Scanner::kNoSourcePos,
6716 new(Z) LoadLocalNode(Scanner::kNoSourcePos,
6717 controller_var),
6718 Symbols::Stream()));
6719 current_block_->statements->Add(return_node);
6720 return CloseBlock();
6721 }
6722
6723
6724 void Parser::OpenAsyncGeneratorClosure() {
6725 async_temp_scope_ = current_block_->scope;
6726 OpenAsyncTryBlock();
6727 }
6728
6729
6730 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) {
6731 // We need a temporary expression to store intermediate return values.
6732 parsed_function()->EnsureExpressionTemp();
6733
6734 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body);
6735 ASSERT(new_body != NULL);
6736 ASSERT(new_body->scope() != NULL);
6737
6738 // Implicitly mark those variables below as captured. We currently mark all
6739 // variables of all scopes as captured, but as soon as we do something
6740 // smarter we rely on these internal variables to be available.
6741 new_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
6742 new_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
6743 new_body->scope()->LookupVariable(Symbols::Controller(), false);
6744 new_body->scope()->LookupVariable(Symbols::AsyncOperationParam(), false);
6745 new_body->scope()->LookupVariable(Symbols::AsyncOperationErrorParam(), false);
6746 new_body->scope()->LookupVariable(
6747 Symbols::AsyncOperationStackTraceParam(), false);
6748 new_body->scope()->RecursivelyCaptureAllVariables();
6749 return new_body;
6750 }
6751
6752
6359 SequenceNode* Parser::CloseBlock() { 6753 SequenceNode* Parser::CloseBlock() {
6360 SequenceNode* statements = current_block_->statements; 6754 SequenceNode* statements = current_block_->statements;
6361 if (current_block_->scope != NULL) { 6755 if (current_block_->scope != NULL) {
6362 // Record the begin and end token index of the scope. 6756 // Record the begin and end token index of the scope.
6363 ASSERT(statements != NULL); 6757 ASSERT(statements != NULL);
6364 current_block_->scope->set_begin_token_pos(statements->token_pos()); 6758 current_block_->scope->set_begin_token_pos(statements->token_pos());
6365 current_block_->scope->set_end_token_pos(TokenPos()); 6759 current_block_->scope->set_end_token_pos(TokenPos());
6366 } 6760 }
6367 current_block_ = current_block_->parent; 6761 current_block_ = current_block_->parent;
6368 return statements; 6762 return statements;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
6458 new (Z) LoadLocalNode( 6852 new (Z) LoadLocalNode(
6459 Scanner::kNoSourcePos, 6853 Scanner::kNoSourcePos,
6460 async_completer), 6854 async_completer),
6461 Symbols::CompleterFuture())); 6855 Symbols::CompleterFuture()));
6462 current_block_->statements->Add(return_node); 6856 current_block_->statements->Add(return_node);
6463 return CloseBlock(); 6857 return CloseBlock();
6464 } 6858 }
6465 6859
6466 6860
6467 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body) { 6861 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body) {
6468 TRACE_PARSER("CloseAsyncClosure");
6469
6470 // We need a temporary expression to store intermediate return values. 6862 // We need a temporary expression to store intermediate return values.
6471 parsed_function()->EnsureExpressionTemp(); 6863 parsed_function()->EnsureExpressionTemp();
6472 // Implicitly mark those variables below as captured. We currently mark all 6864 // Implicitly mark those variables below as captured. We currently mark all
6473 // variables of all scopes as captured (below), but as soon as we do something 6865 // variables of all scopes as captured (below), but as soon as we do something
6474 // smarter we rely on these internal variables to be available. 6866 // smarter we rely on these internal variables to be available.
6475 SequenceNode* new_body = CloseAsyncTryBlock(body); 6867 SequenceNode* new_body = CloseAsyncTryBlock(body);
6476 ASSERT(new_body != NULL); 6868 ASSERT(new_body != NULL);
6477 ASSERT(new_body->scope() != NULL); 6869 ASSERT(new_body->scope() != NULL);
6478 new_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); 6870 new_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
6479 new_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); 6871 new_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
(...skipping 1314 matching lines...) Expand 10 before | Expand all | Expand 10 after
7794 *outer_try_index = try_blocks_list_->outer_try_block()->try_index(); 8186 *outer_try_index = try_blocks_list_->outer_try_block()->try_index();
7795 } 8187 }
7796 } 8188 }
7797 } 8189 }
7798 } 8190 }
7799 // An async or async* has an implicitly created try-catch around the 8191 // 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 8192 // function body, so the await or yield inside the async closure should always
7801 // be created with a try scope. 8193 // be created with a try scope.
7802 ASSERT((*try_scope != NULL) || 8194 ASSERT((*try_scope != NULL) ||
7803 innermost_function().IsAsyncFunction() || 8195 innermost_function().IsAsyncFunction() ||
8196 innermost_function().IsAsyncGenerator() ||
7804 innermost_function().IsSyncGenClosure() || 8197 innermost_function().IsSyncGenClosure() ||
7805 innermost_function().IsSyncGenerator()); 8198 innermost_function().IsSyncGenerator());
7806 } 8199 }
7807 8200
7808 8201
7809 AstNode* Parser::ParseAwaitForStatement(String* label_name) { 8202 AstNode* Parser::ParseAwaitForStatement(String* label_name) {
7810 TRACE_PARSER("ParseAwaitForStatement"); 8203 TRACE_PARSER("ParseAwaitForStatement");
7811 ASSERT(IsAwaitKeyword()); 8204 ASSERT(IsAwaitKeyword());
7812 const intptr_t await_for_pos = TokenPos(); 8205 const intptr_t await_for_pos = TokenPos();
7813 ConsumeToken(); // await. 8206 ConsumeToken(); // await.
7814 ASSERT(CurrentToken() == Token::kFOR); 8207 ASSERT(CurrentToken() == Token::kFOR);
7815 ConsumeToken(); // for. 8208 ConsumeToken(); // for.
7816 ExpectToken(Token::kLPAREN); 8209 ExpectToken(Token::kLPAREN);
7817 8210
7818 if (!innermost_function().IsAsyncFunction() && 8211 if (!innermost_function().IsAsyncFunction() &&
7819 !innermost_function().IsAsyncClosure()) { 8212 !innermost_function().IsAsyncClosure() &&
8213 !innermost_function().IsAsyncGenerator() &&
8214 !innermost_function().IsAsyncGenClosure()) {
7820 ReportError(await_for_pos, 8215 ReportError(await_for_pos,
7821 "await for loop is only allowed in async function"); 8216 "await for loop is only allowed in an asynchronous function");
7822 } 8217 }
7823 8218
7824 // Parse loop variable. 8219 // Parse loop variable.
7825 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); 8220 bool loop_var_is_final = (CurrentToken() == Token::kFINAL);
7826 if (CurrentToken() == Token::kCONST) { 8221 if (CurrentToken() == Token::kCONST) {
7827 ReportError("Loop variable cannot be 'const'"); 8222 ReportError("Loop variable cannot be 'const'");
7828 } 8223 }
7829 bool new_loop_var = false; 8224 bool new_loop_var = false;
7830 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); 8225 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z);
7831 if (LookaheadToken(1) != Token::kIN) { 8226 if (LookaheadToken(1) != Token::kIN) {
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
8256 } 8651 }
8257 } 8652 }
8258 8653
8259 8654
8260 // Populate current scope of the try block with the saved exception and saved 8655 // Populate current scope of the try block with the saved exception and saved
8261 // stack trace. 8656 // stack trace.
8262 void Parser::SetupSavedExceptionAndStacktrace() { 8657 void Parser::SetupSavedExceptionAndStacktrace() {
8263 ASSERT(innermost_function().IsAsyncClosure() || 8658 ASSERT(innermost_function().IsAsyncClosure() ||
8264 innermost_function().IsAsyncFunction() || 8659 innermost_function().IsAsyncFunction() ||
8265 innermost_function().IsSyncGenClosure() || 8660 innermost_function().IsSyncGenClosure() ||
8266 innermost_function().IsSyncGenerator()); 8661 innermost_function().IsSyncGenerator() ||
8662 innermost_function().IsAsyncGenerator() ||
8663 innermost_function().IsAsyncGenClosure());
8267 // Add :saved_exception_var and :saved_stack_trace_var to current scope. 8664 // Add :saved_exception_var and :saved_stack_trace_var to current scope.
8268 // They will automatically get captured. 8665 // They will automatically get captured.
8269 // Parallel try statements share the same set of variables. 8666 // Parallel try statements share the same set of variables.
8270 LocalVariable* saved_exception_var = 8667 LocalVariable* saved_exception_var =
8271 current_block_->scope->LocalLookupVariable(Symbols::SavedExceptionVar()); 8668 current_block_->scope->LocalLookupVariable(Symbols::SavedExceptionVar());
8272 if (saved_exception_var == NULL) { 8669 if (saved_exception_var == NULL) {
8273 saved_exception_var = new (Z) LocalVariable( 8670 saved_exception_var = new (Z) LocalVariable(
8274 Scanner::kNoSourcePos, 8671 Scanner::kNoSourcePos,
8275 Symbols::SavedExceptionVar(), 8672 Symbols::SavedExceptionVar(),
8276 Type::ZoneHandle(Z, Type::DynamicType())); 8673 Type::ZoneHandle(Z, Type::DynamicType()));
(...skipping 13 matching lines...) Expand all
8290 } 8687 }
8291 8688
8292 8689
8293 // Generate code to load the exception object (:exception_var) into 8690 // Generate code to load the exception object (:exception_var) into
8294 // the saved exception variable (:saved_exception_var) used to rethrow. 8691 // the saved exception variable (:saved_exception_var) used to rethrow.
8295 void Parser::SaveExceptionAndStacktrace(LocalVariable* exception_var, 8692 void Parser::SaveExceptionAndStacktrace(LocalVariable* exception_var,
8296 LocalVariable* stack_trace_var) { 8693 LocalVariable* stack_trace_var) {
8297 ASSERT(innermost_function().IsAsyncClosure() || 8694 ASSERT(innermost_function().IsAsyncClosure() ||
8298 innermost_function().IsAsyncFunction() || 8695 innermost_function().IsAsyncFunction() ||
8299 innermost_function().IsSyncGenClosure() || 8696 innermost_function().IsSyncGenClosure() ||
8300 innermost_function().IsSyncGenerator()); 8697 innermost_function().IsSyncGenerator() ||
8698 innermost_function().IsAsyncGenClosure() ||
8699 innermost_function().IsAsyncGenerator());
8301 LocalVariable* saved_exception_var = current_block_->scope->LookupVariable( 8700 LocalVariable* saved_exception_var = current_block_->scope->LookupVariable(
8302 Symbols::SavedExceptionVar(), false); 8701 Symbols::SavedExceptionVar(), false);
8303 ASSERT(saved_exception_var != NULL); 8702 ASSERT(saved_exception_var != NULL);
8304 ASSERT(exception_var != NULL); 8703 ASSERT(exception_var != NULL);
8305 current_block_->statements->Add(new(Z) StoreLocalNode( 8704 current_block_->statements->Add(new(Z) StoreLocalNode(
8306 Scanner::kNoSourcePos, 8705 Scanner::kNoSourcePos,
8307 saved_exception_var, 8706 saved_exception_var,
8308 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); 8707 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var)));
8309 8708
8310 // Generate code to load the stack trace object (:stack_trace_var) into 8709 // Generate code to load the stack trace object (:stack_trace_var) into
(...skipping 13 matching lines...) Expand all
8324 TRACE_PARSER("ParseFinallyBlock"); 8723 TRACE_PARSER("ParseFinallyBlock");
8325 OpenBlock(); 8724 OpenBlock();
8326 ExpectToken(Token::kLBRACE); 8725 ExpectToken(Token::kLBRACE);
8327 8726
8328 // In case of async closures we need to restore the saved try index of an 8727 // 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 8728 // outer try block (if it exists). The current try block has already been
8330 // removed from the stack of try blocks. 8729 // removed from the stack of try blocks.
8331 if ((innermost_function().IsAsyncClosure() || 8730 if ((innermost_function().IsAsyncClosure() ||
8332 innermost_function().IsAsyncFunction() || 8731 innermost_function().IsAsyncFunction() ||
8333 innermost_function().IsSyncGenClosure() || 8732 innermost_function().IsSyncGenClosure() ||
8334 innermost_function().IsSyncGenerator()) && 8733 innermost_function().IsSyncGenerator() ||
8734 innermost_function().IsAsyncGenerator() ||
8735 innermost_function().IsAsyncGenClosure()) &&
8335 (try_blocks_list_ != NULL)) { 8736 (try_blocks_list_ != NULL)) {
8336 LocalScope* scope = try_blocks_list_->try_block()->scope; 8737 LocalScope* scope = try_blocks_list_->try_block()->scope;
8337 if (scope->function_level() == current_block_->scope->function_level()) { 8738 if (scope->function_level() == current_block_->scope->function_level()) {
8338 current_block_->statements->Add( 8739 current_block_->statements->Add(
8339 AwaitTransformer::RestoreSavedTryContext( 8740 AwaitTransformer::RestoreSavedTryContext(
8340 Z, scope->parent(), try_blocks_list_->try_index())); 8741 Z, scope->parent(), try_blocks_list_->try_index()));
8341 } 8742 }
8342 } 8743 }
8343 8744
8344 ParseStatementSequence(); 8745 ParseStatementSequence();
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
8433 } else { 8834 } else {
8434 exception_param.type = &AbstractType::ZoneHandle(Z, Type::DynamicType()); 8835 exception_param.type = &AbstractType::ZoneHandle(Z, Type::DynamicType());
8435 } 8836 }
8436 if (CurrentToken() == Token::kCATCH) { 8837 if (CurrentToken() == Token::kCATCH) {
8437 ConsumeToken(); // Consume the 'catch'. 8838 ConsumeToken(); // Consume the 'catch'.
8438 ExpectToken(Token::kLPAREN); 8839 ExpectToken(Token::kLPAREN);
8439 exception_param.token_pos = TokenPos(); 8840 exception_param.token_pos = TokenPos();
8440 exception_param.name = ExpectIdentifier("identifier expected"); 8841 exception_param.name = ExpectIdentifier("identifier expected");
8441 if (CurrentToken() == Token::kCOMMA) { 8842 if (CurrentToken() == Token::kCOMMA) {
8442 ConsumeToken(); 8843 ConsumeToken();
8443 // TODO(hausner): Make implicit type be StackTrace, not dynamic.
8444 stack_trace_param.type = 8844 stack_trace_param.type =
8445 &AbstractType::ZoneHandle(Z, Type::DynamicType()); 8845 &AbstractType::ZoneHandle(Z, Type::DynamicType());
8446 stack_trace_param.token_pos = TokenPos(); 8846 stack_trace_param.token_pos = TokenPos();
8447 stack_trace_param.name = ExpectIdentifier("identifier expected"); 8847 stack_trace_param.name = ExpectIdentifier("identifier expected");
8448 } 8848 }
8449 ExpectToken(Token::kRPAREN); 8849 ExpectToken(Token::kRPAREN);
8450 } 8850 }
8451 8851
8452 // Create a block containing the catch clause parameters and the 8852 // Create a block containing the catch clause parameters and the
8453 // following code: 8853 // following code:
(...skipping 18 matching lines...) Expand all
8472 // A stack trace variable is specified in this block, so generate code 8872 // 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 8873 // to load the stack trace object (:stack_trace_var) into the stack
8474 // trace variable specified in this block. 8874 // trace variable specified in this block.
8475 *needs_stack_trace = true; 8875 *needs_stack_trace = true;
8476 ASSERT(stack_trace_var != NULL); 8876 ASSERT(stack_trace_var != NULL);
8477 current_block_->statements->Add(new(Z) StoreLocalNode( 8877 current_block_->statements->Add(new(Z) StoreLocalNode(
8478 catch_pos, stack_trace_param.var, new(Z) LoadLocalNode( 8878 catch_pos, stack_trace_param.var, new(Z) LoadLocalNode(
8479 catch_pos, stack_trace_var))); 8879 catch_pos, stack_trace_var)));
8480 } 8880 }
8481 8881
8482 // Add nested block with user-defined code. This blocks allows 8882 // Add nested block with user-defined code. This block allows
8483 // declarations in the body to shadow the catch parameters. 8883 // declarations in the body to shadow the catch parameters.
8484 CheckToken(Token::kLBRACE); 8884 CheckToken(Token::kLBRACE);
8485 8885
8486 // In case of async closures we need to restore the saved try index of an 8886 // In case of async closures we need to restore the saved try index of an
8487 // outer try block (if it exists). 8887 // outer try block (if it exists).
8488 ASSERT(try_blocks_list_ != NULL); 8888 ASSERT(try_blocks_list_ != NULL);
8489 if (innermost_function().IsAsyncClosure() || 8889 if (innermost_function().IsAsyncClosure() ||
8490 innermost_function().IsAsyncFunction() || 8890 innermost_function().IsAsyncFunction() ||
8491 innermost_function().IsSyncGenClosure() || 8891 innermost_function().IsSyncGenClosure() ||
8492 innermost_function().IsSyncGenerator()) { 8892 innermost_function().IsSyncGenerator() ||
8893 innermost_function().IsAsyncGenerator() ||
8894 innermost_function().IsAsyncGenClosure()) {
8493 const TryBlocks* try_block = try_blocks_list_->outer_try_block(); 8895 const TryBlocks* try_block = try_blocks_list_->outer_try_block();
8494 if (try_block != NULL) { 8896 if (try_block != NULL) {
8495 LocalScope* scope = try_block->try_block()->scope; 8897 LocalScope* scope = try_block->try_block()->scope;
8496 if (scope->function_level() == 8898 if (scope->function_level() ==
8497 current_block_->scope->function_level()) { 8899 current_block_->scope->function_level()) {
8498 current_block_->statements->Add( 8900 current_block_->statements->Add(
8499 AwaitTransformer::RestoreSavedTryContext( 8901 AwaitTransformer::RestoreSavedTryContext(
8500 Z, scope->parent(), try_block->try_index())); 8902 Z, scope->parent(), try_block->try_index()));
8501 } 8903 }
8502 } 8904 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
8595 current_block_->statements->Add(new(Z) IfNode( 8997 current_block_->statements->Add(new(Z) IfNode(
8596 type_test->token_pos(), type_test, catch_block, current)); 8998 type_test->token_pos(), type_test, catch_block, current));
8597 current = CloseBlock(); 8999 current = CloseBlock();
8598 } 9000 }
8599 // Restore :saved_try_context_var before executing the catch clauses. 9001 // Restore :saved_try_context_var before executing the catch clauses.
8600 if (current != NULL) { 9002 if (current != NULL) {
8601 ASSERT(try_blocks_list_ != NULL); 9003 ASSERT(try_blocks_list_ != NULL);
8602 if (innermost_function().IsAsyncClosure() || 9004 if (innermost_function().IsAsyncClosure() ||
8603 innermost_function().IsAsyncFunction() || 9005 innermost_function().IsAsyncFunction() ||
8604 innermost_function().IsSyncGenClosure() || 9006 innermost_function().IsSyncGenClosure() ||
8605 innermost_function().IsSyncGenerator()) { 9007 innermost_function().IsSyncGenerator() ||
9008 innermost_function().IsAsyncGenerator() ||
9009 innermost_function().IsAsyncGenClosure()) {
8606 const TryBlocks* try_block = try_blocks_list_->outer_try_block(); 9010 const TryBlocks* try_block = try_blocks_list_->outer_try_block();
8607 if (try_block != NULL) { 9011 if (try_block != NULL) {
8608 LocalScope* scope = try_block->try_block()->scope; 9012 LocalScope* scope = try_block->try_block()->scope;
8609 if (scope->function_level() == 9013 if (scope->function_level() ==
8610 current_block_->scope->function_level()) { 9014 current_block_->scope->function_level()) {
8611 SequenceNode* restore_code = new(Z) SequenceNode(handler_pos, NULL); 9015 SequenceNode* restore_code = new(Z) SequenceNode(handler_pos, NULL);
8612 restore_code->Add( 9016 restore_code->Add(
8613 AwaitTransformer::RestoreSavedTryContext( 9017 AwaitTransformer::RestoreSavedTryContext(
8614 Z, scope->parent(), try_block->try_index())); 9018 Z, scope->parent(), try_block->try_index()));
8615 restore_code->Add(current); 9019 restore_code->Add(current);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
8687 stack_trace_var = new(Z) LocalVariable( 9091 stack_trace_var = new(Z) LocalVariable(
8688 TokenPos(), 9092 TokenPos(),
8689 Symbols::StackTraceVar(), 9093 Symbols::StackTraceVar(),
8690 Type::ZoneHandle(Z, Type::DynamicType())); 9094 Type::ZoneHandle(Z, Type::DynamicType()));
8691 current_block_->scope->AddVariable(stack_trace_var); 9095 current_block_->scope->AddVariable(stack_trace_var);
8692 } 9096 }
8693 9097
8694 if (innermost_function().IsAsyncClosure() || 9098 if (innermost_function().IsAsyncClosure() ||
8695 innermost_function().IsAsyncFunction() || 9099 innermost_function().IsAsyncFunction() ||
8696 innermost_function().IsSyncGenClosure() || 9100 innermost_function().IsSyncGenClosure() ||
8697 innermost_function().IsSyncGenerator()) { 9101 innermost_function().IsSyncGenerator() ||
9102 innermost_function().IsAsyncGenClosure() ||
9103 innermost_function().IsAsyncGenerator()) {
8698 SetupSavedExceptionAndStacktrace(); 9104 SetupSavedExceptionAndStacktrace();
8699 } 9105 }
8700 9106
8701 const intptr_t try_pos = TokenPos(); 9107 const intptr_t try_pos = TokenPos();
8702 ConsumeToken(); // Consume the 'try'. 9108 ConsumeToken(); // Consume the 'try'.
8703 9109
8704 SourceLabel* try_label = NULL; 9110 SourceLabel* try_label = NULL;
8705 if (label_name != NULL) { 9111 if (label_name != NULL) {
8706 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); 9112 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement);
8707 OpenBlock(); 9113 OpenBlock();
8708 current_block_->scope->AddLabel(try_label); 9114 current_block_->scope->AddLabel(try_label);
8709 } 9115 }
8710 9116
8711 // Now parse the 'try' block. 9117 // Now parse the 'try' block.
8712 OpenBlock(); 9118 OpenBlock();
8713 PushTryBlock(current_block_); 9119 PushTryBlock(current_block_);
8714 ExpectToken(Token::kLBRACE); 9120 ExpectToken(Token::kLBRACE);
8715 9121
8716 if (innermost_function().IsAsyncClosure() || 9122 if (innermost_function().IsAsyncClosure() ||
8717 innermost_function().IsAsyncFunction() || 9123 innermost_function().IsAsyncFunction() ||
8718 innermost_function().IsSyncGenClosure() || 9124 innermost_function().IsSyncGenClosure() ||
8719 innermost_function().IsSyncGenerator()) { 9125 innermost_function().IsSyncGenerator() ||
9126 innermost_function().IsAsyncGenerator() ||
9127 innermost_function().IsAsyncGenClosure()) {
8720 SetupSavedTryContext(context_var); 9128 SetupSavedTryContext(context_var);
8721 } 9129 }
8722 9130
8723 ParseStatementSequence(); 9131 ParseStatementSequence();
8724 ExpectToken(Token::kRBRACE); 9132 ExpectToken(Token::kRBRACE);
8725 SequenceNode* try_block = CloseBlock(); 9133 SequenceNode* try_block = CloseBlock();
8726 9134
8727 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && 9135 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") &&
8728 (CurrentToken() != Token::kFINALLY)) { 9136 (CurrentToken() != Token::kFINALLY)) {
8729 ReportError("catch or finally clause expected"); 9137 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"); 9261 ReportError(jump_pos, "'break' to case clause label is illegal");
8854 } 9262 }
8855 if (target->FunctionLevel() != current_block_->scope->function_level()) { 9263 if (target->FunctionLevel() != current_block_->scope->function_level()) {
8856 ReportError(jump_pos, "'%s' target must be in same function context", 9264 ReportError(jump_pos, "'%s' target must be in same function context",
8857 Token::Str(jump_kind)); 9265 Token::Str(jump_kind));
8858 } 9266 }
8859 return new(Z) JumpNode(jump_pos, jump_kind, target); 9267 return new(Z) JumpNode(jump_pos, jump_kind, target);
8860 } 9268 }
8861 9269
8862 9270
9271 AstNode* Parser::ParseYieldStatement() {
9272 bool is_yield_each = false;
9273 const intptr_t yield_pos = TokenPos();
9274 ConsumeToken(); // yield reserved word.
9275 ASSERT(innermost_function().IsGenerator() ||
9276 innermost_function().IsSyncGenClosure() ||
9277 innermost_function().IsAsyncGenerator() ||
9278 innermost_function().IsAsyncGenClosure());
9279 if (CurrentToken() == Token::kMUL) {
9280 is_yield_each = true;
9281 ConsumeToken();
9282 }
9283 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
9284
9285 LetNode* yield = new(Z) LetNode(yield_pos);
9286 if (innermost_function().IsSyncGenerator() ||
9287 innermost_function().IsSyncGenClosure()) {
9288 // Yield statement in sync* function.
9289
9290 LocalVariable* iterator_param =
9291 LookupLocalScope(Symbols::IteratorParameter());
9292 ASSERT(iterator_param != NULL);
9293 // Generate :iterator.current = expr;
9294 AstNode* iterator =
9295 new(Z) LoadLocalNode(Scanner::kNoSourcePos, iterator_param);
9296 AstNode* store_current =
9297 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
9298 iterator,
9299 String::ZoneHandle(Symbols::Current().raw()),
9300 expr);
9301 yield->AddNode(store_current);
9302 if (is_yield_each) {
9303 // Generate :iterator.isYieldEach = true;
9304 AstNode* set_is_yield_each =
9305 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
9306 iterator,
9307 String::ZoneHandle(Symbols::IsYieldEach().raw()),
9308 new(Z) LiteralNode(TokenPos(), Bool::True()));
9309 yield->AddNode(set_is_yield_each);
9310 }
9311 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
9312 await_marker->set_scope(current_block_->scope);
9313 yield->AddNode(await_marker);
9314 // Return true to indicate that a value has been generated.
9315 ReturnNode* return_true = new(Z) ReturnNode(yield_pos,
9316 new(Z) LiteralNode(TokenPos(), Bool::True()));
9317 return_true->set_return_type(ReturnNode::kContinuationTarget);
9318 yield->AddNode(return_true);
9319
9320 // If this expression is part of a try block, also append the code for
9321 // restoring the saved try context that lives on the stack and possibly the
9322 // saved try context of the outer try block.
9323 LocalScope* try_scope;
9324 int16_t try_index;
9325 LocalScope* outer_try_scope;
9326 int16_t outer_try_index;
9327 CheckAsyncOpInTryBlock(&try_scope, &try_index,
9328 &outer_try_scope, &outer_try_index);
9329 if (try_scope != NULL) {
9330 yield->AddNode(
9331 AwaitTransformer::RestoreSavedTryContext(Z,
9332 try_scope,
9333 try_index));
9334 if (outer_try_scope != NULL) {
9335 yield->AddNode(
9336 AwaitTransformer::RestoreSavedTryContext(Z,
9337 outer_try_scope,
9338 outer_try_index));
9339 }
9340 } else {
9341 ASSERT(outer_try_scope == NULL);
9342 }
9343 } else {
9344 // yield statement in async* function.
9345 ASSERT(innermost_function().IsAsyncGenerator() ||
9346 innermost_function().IsAsyncGenClosure());
9347
9348 LocalVariable* controller_var = LookupLocalScope(Symbols::Controller());
9349 ASSERT(controller_var != NULL);
9350 // :controller.add[Stream](expr);
9351 ArgumentListNode* add_args = new(Z) ArgumentListNode(yield_pos);
9352 add_args->Add(expr);
9353 AstNode* add_call =
9354 new(Z) InstanceCallNode(yield_pos,
9355 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller_var),
9356 is_yield_each ? Symbols::AddStream() : Symbols::add(),
9357 add_args);
9358
9359
9360 // if (:controller.add[Stream](expr)) {
9361 // return;
9362 // }
9363 // await_marker;
9364 // continuation_return;
9365 // restore saved_try_context
9366
9367 SequenceNode* true_branch =
9368 new(Z) SequenceNode(Scanner::kNoSourcePos, current_block_->scope);
9369 AstNode* return_from_generator = new(Z) ReturnNode(yield_pos);
9370 true_branch->Add(return_from_generator);
9371 AddNodeForFinallyInlining(return_from_generator);
9372 AstNode* if_is_cancelled =
9373 new(Z) IfNode(Scanner::kNoSourcePos, add_call, true_branch, NULL);
9374 yield->AddNode(if_is_cancelled);
9375
9376 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
9377 await_marker->set_scope(current_block_->scope);
9378 yield->AddNode(await_marker);
9379 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos);
9380 continuation_return->set_return_type(ReturnNode::kContinuationTarget);
9381 yield->AddNode(continuation_return);
9382
9383 // If this expression is part of a try block, also append the code for
9384 // restoring the saved try context that lives on the stack and possibly the
9385 // saved try context of the outer try block.
9386 LocalScope* try_scope;
9387 int16_t try_index;
9388 LocalScope* outer_try_scope;
9389 int16_t outer_try_index;
9390 CheckAsyncOpInTryBlock(&try_scope, &try_index,
9391 &outer_try_scope, &outer_try_index);
9392 if (try_scope != NULL) {
9393 yield->AddNode(
9394 AwaitTransformer::RestoreSavedTryContext(Z,
9395 try_scope,
9396 try_index));
9397 if (outer_try_scope != NULL) {
9398 yield->AddNode(
9399 AwaitTransformer::RestoreSavedTryContext(Z,
9400 outer_try_scope,
9401 outer_try_index));
9402 }
9403 } else {
9404 ASSERT(outer_try_scope == NULL);
9405 }
9406 }
9407 return yield;
9408 }
9409
9410
8863 AstNode* Parser::ParseStatement() { 9411 AstNode* Parser::ParseStatement() {
8864 TRACE_PARSER("ParseStatement"); 9412 TRACE_PARSER("ParseStatement");
8865 AstNode* statement = NULL; 9413 AstNode* statement = NULL;
8866 intptr_t label_pos = 0; 9414 intptr_t label_pos = 0;
8867 String* label_name = NULL; 9415 String* label_name = NULL;
8868 if (IsIdentifier()) { 9416 if (IsIdentifier()) {
8869 if (LookaheadToken(1) == Token::kCOLON) { 9417 if (LookaheadToken(1) == Token::kCOLON) {
8870 // Statement starts with a label. 9418 // Statement starts with a label.
8871 label_name = CurrentLiteral(); 9419 label_name = CurrentLiteral();
8872 label_pos = TokenPos(); 9420 label_pos = TokenPos();
(...skipping 19 matching lines...) Expand all
8892 statement = ParseTryStatement(label_name); 9440 statement = ParseTryStatement(label_name);
8893 } else if (token == Token::kRETURN) { 9441 } else if (token == Token::kRETURN) {
8894 const intptr_t return_pos = TokenPos(); 9442 const intptr_t return_pos = TokenPos();
8895 ConsumeToken(); 9443 ConsumeToken();
8896 if (CurrentToken() != Token::kSEMICOLON) { 9444 if (CurrentToken() != Token::kSEMICOLON) {
8897 const intptr_t expr_pos = TokenPos(); 9445 const intptr_t expr_pos = TokenPos();
8898 if (current_function().IsGenerativeConstructor() && 9446 if (current_function().IsGenerativeConstructor() &&
8899 (current_block_->scope->function_level() == 0)) { 9447 (current_block_->scope->function_level() == 0)) {
8900 ReportError(expr_pos, 9448 ReportError(expr_pos,
8901 "return of a value is not allowed in constructors"); 9449 "return of a value is not allowed in constructors");
8902 } else if (current_function().IsGenerator()) { 9450 } else if (current_function().IsGeneratorClosure() &&
9451 (current_block_->scope->function_level() == 0)) {
8903 ReportError(expr_pos, "generator functions may not return a value"); 9452 ReportError(expr_pos, "generator functions may not return a value");
8904 } 9453 }
8905 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); 9454 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
8906 statement = new(Z) ReturnNode(statement_pos, expr); 9455 statement = new(Z) ReturnNode(statement_pos, expr);
8907 } else { 9456 } else {
8908 if (current_function().IsSyncGenClosure() && 9457 if (current_function().IsSyncGenClosure() &&
8909 (current_block_->scope->function_level() == 0)) { 9458 (current_block_->scope->function_level() == 0)) {
8910 // In a synchronous generator, return without an expression 9459 // In a synchronous generator, return without an expression
8911 // returns false, signaling that the iterator terminates and 9460 // returns false, signaling that the iterator terminates and
8912 // did not yield a value. 9461 // did not yield a value.
8913 statement = new(Z) ReturnNode(statement_pos, 9462 statement = new(Z) ReturnNode(statement_pos,
8914 new(Z) LiteralNode(return_pos, Bool::False())); 9463 new(Z) LiteralNode(return_pos, Bool::False()));
8915 } else { 9464 } else {
8916 statement = new(Z) ReturnNode(statement_pos); 9465 statement = new(Z) ReturnNode(statement_pos);
8917 } 9466 }
8918 } 9467 }
8919 AddNodeForFinallyInlining(statement); 9468 AddNodeForFinallyInlining(statement);
8920 ExpectSemicolon(); 9469 ExpectSemicolon();
8921 } else if (IsYieldKeyword()) { 9470 } else if (IsYieldKeyword()) {
8922 bool is_yield_each = false; 9471 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(); 9472 ExpectSemicolon();
8988 } else if (token == Token::kIF) { 9473 } else if (token == Token::kIF) {
8989 statement = ParseIfStatement(label_name); 9474 statement = ParseIfStatement(label_name);
8990 } else if (token == Token::kASSERT) { 9475 } else if (token == Token::kASSERT) {
8991 statement = ParseAssertStatement(); 9476 statement = ParseAssertStatement();
8992 ExpectSemicolon(); 9477 ExpectSemicolon();
8993 } else if (IsVariableDeclaration()) { 9478 } else if (IsVariableDeclaration()) {
8994 statement = ParseVariableDeclarationList(); 9479 statement = ParseVariableDeclarationList();
8995 ExpectSemicolon(); 9480 ExpectSemicolon();
8996 } else if (IsFunctionDeclaration()) { 9481 } else if (IsFunctionDeclaration()) {
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after
9837 } 10322 }
9838 10323
9839 10324
9840 AstNode* Parser::ParseUnaryExpr() { 10325 AstNode* Parser::ParseUnaryExpr() {
9841 TRACE_PARSER("ParseUnaryExpr"); 10326 TRACE_PARSER("ParseUnaryExpr");
9842 AstNode* expr = NULL; 10327 AstNode* expr = NULL;
9843 const intptr_t op_pos = TokenPos(); 10328 const intptr_t op_pos = TokenPos();
9844 if (IsAwaitKeyword()) { 10329 if (IsAwaitKeyword()) {
9845 TRACE_PARSER("ParseAwaitExpr"); 10330 TRACE_PARSER("ParseAwaitExpr");
9846 if (!innermost_function().IsAsyncFunction() && 10331 if (!innermost_function().IsAsyncFunction() &&
9847 !innermost_function().IsAsyncClosure()) { 10332 !innermost_function().IsAsyncClosure() &&
9848 ReportError("await operator is only allowed in async function"); 10333 !innermost_function().IsAsyncGenerator() &&
10334 !innermost_function().IsAsyncGenClosure()) {
10335 ReportError("await operator is only allowed in an asynchronous function");
9849 } 10336 }
9850 ConsumeToken(); 10337 ConsumeToken();
9851 parsed_function()->record_await(); 10338 parsed_function()->record_await();
9852 10339
9853 LocalScope* try_scope; 10340 LocalScope* try_scope;
9854 int16_t try_index; 10341 int16_t try_index;
9855 LocalScope* outer_try_scope; 10342 LocalScope* outer_try_scope;
9856 int16_t outer_try_index; 10343 int16_t outer_try_index;
9857 CheckAsyncOpInTryBlock(&try_scope, &try_index, 10344 CheckAsyncOpInTryBlock(&try_scope, &try_index,
9858 &outer_try_scope, &outer_try_index); 10345 &outer_try_scope, &outer_try_index);
(...skipping 1810 matching lines...) Expand 10 before | Expand all | Expand 10 after
11669 // them here. 12156 // them here.
11670 // Map and List interfaces do not declare bounds on their type parameters, so 12157 // Map and List interfaces do not declare bounds on their type parameters, so
11671 // we will not see malbounded type arguments here. 12158 // we will not see malbounded type arguments here.
11672 AstNode* primary = NULL; 12159 AstNode* primary = NULL;
11673 if ((CurrentToken() == Token::kLBRACK) || 12160 if ((CurrentToken() == Token::kLBRACK) ||
11674 (CurrentToken() == Token::kINDEX)) { 12161 (CurrentToken() == Token::kINDEX)) {
11675 primary = ParseListLiteral(type_pos, is_const, type_arguments); 12162 primary = ParseListLiteral(type_pos, is_const, type_arguments);
11676 } else if (CurrentToken() == Token::kLBRACE) { 12163 } else if (CurrentToken() == Token::kLBRACE) {
11677 primary = ParseMapLiteral(type_pos, is_const, type_arguments); 12164 primary = ParseMapLiteral(type_pos, is_const, type_arguments);
11678 } else { 12165 } else {
11679 ReportError("unexpected token %s", Token::Str(CurrentToken())); 12166 UnexpectedToken();
11680 } 12167 }
11681 return primary; 12168 return primary;
11682 } 12169 }
11683 12170
11684 12171
11685 AstNode* Parser::ParseSymbolLiteral() { 12172 AstNode* Parser::ParseSymbolLiteral() {
11686 ASSERT(CurrentToken() == Token::kHASH); 12173 ASSERT(CurrentToken() == Token::kHASH);
11687 ConsumeToken(); 12174 ConsumeToken();
11688 intptr_t symbol_pos = TokenPos(); 12175 intptr_t symbol_pos = TokenPos();
11689 String& symbol = String::Handle(Z); 12176 String& symbol = String::Handle(Z);
(...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after
12688 void Parser::SkipQualIdent() { 13175 void Parser::SkipQualIdent() {
12689 ASSERT(IsIdentifier()); 13176 ASSERT(IsIdentifier());
12690 ConsumeToken(); 13177 ConsumeToken();
12691 if (CurrentToken() == Token::kPERIOD) { 13178 if (CurrentToken() == Token::kPERIOD) {
12692 ConsumeToken(); // Consume the kPERIOD token. 13179 ConsumeToken(); // Consume the kPERIOD token.
12693 ExpectIdentifier("identifier expected after '.'"); 13180 ExpectIdentifier("identifier expected after '.'");
12694 } 13181 }
12695 } 13182 }
12696 13183
12697 } // namespace dart 13184 } // 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