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

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

Issue 944893005: Implement async* functions in VM (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/ast_transformer.h" 9 #include "vm/ast_transformer.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 3097 matching lines...) Expand 10 before | Expand all | Expand 10 after
3108 AddFormalParamsToScope(&params, current_block_->scope); 3108 AddFormalParamsToScope(&params, current_block_->scope);
3109 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); 3109 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved());
3110 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { 3110 if (!Function::Handle(func.parent_function()).IsGetterFunction()) {
3111 // Parse and discard any formal parameters. They are accessed as 3111 // Parse and discard any formal parameters. They are accessed as
3112 // context variables. 3112 // context variables.
3113 ParamList discarded_params; 3113 ParamList discarded_params;
3114 ParseFormalParameterList(allow_explicit_default_values, 3114 ParseFormalParameterList(allow_explicit_default_values,
3115 false, 3115 false,
3116 &discarded_params); 3116 &discarded_params);
3117 } 3117 }
3118 } else if (func.IsAsyncGenClosure()) {
3119 AddAsyncGenClosureParameters(&params);
3120 SetupDefaultsForOptionalParams(&params, default_parameter_values);
3121 AddFormalParamsToScope(&params, current_block_->scope);
3122 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved());
3123 ASSERT(func.NumParameters() == params.parameters->length());
3124 if (!Function::Handle(func.parent_function()).IsGetterFunction()) {
3125 // Parse and discard any formal parameters. They are accessed as
3126 // context variables.
3127 ParamList discarded_params;
3128 ParseFormalParameterList(allow_explicit_default_values,
3129 false,
3130 &discarded_params);
3131 }
3118 } else { 3132 } else {
3119 ParseFormalParameterList(allow_explicit_default_values, false, &params); 3133 ParseFormalParameterList(allow_explicit_default_values, false, &params);
3120 3134
3121 // The number of parameters and their type are not yet set in local 3135 // The number of parameters and their type are not yet set in local
3122 // functions, since they are not 'top-level' parsed. 3136 // functions, since they are not 'top-level' parsed.
3123 if (func.IsLocalFunction()) { 3137 if (func.IsLocalFunction()) {
3124 AddFormalParamsToFunction(&params, func); 3138 AddFormalParamsToFunction(&params, func);
3125 } 3139 }
3126 SetupDefaultsForOptionalParams(&params, default_parameter_values); 3140 SetupDefaultsForOptionalParams(&params, default_parameter_values);
3127 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); 3141 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3176 ASSERT(func.is_debuggable()); 3190 ASSERT(func.is_debuggable());
3177 OpenAsyncClosure(); 3191 OpenAsyncClosure();
3178 } else if (func.IsSyncGenerator()) { 3192 } else if (func.IsSyncGenerator()) {
3179 // The code of a sync generator is synthesized. Disable debugging. 3193 // The code of a sync generator is synthesized. Disable debugging.
3180 func.set_is_debuggable(false); 3194 func.set_is_debuggable(false);
3181 generated_body_closure = OpenSyncGeneratorFunction(func.token_pos()); 3195 generated_body_closure = OpenSyncGeneratorFunction(func.token_pos());
3182 } else if (func.IsSyncGenClosure()) { 3196 } else if (func.IsSyncGenClosure()) {
3183 // The closure containing the body of a sync generator is debuggable. 3197 // The closure containing the body of a sync generator is debuggable.
3184 ASSERT(func.is_debuggable()); 3198 ASSERT(func.is_debuggable());
3185 async_temp_scope_ = current_block_->scope; 3199 async_temp_scope_ = current_block_->scope;
3200 } else if (func.IsAsyncGenerator()) {
3201 func.set_is_debuggable(false);
3202 generated_body_closure = OpenAsyncGeneratorFunction(func.token_pos());
3203 } else if (func.IsAsyncGenClosure()) {
3204 // The closure containing the body of an async* function is debuggable.
3205 ASSERT(func.is_debuggable());
3206 OpenAsyncGeneratorClosure();
3186 } 3207 }
3187 3208
3188 BoolScope allow_await(&this->await_is_keyword_, 3209 BoolScope allow_await(&this->await_is_keyword_,
3189 func.IsAsyncOrGenerator() || func.is_generated_body()); 3210 func.IsAsyncOrGenerator() || func.is_generated_body());
3190 intptr_t end_token_pos = 0; 3211 intptr_t end_token_pos = 0;
3191 if (CurrentToken() == Token::kLBRACE) { 3212 if (CurrentToken() == Token::kLBRACE) {
3192 ConsumeToken(); 3213 ConsumeToken();
3193 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { 3214 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) {
3194 const Class& owner = Class::Handle(Z, func.Owner()); 3215 const Class& owner = Class::Handle(Z, func.Owner());
3195 if (!owner.IsObjectClass()) { 3216 if (!owner.IsObjectClass()) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3253 if (func.IsAsyncFunction()) { 3274 if (func.IsAsyncFunction()) {
3254 body = CloseAsyncFunction(generated_body_closure, body); 3275 body = CloseAsyncFunction(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.IsAsyncClosure()) { 3277 } else if (func.IsAsyncClosure()) {
3257 body = CloseAsyncClosure(body); 3278 body = CloseAsyncClosure(body);
3258 } else if (func.IsSyncGenerator()) { 3279 } else if (func.IsSyncGenerator()) {
3259 body = CloseSyncGenFunction(generated_body_closure, body); 3280 body = CloseSyncGenFunction(generated_body_closure, body);
3260 generated_body_closure.set_end_token_pos(end_token_pos); 3281 generated_body_closure.set_end_token_pos(end_token_pos);
3261 } else if (func.IsSyncGenClosure()) { 3282 } else if (func.IsSyncGenClosure()) {
3262 body->scope()->RecursivelyCaptureAllVariables(); 3283 body->scope()->RecursivelyCaptureAllVariables();
3284 } else if (func.IsAsyncGenerator()) {
3285 body = CloseAsyncGeneratorFunction(generated_body_closure, body);
3286 generated_body_closure.set_end_token_pos(end_token_pos);
3287 } else if (func.IsAsyncGenClosure()) {
3288 body = CloseAsyncGeneratorClosure(body);
3263 } 3289 }
3264 current_block_->statements->Add(body); 3290 current_block_->statements->Add(body);
3265 innermost_function_ = saved_innermost_function.raw(); 3291 innermost_function_ = saved_innermost_function.raw();
3266 last_used_try_index_ = saved_try_index; 3292 last_used_try_index_ = saved_try_index;
3267 async_temp_scope_ = saved_async_temp_scope; 3293 async_temp_scope_ = saved_async_temp_scope;
3268 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx); 3294 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx);
3269 parsed_function()->set_async_saved_try_ctx_name( 3295 parsed_function()->set_async_saved_try_ctx_name(
3270 saved_async_saved_try_ctx_name); 3296 saved_async_saved_try_ctx_name);
3271 return CloseBlock(); 3297 return CloseBlock();
3272 } 3298 }
(...skipping 1980 matching lines...) Expand 10 before | Expand all | Expand 10 after
5253 ExpectSemicolon(); // Reports error. 5279 ExpectSemicolon(); // Reports error.
5254 } 5280 }
5255 } 5281 }
5256 } 5282 }
5257 5283
5258 5284
5259 RawFunction::AsyncModifier Parser::ParseFunctionModifier() { 5285 RawFunction::AsyncModifier Parser::ParseFunctionModifier() {
5260 if (CurrentLiteral()->raw() == Symbols::Async().raw()) { 5286 if (CurrentLiteral()->raw() == Symbols::Async().raw()) {
5261 ConsumeToken(); 5287 ConsumeToken();
5262 if (CurrentToken() == Token::kMUL) { 5288 if (CurrentToken() == Token::kMUL) {
5263 ReportError("async* generator functions are not yet supported"); 5289 const bool enableAsyncStar = true;
5290 if (!enableAsyncStar) {
5291 ReportError("async* generator functions are not yet supported");
5292 }
5264 ConsumeToken(); 5293 ConsumeToken();
5265 return RawFunction::kAsyncGen; 5294 return RawFunction::kAsyncGen;
5266 } else { 5295 } else {
5267 return RawFunction::kAsync; 5296 return RawFunction::kAsync;
5268 } 5297 }
5269 } else if ((CurrentLiteral()->raw() == Symbols::Sync().raw()) && 5298 } else if ((CurrentLiteral()->raw() == Symbols::Sync().raw()) &&
5270 (LookaheadToken(1) == Token::kMUL)) { 5299 (LookaheadToken(1) == Token::kMUL)) {
5271 const bool enableSyncStar = true; 5300 const bool enableSyncStar = true;
5272 if (!enableSyncStar) { 5301 if (!enableSyncStar) {
5273 ReportError("sync* generator functions are not yet supported"); 5302 ReportError("sync* generator functions are not yet supported");
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after
5944 5973
5945 void Parser::OpenAsyncClosure() { 5974 void Parser::OpenAsyncClosure() {
5946 TRACE_PARSER("OpenAsyncClosure"); 5975 TRACE_PARSER("OpenAsyncClosure");
5947 5976
5948 async_temp_scope_ = current_block_->scope; 5977 async_temp_scope_ = current_block_->scope;
5949 5978
5950 OpenAsyncTryBlock(); 5979 OpenAsyncTryBlock();
5951 } 5980 }
5952 5981
5953 5982
5954 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { 5983 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode *body) {
5984 TRACE_PARSER("CloseAsyncGeneratorTryBlock");
5985 // The generated try-catch-finally that wraps the async generator function
5986 // body is the outermost try statement.
5987 ASSERT(try_blocks_list_ != NULL);
5988 ASSERT(try_blocks_list_->outer_try_block() == NULL);
5989 // We only get here when parsing an async generator body.
5990 ASSERT(innermost_function().IsAsyncGenClosure());
5991
5992 const intptr_t try_end_pos = innermost_function().end_token_pos();
5993
5994 // The try-block (closure body code) has been parsed. We are now
5995 // generating the code for the catch block.
5955 try_blocks_list_->enter_catch(); 5996 try_blocks_list_->enter_catch();
5997 OpenBlock(); // Catch handler list.
5998 OpenBlock(); // Catch block.
5956 5999
5957 OpenBlock(); 6000 // Add the exception and stack trace parameters to the scope.
5958 OpenBlock();
5959 const AbstractType& dynamic_type = 6001 const AbstractType& dynamic_type =
5960 AbstractType::ZoneHandle(Z, Type::DynamicType()); 6002 AbstractType::ZoneHandle(Z, Type::DynamicType());
5961 CatchParamDesc exception_param; 6003 CatchParamDesc exception_param;
5962 CatchParamDesc stack_trace_param; 6004 CatchParamDesc stack_trace_param;
5963 exception_param.token_pos = Scanner::kNoSourcePos; 6005 exception_param.token_pos = Scanner::kNoSourcePos;
5964 exception_param.type = &dynamic_type; 6006 exception_param.type = &dynamic_type;
5965 exception_param.name = &Symbols::ExceptionParameter(); 6007 exception_param.name = &Symbols::ExceptionParameter();
5966 stack_trace_param.token_pos = Scanner::kNoSourcePos; 6008 stack_trace_param.token_pos = Scanner::kNoSourcePos;
5967 stack_trace_param.type = &dynamic_type; 6009 stack_trace_param.type = &dynamic_type;
5968 stack_trace_param.name = &Symbols::StackTraceParameter(); 6010 stack_trace_param.name = &Symbols::StackTraceParameter();
5969
5970 AddCatchParamsToScope( 6011 AddCatchParamsToScope(
5971 &exception_param, &stack_trace_param, current_block_->scope); 6012 &exception_param, &stack_trace_param, current_block_->scope);
5972 6013
6014 // Generate code to save the exception object and stack trace
6015 // in local variables.
5973 LocalVariable* context_var = current_block_->scope->LookupVariable( 6016 LocalVariable* context_var = current_block_->scope->LookupVariable(
5974 Symbols::SavedTryContextVar(), false); 6017 Symbols::SavedTryContextVar(), false);
5975 ASSERT(context_var != NULL); 6018 ASSERT(context_var != NULL);
5976 6019
5977 LocalVariable* exception_var = current_block_->scope->LookupVariable( 6020 LocalVariable* exception_var = current_block_->scope->LookupVariable(
5978 Symbols::ExceptionVar(), false); 6021 Symbols::ExceptionVar(), false);
5979 ASSERT(exception_var != NULL); 6022 ASSERT(exception_var != NULL);
5980 if (exception_param.var != NULL) { 6023 if (exception_param.var != NULL) {
5981 // Generate code to load the exception object (:exception_var) into 6024 // Generate code to load the exception object (:exception_var) into
5982 // the exception variable specified in this block. 6025 // the exception variable specified in this block.
(...skipping 12 matching lines...) Expand all
5995 // trace variable specified in this block. 6038 // trace variable specified in this block.
5996 current_block_->statements->Add(new(Z) StoreLocalNode( 6039 current_block_->statements->Add(new(Z) StoreLocalNode(
5997 Scanner::kNoSourcePos, 6040 Scanner::kNoSourcePos,
5998 stack_trace_param.var, 6041 stack_trace_param.var,
5999 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); 6042 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
6000 } 6043 }
6001 6044
6002 AddSavedExceptionAndStacktraceToScope( 6045 AddSavedExceptionAndStacktraceToScope(
6003 exception_var, stack_trace_var, current_block_->scope); 6046 exception_var, stack_trace_var, current_block_->scope);
6004 6047
6048 parsed_function()->reset_saved_try_ctx_vars();
6049
6050 // Catch block: add the error to the stream.
6051 // :controller.AddError(:exception, :stack_trace);
6052 // return; // The finally block will close the stream.
6053 LocalVariable* controller =
6054 current_block_->scope->LookupVariable(Symbols::Controller(), false);
6055 ASSERT(controller != NULL);
6056 ArgumentListNode* args =
6057 new(Z) ArgumentListNode(Scanner::kNoSourcePos);
6058 args->Add(new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var));
6059 args->Add(new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var));
6060 current_block_->statements->Add(
6061 new(Z) InstanceCallNode(try_end_pos,
6062 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller),
6063 Symbols::AddError(),
6064 args));
6065 ReturnNode* return_node = new(Z) ReturnNode(Scanner::kNoSourcePos);
6066 current_block_->statements->Add(return_node);
6067 AstNode* catch_block = CloseBlock();
6068 current_block_->statements->Add(catch_block);
6069 SequenceNode* catch_handler_list = CloseBlock();
6070
6071 TryBlocks* try_block = PopTryBlock();
6072 ASSERT(try_blocks_list_ == NULL); // We popped the outermost try block.
6073
6074 // Finally block: closing the stream and returning. (Note: the return
6075 // is necessary otherwise the back-end will append a rethrow of the
6076 // current exception.)
6077 // :controller.close();
6078 // return;
6079 // We need to inline this code in all recorded exit points.
6080 intptr_t node_index = 0;
6081 SequenceNode* finally_clause = NULL;
6082 do {
6083 OpenBlock();
6084 ArgumentListNode* no_args =
6085 new(Z) ArgumentListNode(Scanner::kNoSourcePos);
6086 current_block_->statements->Add(
6087 new(Z) InstanceCallNode(try_end_pos,
6088 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller),
6089 Symbols::Close(),
6090 no_args));
6091
6092 ReturnNode* return_node = new(Z) ReturnNode(Scanner::kNoSourcePos);
6093 current_block_->statements->Add(return_node);
6094
6095 finally_clause = CloseBlock();
6096 AstNode* node_to_inline = try_block->GetNodeToInlineFinally(node_index);
6097 if (node_to_inline != NULL) {
6098 InlinedFinallyNode* node =
6099 new(Z) InlinedFinallyNode(try_end_pos,
6100 finally_clause,
6101 context_var,
6102 // No outer try statement
6103 CatchClauseNode::kInvalidTryIndex);
6104 finally_clause = NULL;
6105 AddFinallyBlockToNode(node_to_inline, node);
6106 node_index++;
6107 }
6108 } while (finally_clause == NULL);
6109
6110 const GrowableObjectArray& handler_types =
6111 GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
6112 handler_types.Add(dynamic_type); // Catch block handles all exceptions.
6113
6114 CatchClauseNode* catch_clause = new(Z) CatchClauseNode(
6115 Scanner::kNoSourcePos,
6116 catch_handler_list,
6117 Array::ZoneHandle(Z, Array::MakeArray(handler_types)),
6118 context_var,
6119 exception_var,
6120 stack_trace_var,
6121 AllocateTryIndex(),
6122 true);
6123
6124 const intptr_t try_index = try_block->try_index();
6125
6126 AstNode* try_catch_node =
6127 new(Z) TryCatchNode(Scanner::kNoSourcePos,
6128 body,
6129 context_var,
6130 catch_clause,
6131 finally_clause,
6132 try_index);
6133 current_block_->statements->Add(try_catch_node);
6134 return CloseBlock();
6135 }
6136
6137
6138 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) {
6139 // This is the outermost try-catch of the function.
6005 ASSERT(try_blocks_list_ != NULL); 6140 ASSERT(try_blocks_list_ != NULL);
6006 ASSERT(innermost_function().IsAsyncClosure() || 6141 ASSERT(try_blocks_list_->outer_try_block() == NULL);
6007 innermost_function().IsAsyncFunction()); 6142 ASSERT(innermost_function().IsAsyncClosure());
6008 if ((try_blocks_list_->outer_try_block() != NULL) && 6143
6009 (try_blocks_list_->outer_try_block()->try_block() 6144 try_blocks_list_->enter_catch();
6010 ->scope->function_level() == 6145
6011 current_block_->scope->function_level())) { 6146 OpenBlock(); // Catch handler list.
6012 // We need to unchain three scope levels: catch clause, catch 6147 OpenBlock(); // Catch block.
6013 // parameters, and the general try block. 6148 const AbstractType& dynamic_type =
6014 RestoreSavedTryContext( 6149 AbstractType::ZoneHandle(Z, Type::DynamicType());
6015 current_block_->scope->parent()->parent()->parent(), 6150 CatchParamDesc exception_param;
6016 try_blocks_list_->outer_try_block()->try_index(), 6151 CatchParamDesc stack_trace_param;
6017 current_block_->statements); 6152 exception_param.token_pos = Scanner::kNoSourcePos;
6018 } else { 6153 exception_param.type = &dynamic_type;
6019 parsed_function()->reset_saved_try_ctx_vars(); 6154 exception_param.name = &Symbols::ExceptionParameter();
6155 stack_trace_param.token_pos = Scanner::kNoSourcePos;
6156 stack_trace_param.type = &dynamic_type;
6157 stack_trace_param.name = &Symbols::StackTraceParameter();
6158
6159 AddCatchParamsToScope(
6160 &exception_param, &stack_trace_param, current_block_->scope);
6161
6162 LocalVariable* context_var = current_block_->scope->LookupVariable(
6163 Symbols::SavedTryContextVar(), false);
6164 ASSERT(context_var != NULL);
6165 LocalVariable* exception_var = current_block_->scope->LookupVariable(
6166 Symbols::ExceptionVar(), false);
6167 if (exception_param.var != NULL) {
6168 // Generate code to load the exception object (:exception_var) into
6169 // the exception variable specified in this block.
6170 ASSERT(exception_var != NULL);
6171 current_block_->statements->Add(new(Z) StoreLocalNode(
6172 Scanner::kNoSourcePos,
6173 exception_param.var,
6174 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var)));
6175 }
6176 LocalVariable* stack_trace_var =
6177 current_block_->scope->LookupVariable(Symbols::StackTraceVar(), false);
6178 if (stack_trace_param.var != NULL) {
6179 // A stack trace variable is specified in this block, so generate code
6180 // to load the stack trace object (:stack_trace_var) into the stack
6181 // trace variable specified in this block.
6182 ASSERT(stack_trace_var != NULL);
6183 current_block_->statements->Add(new(Z) StoreLocalNode(
6184 Scanner::kNoSourcePos,
6185 stack_trace_param.var,
6186 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
6020 } 6187 }
6021 6188
6022 // Complete the async future with an error. 6189 AddSavedExceptionAndStacktraceToScope(
6023 // Since we control the catch block there is no need to generate a nested 6190 exception_var, stack_trace_var, current_block_->scope);
6024 // if/then/else. 6191
6192 parsed_function()->reset_saved_try_ctx_vars();
6193
6194 // Complete the async future with an error. This catch block executes
6195 // unconditionally, there is no need to generate a type check for.
6025 LocalVariable* async_completer = current_block_->scope->LookupVariable( 6196 LocalVariable* async_completer = current_block_->scope->LookupVariable(
6026 Symbols::AsyncCompleter(), false); 6197 Symbols::AsyncCompleter(), false);
6027 ASSERT(async_completer != NULL); 6198 ASSERT(async_completer != NULL);
6028 ArgumentListNode* completer_args = 6199 ArgumentListNode* completer_args =
6029 new (Z) ArgumentListNode(Scanner::kNoSourcePos); 6200 new (Z) ArgumentListNode(Scanner::kNoSourcePos);
6030 completer_args->Add( 6201 completer_args->Add(
6031 new (Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var)); 6202 new (Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var));
6032 completer_args->Add( 6203 completer_args->Add(
6033 new (Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var)); 6204 new (Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var));
6034 current_block_->statements->Add(new (Z) InstanceCallNode( 6205 current_block_->statements->Add(new (Z) InstanceCallNode(
(...skipping 24 matching lines...) Expand all
6059 context_var, 6230 context_var,
6060 exception_var, 6231 exception_var,
6061 stack_trace_var, 6232 stack_trace_var,
6062 CatchClauseNode::kInvalidTryIndex, 6233 CatchClauseNode::kInvalidTryIndex,
6063 true); 6234 true);
6064 AstNode* try_catch_node = new (Z) TryCatchNode( 6235 AstNode* try_catch_node = new (Z) TryCatchNode(
6065 Scanner::kNoSourcePos, 6236 Scanner::kNoSourcePos,
6066 try_block, 6237 try_block,
6067 context_var, 6238 context_var,
6068 catch_clause, 6239 catch_clause,
6069 NULL, 6240 NULL, // No finally clause.
6070 try_index); 6241 try_index);
6071 current_block_->statements->Add(try_catch_node); 6242 current_block_->statements->Add(try_catch_node);
6072 return CloseBlock(); 6243 return CloseBlock();
6073 } 6244 }
6074 6245
6075 6246
6247 // Wrap the body of the async or arync* closure in a try/catch block.
6076 void Parser::OpenAsyncTryBlock() { 6248 void Parser::OpenAsyncTryBlock() {
6077 // Manually wrapping the actual body into a try/catch block. 6249 ASSERT(innermost_function().IsAsyncClosure() ||
6250 innermost_function().IsAsyncGenClosure());
6251
6078 LocalVariable* context_var = 6252 LocalVariable* context_var =
6079 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); 6253 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar());
6080 if (context_var == NULL) { 6254 if (context_var == NULL) {
6081 context_var = new(Z) LocalVariable( 6255 context_var = new(Z) LocalVariable(
6082 TokenPos(), 6256 TokenPos(),
6083 Symbols::SavedTryContextVar(), 6257 Symbols::SavedTryContextVar(),
6084 Type::ZoneHandle(Z, Type::DynamicType())); 6258 Type::ZoneHandle(Z, Type::DynamicType()));
6085 current_block_->scope->AddVariable(context_var); 6259 current_block_->scope->AddVariable(context_var);
6086 } 6260 }
6087 LocalVariable* exception_var = 6261 LocalVariable* exception_var =
(...skipping 10 matching lines...) Expand all
6098 if (stack_trace_var == NULL) { 6272 if (stack_trace_var == NULL) {
6099 stack_trace_var = new(Z) LocalVariable( 6273 stack_trace_var = new(Z) LocalVariable(
6100 TokenPos(), 6274 TokenPos(),
6101 Symbols::StackTraceVar(), 6275 Symbols::StackTraceVar(),
6102 Type::ZoneHandle(Z, Type::DynamicType())); 6276 Type::ZoneHandle(Z, Type::DynamicType()));
6103 current_block_->scope->AddVariable(stack_trace_var); 6277 current_block_->scope->AddVariable(stack_trace_var);
6104 } 6278 }
6105 6279
6106 // Open the try block. 6280 // Open the try block.
6107 OpenBlock(); 6281 OpenBlock();
6282 // This is the outermost try-catch in the function.
6283 ASSERT(try_blocks_list_ == NULL);
6108 PushTryBlock(current_block_); 6284 PushTryBlock(current_block_);
6109 6285
6110 if (innermost_function().IsAsyncClosure() || 6286 SetupSavedTryContext(context_var);
6111 innermost_function().IsAsyncFunction() ||
6112 innermost_function().IsSyncGenClosure() ||
6113 innermost_function().IsSyncGenerator()) {
6114 SetupSavedTryContext(context_var);
6115 }
6116 } 6287 }
6117 6288
6118 6289
6119 void Parser::AddSyncGenClosureParameters(ParamList* params) { 6290 void Parser::AddSyncGenClosureParameters(ParamList* params) {
6120 // Create the parameter list for the body closure of a sync generator: 6291 // Create the parameter list for the body closure of a sync generator:
6121 // 1) Implicit closure parameter; 6292 // 1) Implicit closure parameter;
6122 // 2) Iterator 6293 // 2) Iterator
6123 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); 6294 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6124 // Add implicit closure parameter if not already present. 6295 // Add implicit closure parameter if not already present.
6125 if (params->parameters->length() == 0) { 6296 if (params->parameters->length() == 0) {
6126 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type); 6297 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type);
6127 } 6298 }
6128 ParamDesc iterator_param; 6299 ParamDesc iterator_param;
6129 iterator_param.name = &Symbols::IteratorParameter(); 6300 iterator_param.name = &Symbols::IteratorParameter();
6130 iterator_param.type = &dynamic_type; 6301 iterator_param.type = &dynamic_type;
6131 params->parameters->Add(iterator_param); 6302 params->parameters->Add(iterator_param);
6132 params->num_fixed_parameters++; 6303 params->num_fixed_parameters++;
6133 } 6304 }
6134 6305
6135 6306
6307 void Parser::AddAsyncGenClosureParameters(ParamList* params) {
6308 // Create the parameter list for the body closure of an async generator:
6309 // The closure has the same parameters as an asynchronous non-generator.
6310 AddAsyncClosureParameters(params);
6311 }
6312
6313
6136 RawFunction* Parser::OpenSyncGeneratorFunction(intptr_t func_pos) { 6314 RawFunction* Parser::OpenSyncGeneratorFunction(intptr_t func_pos) {
6137 Function& body = Function::Handle(Z); 6315 Function& body = Function::Handle(Z);
6138 String& body_closure_name = String::Handle(Z); 6316 String& body_closure_name = String::Handle(Z);
6139 bool is_new_closure = false; 6317 bool is_new_closure = false;
6140 6318
6141 AddContinuationVariables(); 6319 AddContinuationVariables();
6142 6320
6143 // Check whether a function for the body of this generator 6321 // Check whether a function for the body of this generator
6144 // function has already been created by a previous 6322 // function has already been created by a previous
6145 // compilation. 6323 // compilation.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
6236 iterable_constructor, 6414 iterable_constructor,
6237 arguments); 6415 arguments);
6238 ReturnNode* return_node = 6416 ReturnNode* return_node =
6239 new (Z) ReturnNode(Scanner::kNoSourcePos, new_iterable); 6417 new (Z) ReturnNode(Scanner::kNoSourcePos, new_iterable);
6240 current_block_->statements->Add(return_node); 6418 current_block_->statements->Add(return_node);
6241 return CloseBlock(); 6419 return CloseBlock();
6242 } 6420 }
6243 6421
6244 6422
6245 void Parser::AddAsyncClosureParameters(ParamList* params) { 6423 void Parser::AddAsyncClosureParameters(ParamList* params) {
6246 // Async closures have two optional parameters: 6424 // Async closures have three optional parameters:
6247 // * A continuation result. 6425 // * A continuation result.
6248 // * A continuation error. 6426 // * A continuation error.
6249 // * A continuation stack trace. 6427 // * A continuation stack trace.
6250 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); 6428 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6251 // Add implicit closure parameter if not yet present. 6429 // Add implicit closure parameter if not yet present.
6252 if (params->parameters->length() == 0) { 6430 if (params->parameters->length() == 0) {
6253 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type); 6431 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type);
6254 } 6432 }
6255 ParamDesc result_param; 6433 ParamDesc result_param;
6256 result_param.name = &Symbols::AsyncOperationParam(); 6434 result_param.name = &Symbols::AsyncOperationParam();
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
6365 current_block_->scope->CaptureVariable(Symbols::AsyncOperation()); 6543 current_block_->scope->CaptureVariable(Symbols::AsyncOperation());
6366 async_op_var->set_is_captured(); 6544 async_op_var->set_is_captured();
6367 LocalVariable* async_completer = new(Z) LocalVariable( 6545 LocalVariable* async_completer = new(Z) LocalVariable(
6368 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type); 6546 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type);
6369 current_block_->scope->AddVariable(async_completer); 6547 current_block_->scope->AddVariable(async_completer);
6370 current_block_->scope->CaptureVariable(Symbols::AsyncCompleter()); 6548 current_block_->scope->CaptureVariable(Symbols::AsyncCompleter());
6371 async_completer->set_is_captured(); 6549 async_completer->set_is_captured();
6372 } 6550 }
6373 6551
6374 6552
6553 void Parser::AddAsyncGeneratorVariables() {
6554 // Add to current block's scope:
6555 // var :controller;
6556 // This variable is used by the nested async generator closure to
6557 // store the StreamController object to which the yielded expressions
6558 // are added.
6559 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6560 LocalVariable* controller_var = new(Z) LocalVariable(
6561 Scanner::kNoSourcePos, Symbols::Controller(), dynamic_type);
6562 current_block_->scope->AddVariable(controller_var);
6563 current_block_->scope->CaptureVariable(Symbols::Controller());
6564 controller_var->set_is_captured();
6565
6566 LocalVariable* async_op_var = new(Z) LocalVariable(
6567 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
6568 current_block_->scope->AddVariable(async_op_var);
6569 current_block_->scope->CaptureVariable(Symbols::AsyncOperation());
6570 async_op_var->set_is_captured();
6571 }
6572
6573
6574 RawFunction* Parser::OpenAsyncGeneratorFunction(intptr_t async_func_pos) {
6575 TRACE_PARSER("OpenAsyncGeneratorFunction");
6576 AddContinuationVariables();
6577 AddAsyncGeneratorVariables();
6578
6579 Function& closure = Function::Handle(Z);
6580 bool is_new_closure = false;
6581
6582 // Check whether a function for the asynchronous function body of
6583 // this async generator has already been created by a previous
6584 // compilation of this function.
6585 const Function& found_func = Function::Handle(
6586 Z, current_class().LookupClosureFunction(async_func_pos));
6587 if (!found_func.IsNull() &&
6588 (found_func.token_pos() == async_func_pos) &&
6589 (found_func.script() == innermost_function().script()) &&
6590 (found_func.parent_function() == innermost_function().raw())) {
6591 ASSERT(found_func.IsAsyncGenClosure());
6592 closure = found_func.raw();
6593 } else {
6594 // Create the closure containing the body of this async generator function.
6595 const String& async_generator_name =
6596 String::Handle(Z, innermost_function().name());
6597 String& closure_name = String::Handle(Z,
6598 String::NewFormatted("<%s_async_gen_body>",
6599 async_generator_name.ToCString()));
6600 closure = Function::NewClosureFunction(
6601 String::Handle(Z, Symbols::New(closure_name)),
6602 innermost_function(),
6603 async_func_pos);
6604 closure.set_is_generated_body(true);
6605 closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
6606 is_new_closure = true;
6607 }
6608
6609 ParamList closure_params;
6610 AddAsyncGenClosureParameters(&closure_params);
6611
6612 if (is_new_closure) {
6613 // Add the parameters to the newly created closure.
6614 AddFormalParamsToFunction(&closure_params, closure);
6615
6616 // Create and set the signature class of the closure.
6617 const String& sig = String::Handle(Z, closure.Signature());
6618 Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig));
6619 if (sig_cls.IsNull()) {
6620 sig_cls =
6621 Class::NewSignatureClass(sig, closure, script_, closure.token_pos());
6622 library_.AddClass(sig_cls);
6623 }
6624 closure.set_signature_class(sig_cls);
6625 const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType());
6626 if (!sig_type.IsFinalized()) {
6627 ClassFinalizer::FinalizeType(
6628 sig_cls, sig_type, ClassFinalizer::kCanonicalize);
6629 }
6630 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved());
6631 ASSERT(closure.NumParameters() == closure_params.parameters->length());
6632 }
6633
6634 OpenFunctionBlock(closure);
6635 AddFormalParamsToScope(&closure_params, current_block_->scope);
6636 OpenBlock();
6637 async_temp_scope_ = current_block_->scope;
6638 return closure.raw();
6639 }
6640
6641
6642 // Generate the Ast nodes for the implicit code of the async* function.
6643 //
6644 // f(...) async* {
6645 // var :controller;
6646 // var :await_jump_var = -1;
6647 // var :await_context_var;
6648 // f_async_body() {
6649 // ... source code of f ...
6650 // }
6651 // :controller = new _AsyncStarStreamController(f_async_body);
6652 // return :controller.stream;
6653 // }
6654 SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure,
6655 SequenceNode* closure_body) {
6656 TRACE_PARSER("CloseAsyncGeneratorFunction");
6657 ASSERT(!closure.IsNull());
6658 ASSERT(closure_body != NULL);
6659
6660 // The block for the async closure body has already been closed. Close the
6661 // corresponding function block.
6662 CloseBlock();
6663
6664 // Make sure the implicit variables of the async generator function
6665 // are captured.
6666 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
6667 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
6668 closure_body->scope()->LookupVariable(Symbols::Controller(), false);
6669
6670 const Class& controller_class = Class::Handle(Z,
6671 Library::LookupCoreClass(Symbols::_AsyncStarStreamController()));
6672 ASSERT(!controller_class.IsNull());
6673 const Function& controller_constructor = Function::ZoneHandle(Z,
6674 controller_class.LookupConstructorAllowPrivate(
6675 Symbols::_AsyncStarStreamControllerConstructor()));
6676
6677 // :await_jump_var = -1;
6678 LocalVariable* jump_var =
6679 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false);
6680 LiteralNode* init_value =
6681 new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1)));
6682 current_block_->statements->Add(
6683 new(Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value));
6684
6685 // Add to AST:
6686 // :async_op = <closure>; (containing the original body)
6687 LocalVariable* async_op_var =
6688 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false);
6689 ClosureNode* cn = new(Z) ClosureNode(
6690 Scanner::kNoSourcePos, closure, NULL, closure_body->scope());
6691 StoreLocalNode* store_async_op = new (Z) StoreLocalNode(
6692 Scanner::kNoSourcePos,
6693 async_op_var,
6694 cn);
6695 current_block_->statements->Add(store_async_op);
6696
6697 // :controller = new _AsyncStarStreamController(body_closure);
6698 ArgumentListNode* arguments = new(Z) ArgumentListNode(Scanner::kNoSourcePos);
6699 ClosureNode* closure_obj = new(Z) ClosureNode(
6700 Scanner::kNoSourcePos, closure, NULL, closure_body->scope());
6701 arguments->Add(closure_obj);
6702 ConstructorCallNode* controller_constructor_call =
6703 new(Z) ConstructorCallNode(Scanner::kNoSourcePos,
6704 TypeArguments::ZoneHandle(Z),
6705 controller_constructor,
6706 arguments);
6707 LocalVariable* controller_var =
6708 current_block_->scope->LookupVariable(Symbols::Controller(), false);
6709 StoreLocalNode* store_controller =
6710 new(Z) StoreLocalNode(Scanner::kNoSourcePos,
6711 controller_var,
6712 controller_constructor_call);
6713 current_block_->statements->Add(store_controller);
6714
6715 // return :controller.stream;
6716 ReturnNode* return_node = new(Z) ReturnNode(Scanner::kNoSourcePos,
6717 new(Z) InstanceGetterNode(Scanner::kNoSourcePos,
6718 new(Z) LoadLocalNode(Scanner::kNoSourcePos,
6719 controller_var),
6720 Symbols::Stream()));
6721 current_block_->statements->Add(return_node);
6722 return CloseBlock();
6723 }
6724
6725
6726 void Parser::OpenAsyncGeneratorClosure() {
6727 async_temp_scope_ = current_block_->scope;
6728 OpenAsyncTryBlock();
6729 }
6730
6731
6732 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) {
6733 // TODO(hausner): Is the temporary expression necessary?
6734 // We need a temporary expression to store intermediate return values.
6735 parsed_function()->EnsureExpressionTemp();
6736
6737 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body);
6738 ASSERT(new_body != NULL);
6739 ASSERT(new_body->scope() != NULL);
6740
6741 // Implicitly mark those variables below as captured. We currently mark all
6742 // variables of all scopes as captured, but as soon as we do something
6743 // smarter we rely on these internal variables to be available.
6744 new_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
6745 new_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
6746 new_body->scope()->LookupVariable(Symbols::Controller(), false);
6747 new_body->scope()->LookupVariable(Symbols::AsyncOperationParam(), false);
6748 new_body->scope()->LookupVariable(Symbols::AsyncOperationErrorParam(), false);
6749 new_body->scope()->LookupVariable(
6750 Symbols::AsyncOperationStackTraceParam(), false);
6751 new_body->scope()->RecursivelyCaptureAllVariables();
6752 return new_body;
6753 }
6754
6755
6375 SequenceNode* Parser::CloseBlock() { 6756 SequenceNode* Parser::CloseBlock() {
6376 SequenceNode* statements = current_block_->statements; 6757 SequenceNode* statements = current_block_->statements;
6377 if (current_block_->scope != NULL) { 6758 if (current_block_->scope != NULL) {
6378 // Record the begin and end token index of the scope. 6759 // Record the begin and end token index of the scope.
6379 ASSERT(statements != NULL); 6760 ASSERT(statements != NULL);
6380 current_block_->scope->set_begin_token_pos(statements->token_pos()); 6761 current_block_->scope->set_begin_token_pos(statements->token_pos());
6381 current_block_->scope->set_end_token_pos(TokenPos()); 6762 current_block_->scope->set_end_token_pos(TokenPos());
6382 } 6763 }
6383 current_block_ = current_block_->parent; 6764 current_block_ = current_block_->parent;
6384 return statements; 6765 return statements;
(...skipping 1395 matching lines...) Expand 10 before | Expand all | Expand 10 after
7780 AstNode* Parser::ParseAwaitForStatement(String* label_name) { 8161 AstNode* Parser::ParseAwaitForStatement(String* label_name) {
7781 TRACE_PARSER("ParseAwaitForStatement"); 8162 TRACE_PARSER("ParseAwaitForStatement");
7782 ASSERT(IsAwaitKeyword()); 8163 ASSERT(IsAwaitKeyword());
7783 const intptr_t await_for_pos = TokenPos(); 8164 const intptr_t await_for_pos = TokenPos();
7784 ConsumeToken(); // await. 8165 ConsumeToken(); // await.
7785 ASSERT(CurrentToken() == Token::kFOR); 8166 ASSERT(CurrentToken() == Token::kFOR);
7786 ConsumeToken(); // for. 8167 ConsumeToken(); // for.
7787 ExpectToken(Token::kLPAREN); 8168 ExpectToken(Token::kLPAREN);
7788 8169
7789 if (!innermost_function().IsAsyncFunction() && 8170 if (!innermost_function().IsAsyncFunction() &&
7790 !innermost_function().IsAsyncClosure()) { 8171 !innermost_function().IsAsyncClosure() &&
8172 !innermost_function().IsAsyncGenerator() &&
8173 !innermost_function().IsAsyncGenClosure()) {
7791 ReportError(await_for_pos, 8174 ReportError(await_for_pos,
7792 "await for loop is only allowed in async function"); 8175 "await for loop is only allowed in an asynchronous function");
7793 } 8176 }
7794 8177
7795 // Parse loop variable. 8178 // Parse loop variable.
7796 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); 8179 bool loop_var_is_final = (CurrentToken() == Token::kFINAL);
7797 if (CurrentToken() == Token::kCONST) { 8180 if (CurrentToken() == Token::kCONST) {
7798 ReportError("Loop variable cannot be 'const'"); 8181 ReportError("Loop variable cannot be 'const'");
7799 } 8182 }
7800 bool new_loop_var = false; 8183 bool new_loop_var = false;
7801 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); 8184 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z);
7802 if (LookaheadToken(1) != Token::kIN) { 8185 if (LookaheadToken(1) != Token::kIN) {
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
8220 8603
8221 // Populate local scope of the catch block with the saved exception and saved 8604 // Populate local scope of the catch block with the saved exception and saved
8222 // stack trace. 8605 // stack trace.
8223 void Parser::AddSavedExceptionAndStacktraceToScope( 8606 void Parser::AddSavedExceptionAndStacktraceToScope(
8224 LocalVariable* exception_var, 8607 LocalVariable* exception_var,
8225 LocalVariable* stack_trace_var, 8608 LocalVariable* stack_trace_var,
8226 LocalScope* scope) { 8609 LocalScope* scope) {
8227 ASSERT(innermost_function().IsAsyncClosure() || 8610 ASSERT(innermost_function().IsAsyncClosure() ||
8228 innermost_function().IsAsyncFunction() || 8611 innermost_function().IsAsyncFunction() ||
8229 innermost_function().IsSyncGenClosure() || 8612 innermost_function().IsSyncGenClosure() ||
8230 innermost_function().IsSyncGenerator()); 8613 innermost_function().IsSyncGenerator() ||
8614 innermost_function().IsAsyncGenerator() ||
8615 innermost_function().IsAsyncGenClosure());
8231 // Add :saved_exception_var and :saved_stack_trace_var to scope. 8616 // Add :saved_exception_var and :saved_stack_trace_var to scope.
8232 // They will automatically get captured. 8617 // They will automatically get captured.
8233 LocalVariable* saved_exception_var = new (Z) LocalVariable( 8618 LocalVariable* saved_exception_var = new (Z) LocalVariable(
8234 Scanner::kNoSourcePos, 8619 Scanner::kNoSourcePos,
8235 Symbols::SavedExceptionVar(), 8620 Symbols::SavedExceptionVar(),
8236 Type::ZoneHandle(Z, Type::DynamicType())); 8621 Type::ZoneHandle(Z, Type::DynamicType()));
8237 saved_exception_var->set_is_final(); 8622 saved_exception_var->set_is_final();
8238 scope->AddVariable(saved_exception_var); 8623 scope->AddVariable(saved_exception_var);
8239 LocalVariable* saved_stack_trace_var = new (Z) LocalVariable( 8624 LocalVariable* saved_stack_trace_var = new (Z) LocalVariable(
8240 Scanner::kNoSourcePos, 8625 Scanner::kNoSourcePos,
(...skipping 30 matching lines...) Expand all
8271 TRACE_PARSER("ParseFinallyBlock"); 8656 TRACE_PARSER("ParseFinallyBlock");
8272 OpenBlock(); 8657 OpenBlock();
8273 ExpectToken(Token::kLBRACE); 8658 ExpectToken(Token::kLBRACE);
8274 8659
8275 // In case of async closures we need to restore the saved try index of an 8660 // In case of async closures we need to restore the saved try index of an
8276 // outer try block (if it exists). The current try block has already been 8661 // outer try block (if it exists). The current try block has already been
8277 // removed from the stack of try blocks. 8662 // removed from the stack of try blocks.
8278 if ((innermost_function().IsAsyncClosure() || 8663 if ((innermost_function().IsAsyncClosure() ||
8279 innermost_function().IsAsyncFunction() || 8664 innermost_function().IsAsyncFunction() ||
8280 innermost_function().IsSyncGenClosure() || 8665 innermost_function().IsSyncGenClosure() ||
8281 innermost_function().IsSyncGenerator()) && 8666 innermost_function().IsSyncGenerator() ||
8667 innermost_function().IsAsyncGenerator() ||
8668 innermost_function().IsAsyncGenClosure()) &&
8282 (try_blocks_list_ != NULL)) { 8669 (try_blocks_list_ != NULL)) {
8283 // We need two unchain two scopes: finally clause, and the try block level. 8670 // We need two unchain two scopes: finally clause, and the try block level.
8284 RestoreSavedTryContext(current_block_->scope->parent()->parent(), 8671 RestoreSavedTryContext(current_block_->scope->parent()->parent(),
8285 try_blocks_list_->try_index(), 8672 try_blocks_list_->try_index(),
8286 current_block_->statements); 8673 current_block_->statements);
8287 } else { 8674 } else {
8288 parsed_function()->reset_saved_try_ctx_vars(); 8675 parsed_function()->reset_saved_try_ctx_vars();
8289 } 8676 }
8290 8677
8291 ParseStatementSequence(); 8678 ParseStatementSequence();
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
8380 } else { 8767 } else {
8381 exception_param.type = &AbstractType::ZoneHandle(Z, Type::DynamicType()); 8768 exception_param.type = &AbstractType::ZoneHandle(Z, Type::DynamicType());
8382 } 8769 }
8383 if (CurrentToken() == Token::kCATCH) { 8770 if (CurrentToken() == Token::kCATCH) {
8384 ConsumeToken(); // Consume the 'catch'. 8771 ConsumeToken(); // Consume the 'catch'.
8385 ExpectToken(Token::kLPAREN); 8772 ExpectToken(Token::kLPAREN);
8386 exception_param.token_pos = TokenPos(); 8773 exception_param.token_pos = TokenPos();
8387 exception_param.name = ExpectIdentifier("identifier expected"); 8774 exception_param.name = ExpectIdentifier("identifier expected");
8388 if (CurrentToken() == Token::kCOMMA) { 8775 if (CurrentToken() == Token::kCOMMA) {
8389 ConsumeToken(); 8776 ConsumeToken();
8390 // TODO(hausner): Make implicit type be StackTrace, not dynamic.
8391 stack_trace_param.type = 8777 stack_trace_param.type =
8392 &AbstractType::ZoneHandle(Z, Type::DynamicType()); 8778 &AbstractType::ZoneHandle(Z, Type::DynamicType());
8393 stack_trace_param.token_pos = TokenPos(); 8779 stack_trace_param.token_pos = TokenPos();
8394 stack_trace_param.name = ExpectIdentifier("identifier expected"); 8780 stack_trace_param.name = ExpectIdentifier("identifier expected");
8395 } 8781 }
8396 ExpectToken(Token::kRPAREN); 8782 ExpectToken(Token::kRPAREN);
8397 } 8783 }
8398 8784
8399 // Create a block containing the catch clause parameters and the 8785 // Create a block containing the catch clause parameters and the
8400 // following code: 8786 // following code:
(...skipping 18 matching lines...) Expand all
8419 // A stack trace variable is specified in this block, so generate code 8805 // A stack trace variable is specified in this block, so generate code
8420 // to load the stack trace object (:stack_trace_var) into the stack 8806 // to load the stack trace object (:stack_trace_var) into the stack
8421 // trace variable specified in this block. 8807 // trace variable specified in this block.
8422 *needs_stack_trace = true; 8808 *needs_stack_trace = true;
8423 ASSERT(stack_trace_var != NULL); 8809 ASSERT(stack_trace_var != NULL);
8424 current_block_->statements->Add(new(Z) StoreLocalNode( 8810 current_block_->statements->Add(new(Z) StoreLocalNode(
8425 catch_pos, stack_trace_param.var, new(Z) LoadLocalNode( 8811 catch_pos, stack_trace_param.var, new(Z) LoadLocalNode(
8426 catch_pos, stack_trace_var))); 8812 catch_pos, stack_trace_var)));
8427 } 8813 }
8428 8814
8429 // Add nested block with user-defined code. This blocks allows 8815 // Add nested block with user-defined code. This block allows
8430 // declarations in the body to shadow the catch parameters. 8816 // declarations in the body to shadow the catch parameters.
8431 CheckToken(Token::kLBRACE); 8817 CheckToken(Token::kLBRACE);
8432 8818
8433 // In case of async closures we need to restore the saved try index of an 8819 // In case of async closures we need to restore the saved try index of an
8434 // outer try block (if it exists). 8820 // outer try block (if it exists).
8435 ASSERT(try_blocks_list_ != NULL); 8821 ASSERT(try_blocks_list_ != NULL);
8436 if (innermost_function().IsAsyncClosure() || 8822 if (innermost_function().IsAsyncClosure() ||
8437 innermost_function().IsAsyncFunction() || 8823 innermost_function().IsAsyncFunction() ||
8438 innermost_function().IsSyncGenClosure() || 8824 innermost_function().IsSyncGenClosure() ||
8439 innermost_function().IsSyncGenerator()) { 8825 innermost_function().IsSyncGenerator() ||
8826 innermost_function().IsAsyncGenerator() ||
8827 innermost_function().IsAsyncGenClosure()) {
8440 if ((try_blocks_list_->outer_try_block() != NULL) && 8828 if ((try_blocks_list_->outer_try_block() != NULL) &&
8441 (try_blocks_list_->outer_try_block()->try_block() 8829 (try_blocks_list_->outer_try_block()->try_block()
8442 ->scope->function_level() == 8830 ->scope->function_level() ==
8443 current_block_->scope->function_level())) { 8831 current_block_->scope->function_level())) {
8444 // We need to unchain three scope levels: catch clause, catch 8832 // We need to unchain three scope levels: catch clause, catch
8445 // parameters, and the general try block. 8833 // parameters, and the general try block.
8446 RestoreSavedTryContext( 8834 RestoreSavedTryContext(
8447 current_block_->scope->parent()->parent()->parent(), 8835 current_block_->scope->parent()->parent()->parent(),
8448 try_blocks_list_->outer_try_block()->try_index(), 8836 try_blocks_list_->outer_try_block()->try_index(),
8449 current_block_->statements); 8837 current_block_->statements);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
8541 while (!type_tests.is_empty()) { 8929 while (!type_tests.is_empty()) {
8542 AstNode* type_test = type_tests.RemoveLast(); 8930 AstNode* type_test = type_tests.RemoveLast();
8543 SequenceNode* catch_block = catch_blocks.RemoveLast(); 8931 SequenceNode* catch_block = catch_blocks.RemoveLast();
8544 8932
8545 // In case of async closures we need to restore the saved try index of an 8933 // In case of async closures we need to restore the saved try index of an
8546 // outer try block (if it exists). 8934 // outer try block (if it exists).
8547 ASSERT(try_blocks_list_ != NULL); 8935 ASSERT(try_blocks_list_ != NULL);
8548 if (innermost_function().IsAsyncClosure() || 8936 if (innermost_function().IsAsyncClosure() ||
8549 innermost_function().IsAsyncFunction() || 8937 innermost_function().IsAsyncFunction() ||
8550 innermost_function().IsSyncGenClosure() || 8938 innermost_function().IsSyncGenClosure() ||
8551 innermost_function().IsSyncGenerator()) { 8939 innermost_function().IsSyncGenerator() ||
8940 innermost_function().IsAsyncGenerator() ||
8941 innermost_function().IsAsyncGenClosure()) {
8552 if ((try_blocks_list_->outer_try_block() != NULL) && 8942 if ((try_blocks_list_->outer_try_block() != NULL) &&
8553 (try_blocks_list_->outer_try_block()->try_block() 8943 (try_blocks_list_->outer_try_block()->try_block()
8554 ->scope->function_level() == 8944 ->scope->function_level() ==
8555 current_block_->scope->function_level())) { 8945 current_block_->scope->function_level())) {
8556 // We need to unchain three scope levels: catch clause, catch 8946 // We need to unchain three scope levels: catch clause, catch
8557 // parameters, and the general try block. 8947 // parameters, and the general try block.
8558 RestoreSavedTryContext( 8948 RestoreSavedTryContext(
8559 current_block_->scope->parent()->parent(), 8949 current_block_->scope->parent()->parent(),
8560 try_blocks_list_->outer_try_block()->try_index(), 8950 try_blocks_list_->outer_try_block()->try_index(),
8561 current_block_->statements); 8951 current_block_->statements);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
8594 parsed_function()->set_async_saved_try_ctx_name(async_saved_try_ctx_name); 8984 parsed_function()->set_async_saved_try_ctx_name(async_saved_try_ctx_name);
8595 } 8985 }
8596 8986
8597 8987
8598 // Restore the currently relevant :saved_try_context_var on the stack 8988 // Restore the currently relevant :saved_try_context_var on the stack
8599 // from the captured :async_saved_try_ctx_var_. 8989 // from the captured :async_saved_try_ctx_var_.
8600 // * Try blocks: Set the context variable for this try block. 8990 // * Try blocks: Set the context variable for this try block.
8601 // * Catch/finally blocks: Set the context variable for any outer try block (if 8991 // * Catch/finally blocks: Set the context variable for any outer try block (if
8602 // existent). 8992 // existent).
8603 // 8993 //
8604 // Also save the captured variable and the stack variable to be able to set 8994 // Also save the captured variable and the stack variable in the parsed
8605 // it after a function continues execution (await). 8995 // function so we are able to set it after a function continues
8996 // execution (await/yield).
8606 void Parser::RestoreSavedTryContext(LocalScope* saved_try_context_scope, 8997 void Parser::RestoreSavedTryContext(LocalScope* saved_try_context_scope,
8607 int16_t try_index, 8998 int16_t try_index,
8608 SequenceNode* target) { 8999 SequenceNode* target) {
8609 LocalVariable* saved_try_ctx = saved_try_context_scope->LookupVariable( 9000 LocalVariable* saved_try_ctx = saved_try_context_scope->LookupVariable(
8610 Symbols::SavedTryContextVar(), false); 9001 Symbols::SavedTryContextVar(), false);
8611 ASSERT((saved_try_ctx != NULL) && !saved_try_ctx->is_captured()); 9002 ASSERT((saved_try_ctx != NULL) && !saved_try_ctx->is_captured());
8612 const String& async_saved_try_ctx_name = 9003 const String& async_saved_try_ctx_name =
8613 BuildAsyncSavedTryContextName(Z, try_index); 9004 BuildAsyncSavedTryContextName(Z, try_index);
8614 LocalVariable* async_saved_try_ctx = 9005 LocalVariable* async_saved_try_ctx =
8615 target->scope()->LookupVariable(async_saved_try_ctx_name, false); 9006 target->scope()->LookupVariable(async_saved_try_ctx_name, false);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
8680 } 9071 }
8681 9072
8682 // Now parse the 'try' block. 9073 // Now parse the 'try' block.
8683 OpenBlock(); 9074 OpenBlock();
8684 PushTryBlock(current_block_); 9075 PushTryBlock(current_block_);
8685 ExpectToken(Token::kLBRACE); 9076 ExpectToken(Token::kLBRACE);
8686 9077
8687 if (innermost_function().IsAsyncClosure() || 9078 if (innermost_function().IsAsyncClosure() ||
8688 innermost_function().IsAsyncFunction() || 9079 innermost_function().IsAsyncFunction() ||
8689 innermost_function().IsSyncGenClosure() || 9080 innermost_function().IsSyncGenClosure() ||
8690 innermost_function().IsSyncGenerator()) { 9081 innermost_function().IsSyncGenerator() ||
9082 innermost_function().IsAsyncGenerator() ||
9083 innermost_function().IsAsyncGenClosure()) {
8691 SetupSavedTryContext(context_var); 9084 SetupSavedTryContext(context_var);
8692 } 9085 }
8693 9086
8694 ParseStatementSequence(); 9087 ParseStatementSequence();
8695 ExpectToken(Token::kRBRACE); 9088 ExpectToken(Token::kRBRACE);
8696 SequenceNode* try_block = CloseBlock(); 9089 SequenceNode* try_block = CloseBlock();
8697 9090
8698 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && 9091 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") &&
8699 (CurrentToken() != Token::kFINALLY)) { 9092 (CurrentToken() != Token::kFINALLY)) {
8700 ReportError("catch or finally clause expected"); 9093 ReportError("catch or finally clause expected");
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
8824 ReportError(jump_pos, "'break' to case clause label is illegal"); 9217 ReportError(jump_pos, "'break' to case clause label is illegal");
8825 } 9218 }
8826 if (target->FunctionLevel() != current_block_->scope->function_level()) { 9219 if (target->FunctionLevel() != current_block_->scope->function_level()) {
8827 ReportError(jump_pos, "'%s' target must be in same function context", 9220 ReportError(jump_pos, "'%s' target must be in same function context",
8828 Token::Str(jump_kind)); 9221 Token::Str(jump_kind));
8829 } 9222 }
8830 return new(Z) JumpNode(jump_pos, jump_kind, target); 9223 return new(Z) JumpNode(jump_pos, jump_kind, target);
8831 } 9224 }
8832 9225
8833 9226
9227 AstNode* Parser::ParseYieldStatement() {
9228 bool is_yield_each = false;
9229 const intptr_t yield_pos = TokenPos();
9230 ConsumeToken(); // yield reserved word.
9231 ASSERT(innermost_function().IsGenerator() ||
9232 innermost_function().IsSyncGenClosure() ||
9233 innermost_function().IsAsyncGenerator() ||
9234 innermost_function().IsAsyncGenClosure());
9235 if (CurrentToken() == Token::kMUL) {
9236 is_yield_each = true;
9237 ConsumeToken();
9238 }
9239 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
9240
9241 LetNode* yield = new(Z) LetNode(yield_pos);
9242 if (innermost_function().IsSyncGenerator() ||
9243 innermost_function().IsSyncGenClosure()) {
9244 // Yield statement in sync* function.
9245
9246 LocalVariable* iterator_param =
9247 LookupLocalScope(Symbols::IteratorParameter());
9248 ASSERT(iterator_param != NULL);
9249 // Generate :iterator.current = expr;
9250 AstNode* iterator =
9251 new(Z) LoadLocalNode(Scanner::kNoSourcePos, iterator_param);
9252 AstNode* store_current =
9253 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
9254 iterator,
9255 String::ZoneHandle(Symbols::Current().raw()),
9256 expr);
9257 yield->AddNode(store_current);
9258 if (is_yield_each) {
9259 // Generate :iterator.isYieldEach = true;
9260 AstNode* set_is_yield_each =
9261 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
9262 iterator,
9263 String::ZoneHandle(Symbols::IsYieldEach().raw()),
9264 new(Z) LiteralNode(TokenPos(), Bool::True()));
9265 yield->AddNode(set_is_yield_each);
9266 }
9267 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
9268 await_marker->set_scope(current_block_->scope);
9269 yield->AddNode(await_marker);
9270 // Return true to indicate that a value has been generated.
9271 ReturnNode* return_true = new(Z) ReturnNode(yield_pos,
9272 new(Z) LiteralNode(TokenPos(), Bool::True()));
9273 return_true->set_return_type(ReturnNode::kContinuationTarget);
9274 yield->AddNode(return_true);
9275
9276 // If this expression is part of a try block, also append the code for
9277 // restoring the saved try context that lives on the stack.
9278 const String& async_saved_try_ctx_name =
9279 String::Handle(Z, parsed_function()->async_saved_try_ctx_name());
9280 if (!async_saved_try_ctx_name.IsNull()) {
9281 LocalVariable* async_saved_try_ctx =
9282 current_block_->scope->LookupVariable(async_saved_try_ctx_name,
9283 false);
9284 ASSERT(async_saved_try_ctx != NULL);
9285 yield->AddNode(new (Z) StoreLocalNode(
9286 Scanner::kNoSourcePos,
9287 parsed_function()->saved_try_ctx(),
9288 new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_saved_try_ctx)));
9289 }
9290 } else {
9291 // yield statement in async* function.
9292 ASSERT(innermost_function().IsAsyncGenerator() ||
9293 innermost_function().IsAsyncGenClosure());
9294
9295 LocalVariable* controller_var = LookupLocalScope(Symbols::Controller());
9296 ASSERT(controller_var != NULL);
9297 // :controller.add[Stream](expr);
9298 ArgumentListNode* add_args = new(Z) ArgumentListNode(yield_pos);
9299 add_args->Add(expr);
9300 AstNode* add_call =
9301 new(Z) InstanceCallNode(yield_pos,
9302 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller_var),
9303 is_yield_each ? Symbols::AddStream() : Symbols::add(),
9304 add_args);
9305
9306
9307 // if (:controller.add[Stream](expr)) {
9308 // return;
9309 // }
9310 // await_marker;
9311 // continuation_return;
9312 //
9313
9314 SequenceNode* true_branch =
9315 new(Z) SequenceNode(Scanner::kNoSourcePos, current_block_->scope);
9316 AstNode* return_from_generator = new(Z) ReturnNode(yield_pos);
9317 true_branch->Add(return_from_generator);
9318 AddNodeForFinallyInlining(return_from_generator);
9319 AstNode* if_is_cancelled =
9320 new(Z) IfNode(Scanner::kNoSourcePos, add_call, true_branch, NULL);
9321 yield->AddNode(if_is_cancelled);
9322
9323 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
9324 await_marker->set_scope(current_block_->scope);
9325 yield->AddNode(await_marker);
9326 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos);
9327 continuation_return->set_return_type(ReturnNode::kContinuationTarget);
9328 yield->AddNode(continuation_return);
9329
9330 // If this expression is part of a try block, also append the code for
9331 // restoring the saved try context that lives on the stack.
9332 const String& async_saved_try_ctx_name =
9333 String::Handle(Z, parsed_function()->async_saved_try_ctx_name());
9334 if (!async_saved_try_ctx_name.IsNull()) {
9335 LocalVariable* async_saved_try_ctx =
9336 current_block_->scope->LookupVariable(async_saved_try_ctx_name,
9337 false);
9338 ASSERT(async_saved_try_ctx != NULL);
9339 yield->AddNode(new (Z) StoreLocalNode(
9340 Scanner::kNoSourcePos,
9341 parsed_function()->saved_try_ctx(),
9342 new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_saved_try_ctx)));
9343 }
9344 }
9345 return yield;
9346 }
9347
9348
8834 AstNode* Parser::ParseStatement() { 9349 AstNode* Parser::ParseStatement() {
8835 TRACE_PARSER("ParseStatement"); 9350 TRACE_PARSER("ParseStatement");
8836 AstNode* statement = NULL; 9351 AstNode* statement = NULL;
8837 intptr_t label_pos = 0; 9352 intptr_t label_pos = 0;
8838 String* label_name = NULL; 9353 String* label_name = NULL;
8839 if (IsIdentifier()) { 9354 if (IsIdentifier()) {
8840 if (LookaheadToken(1) == Token::kCOLON) { 9355 if (LookaheadToken(1) == Token::kCOLON) {
8841 // Statement starts with a label. 9356 // Statement starts with a label.
8842 label_name = CurrentLiteral(); 9357 label_name = CurrentLiteral();
8843 label_pos = TokenPos(); 9358 label_pos = TokenPos();
(...skipping 19 matching lines...) Expand all
8863 statement = ParseTryStatement(label_name); 9378 statement = ParseTryStatement(label_name);
8864 } else if (token == Token::kRETURN) { 9379 } else if (token == Token::kRETURN) {
8865 const intptr_t return_pos = TokenPos(); 9380 const intptr_t return_pos = TokenPos();
8866 ConsumeToken(); 9381 ConsumeToken();
8867 if (CurrentToken() != Token::kSEMICOLON) { 9382 if (CurrentToken() != Token::kSEMICOLON) {
8868 const intptr_t expr_pos = TokenPos(); 9383 const intptr_t expr_pos = TokenPos();
8869 if (current_function().IsGenerativeConstructor() && 9384 if (current_function().IsGenerativeConstructor() &&
8870 (current_block_->scope->function_level() == 0)) { 9385 (current_block_->scope->function_level() == 0)) {
8871 ReportError(expr_pos, 9386 ReportError(expr_pos,
8872 "return of a value is not allowed in constructors"); 9387 "return of a value is not allowed in constructors");
8873 } else if (current_function().IsGenerator()) { 9388 } else if (current_function().IsGeneratorClosure() &&
9389 (current_block_->scope->function_level() == 0)) {
8874 ReportError(expr_pos, "generator functions may not return a value"); 9390 ReportError(expr_pos, "generator functions may not return a value");
8875 } 9391 }
8876 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); 9392 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
8877 statement = new(Z) ReturnNode(statement_pos, expr); 9393 statement = new(Z) ReturnNode(statement_pos, expr);
8878 } else { 9394 } else {
8879 if (current_function().IsSyncGenClosure() && 9395 if (current_function().IsSyncGenClosure() &&
8880 (current_block_->scope->function_level() == 0)) { 9396 (current_block_->scope->function_level() == 0)) {
8881 // In a synchronous generator, return without an expression 9397 // In a synchronous generator, return without an expression
8882 // returns false, signaling that the iterator terminates and 9398 // returns false, signaling that the iterator terminates and
8883 // did not yield a value. 9399 // did not yield a value.
8884 statement = new(Z) ReturnNode(statement_pos, 9400 statement = new(Z) ReturnNode(statement_pos,
8885 new(Z) LiteralNode(return_pos, Bool::False())); 9401 new(Z) LiteralNode(return_pos, Bool::False()));
8886 } else { 9402 } else {
8887 statement = new(Z) ReturnNode(statement_pos); 9403 statement = new(Z) ReturnNode(statement_pos);
8888 } 9404 }
8889 } 9405 }
8890 AddNodeForFinallyInlining(statement); 9406 AddNodeForFinallyInlining(statement);
8891 ExpectSemicolon(); 9407 ExpectSemicolon();
8892 } else if (IsYieldKeyword()) { 9408 } else if (IsYieldKeyword()) {
8893 bool is_yield_each = false; 9409 statement = ParseYieldStatement();
8894 ConsumeToken();
8895 ASSERT(innermost_function().IsGenerator() ||
8896 innermost_function().IsSyncGenClosure());
8897 if (CurrentToken() == Token::kMUL) {
8898 is_yield_each = true;
8899 ConsumeToken();
8900 }
8901 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
8902 LocalVariable* iterator_param =
8903 LookupLocalScope(Symbols::IteratorParameter());
8904 ASSERT(iterator_param != NULL);
8905 // Generate :iterator.current = expr;
8906 AstNode* iterator =
8907 new(Z) LoadLocalNode(Scanner::kNoSourcePos, iterator_param);
8908 AstNode* store_current =
8909 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
8910 iterator,
8911 String::ZoneHandle(Symbols::Current().raw()),
8912 expr);
8913 LetNode* yield = new(Z) LetNode(statement_pos);
8914 yield->AddNode(store_current);
8915 if (is_yield_each) {
8916 // Generate :iterator.isYieldEach = true;
8917 AstNode* set_is_yield_each =
8918 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
8919 iterator,
8920 String::ZoneHandle(Symbols::IsYieldEach().raw()),
8921 new(Z) LiteralNode(TokenPos(), Bool::True()));
8922 yield->AddNode(set_is_yield_each);
8923 }
8924 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode();
8925 await_marker->set_scope(current_block_->scope);
8926 yield->AddNode(await_marker);
8927 // Return true to indicate that a value has been generated.
8928 ReturnNode* return_true = new(Z) ReturnNode(statement_pos,
8929 new(Z) LiteralNode(TokenPos(), Bool::True()));
8930 return_true->set_return_type(ReturnNode::kContinuationTarget);
8931 yield->AddNode(return_true);
8932
8933 // If this expression is part of a try block, also append the code for
8934 // restoring the saved try context that lives on the stack.
8935 const String& async_saved_try_ctx_name =
8936 String::Handle(Z, parsed_function()->async_saved_try_ctx_name());
8937 if (!async_saved_try_ctx_name.IsNull()) {
8938 LocalVariable* async_saved_try_ctx =
8939 current_block_->scope->LookupVariable(async_saved_try_ctx_name,
8940 false);
8941 ASSERT(async_saved_try_ctx != NULL);
8942 yield->AddNode(new (Z) StoreLocalNode(
8943 Scanner::kNoSourcePos,
8944 parsed_function()->saved_try_ctx(),
8945 new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_saved_try_ctx)));
8946 }
8947
8948 statement = yield;
8949 ExpectSemicolon(); 9410 ExpectSemicolon();
8950 } else if (token == Token::kIF) { 9411 } else if (token == Token::kIF) {
8951 statement = ParseIfStatement(label_name); 9412 statement = ParseIfStatement(label_name);
8952 } else if (token == Token::kASSERT) { 9413 } else if (token == Token::kASSERT) {
8953 statement = ParseAssertStatement(); 9414 statement = ParseAssertStatement();
8954 ExpectSemicolon(); 9415 ExpectSemicolon();
8955 } else if (IsVariableDeclaration()) { 9416 } else if (IsVariableDeclaration()) {
8956 statement = ParseVariableDeclarationList(); 9417 statement = ParseVariableDeclarationList();
8957 ExpectSemicolon(); 9418 ExpectSemicolon();
8958 } else if (IsFunctionDeclaration()) { 9419 } else if (IsFunctionDeclaration()) {
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after
9804 } 10265 }
9805 10266
9806 10267
9807 AstNode* Parser::ParseUnaryExpr() { 10268 AstNode* Parser::ParseUnaryExpr() {
9808 TRACE_PARSER("ParseUnaryExpr"); 10269 TRACE_PARSER("ParseUnaryExpr");
9809 AstNode* expr = NULL; 10270 AstNode* expr = NULL;
9810 const intptr_t op_pos = TokenPos(); 10271 const intptr_t op_pos = TokenPos();
9811 if (IsAwaitKeyword()) { 10272 if (IsAwaitKeyword()) {
9812 TRACE_PARSER("ParseAwaitExpr"); 10273 TRACE_PARSER("ParseAwaitExpr");
9813 if (!innermost_function().IsAsyncFunction() && 10274 if (!innermost_function().IsAsyncFunction() &&
9814 !innermost_function().IsAsyncClosure()) { 10275 !innermost_function().IsAsyncClosure() &&
9815 ReportError("await operator is only allowed in async function"); 10276 !innermost_function().IsAsyncGenerator() &&
10277 !innermost_function().IsAsyncGenClosure()) {
10278 ReportError("await operator is only allowed in an asynchronous function");
9816 } 10279 }
9817 ConsumeToken(); 10280 ConsumeToken();
9818 parsed_function()->record_await(); 10281 parsed_function()->record_await();
9819 expr = new (Z) AwaitNode(op_pos, ParseUnaryExpr()); 10282 expr = new (Z) AwaitNode(op_pos, ParseUnaryExpr());
9820 } else if (IsPrefixOperator(CurrentToken())) { 10283 } else if (IsPrefixOperator(CurrentToken())) {
9821 Token::Kind unary_op = CurrentToken(); 10284 Token::Kind unary_op = CurrentToken();
9822 if (unary_op == Token::kSUB) { 10285 if (unary_op == Token::kSUB) {
9823 unary_op = Token::kNEGATE; 10286 unary_op = Token::kNEGATE;
9824 } 10287 }
9825 ConsumeToken(); 10288 ConsumeToken();
(...skipping 2816 matching lines...) Expand 10 before | Expand all | Expand 10 after
12642 void Parser::SkipQualIdent() { 13105 void Parser::SkipQualIdent() {
12643 ASSERT(IsIdentifier()); 13106 ASSERT(IsIdentifier());
12644 ConsumeToken(); 13107 ConsumeToken();
12645 if (CurrentToken() == Token::kPERIOD) { 13108 if (CurrentToken() == Token::kPERIOD) {
12646 ConsumeToken(); // Consume the kPERIOD token. 13109 ConsumeToken(); // Consume the kPERIOD token.
12647 ExpectIdentifier("identifier expected after '.'"); 13110 ExpectIdentifier("identifier expected after '.'");
12648 } 13111 }
12649 } 13112 }
12650 13113
12651 } // namespace dart 13114 } // namespace dart
OLDNEW
« runtime/lib/core_patch.dart ('K') | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698