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

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

Issue 974073002: Fix async machinery for finally clauses (issues 22445, 22300). (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') | tests/language/language.status » ('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 5967 matching lines...) Expand 10 before | Expand all | Expand 10 after
5978 // body is the outermost try statement. 5978 // body is the outermost try statement.
5979 ASSERT(try_blocks_list_ != NULL); 5979 ASSERT(try_blocks_list_ != NULL);
5980 ASSERT(try_blocks_list_->outer_try_block() == NULL); 5980 ASSERT(try_blocks_list_->outer_try_block() == NULL);
5981 // We only get here when parsing an async generator body. 5981 // We only get here when parsing an async generator body.
5982 ASSERT(innermost_function().IsAsyncGenClosure()); 5982 ASSERT(innermost_function().IsAsyncGenClosure());
5983 5983
5984 const intptr_t try_end_pos = innermost_function().end_token_pos(); 5984 const intptr_t try_end_pos = innermost_function().end_token_pos();
5985 5985
5986 // The try-block (closure body code) has been parsed. We are now 5986 // The try-block (closure body code) has been parsed. We are now
5987 // generating the code for the catch block. 5987 // generating the code for the catch block.
5988 LocalScope* try_scope = current_block_->scope;
5988 try_blocks_list_->enter_catch(); 5989 try_blocks_list_->enter_catch();
5989 OpenBlock(); // Catch handler list. 5990 OpenBlock(); // Catch handler list.
5990 OpenBlock(); // Catch block. 5991 OpenBlock(); // Catch block.
5991 5992
5992 // Add the exception and stack trace parameters to the scope. 5993 // Add the exception and stack trace parameters to the scope.
5993 const AbstractType& dynamic_type = 5994 const AbstractType& dynamic_type =
5994 AbstractType::ZoneHandle(Z, Type::DynamicType()); 5995 AbstractType::ZoneHandle(Z, Type::DynamicType());
5995 CatchParamDesc exception_param; 5996 CatchParamDesc exception_param;
5996 CatchParamDesc stack_trace_param; 5997 CatchParamDesc stack_trace_param;
5997 exception_param.token_pos = Scanner::kNoSourcePos; 5998 exception_param.token_pos = Scanner::kNoSourcePos;
5998 exception_param.type = &dynamic_type; 5999 exception_param.type = &dynamic_type;
5999 exception_param.name = &Symbols::ExceptionParameter(); 6000 exception_param.name = &Symbols::ExceptionParameter();
6000 stack_trace_param.token_pos = Scanner::kNoSourcePos; 6001 stack_trace_param.token_pos = Scanner::kNoSourcePos;
6001 stack_trace_param.type = &dynamic_type; 6002 stack_trace_param.type = &dynamic_type;
6002 stack_trace_param.name = &Symbols::StackTraceParameter(); 6003 stack_trace_param.name = &Symbols::StackTraceParameter();
6003 6004
6004 AddCatchParamsToScope( 6005 AddCatchParamsToScope(
6005 &exception_param, &stack_trace_param, current_block_->scope); 6006 &exception_param, &stack_trace_param, current_block_->scope);
6006 6007
6007 // Generate code to save the exception object and stack trace 6008 // Generate code to save the exception object and stack trace
6008 // in local variables. 6009 // in local variables.
6009 LocalVariable* context_var = current_block_->scope->LookupVariable( 6010 LocalVariable* context_var = try_scope->LocalLookupVariable(
6010 Symbols::SavedTryContextVar(), false); 6011 Symbols::SavedTryContextVar());
6011 ASSERT(context_var != NULL); 6012 ASSERT(context_var != NULL);
6012 6013
6013 LocalVariable* exception_var = current_block_->scope->LookupVariable( 6014 LocalVariable* exception_var = try_scope->LocalLookupVariable(
6014 Symbols::ExceptionVar(), false); 6015 Symbols::ExceptionVar());
6015 ASSERT(exception_var != NULL); 6016 ASSERT(exception_var != NULL);
6016 if (exception_param.var != NULL) { 6017 if (exception_param.var != NULL) {
6017 // Generate code to load the exception object (:exception_var) into 6018 // Generate code to load the exception object (:exception_var) into
6018 // the exception variable specified in this block. 6019 // the exception variable specified in this block.
6019 current_block_->statements->Add(new(Z) StoreLocalNode( 6020 current_block_->statements->Add(new(Z) StoreLocalNode(
6020 Scanner::kNoSourcePos, 6021 Scanner::kNoSourcePos,
6021 exception_param.var, 6022 exception_param.var,
6022 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); 6023 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var)));
6023 } 6024 }
6024 6025
6025 LocalVariable* stack_trace_var = 6026 LocalVariable* stack_trace_var =
6026 current_block_->scope->LookupVariable(Symbols::StackTraceVar(), false); 6027 try_scope->LocalLookupVariable(Symbols::StackTraceVar());
6027 ASSERT(stack_trace_var != NULL); 6028 ASSERT(stack_trace_var != NULL);
6028 if (stack_trace_param.var != NULL) { 6029 if (stack_trace_param.var != NULL) {
6029 // A stack trace variable is specified in this block, so generate code 6030 // A stack trace variable is specified in this block, so generate code
6030 // to load the stack trace object (:stack_trace_var) into the stack 6031 // to load the stack trace object (:stack_trace_var) into the stack
6031 // trace variable specified in this block. 6032 // trace variable specified in this block.
6032 current_block_->statements->Add(new(Z) StoreLocalNode( 6033 current_block_->statements->Add(new(Z) StoreLocalNode(
6033 Scanner::kNoSourcePos, 6034 Scanner::kNoSourcePos,
6034 stack_trace_param.var, 6035 stack_trace_param.var,
6035 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); 6036 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
6036 } 6037 }
6037 LocalVariable* saved_exception_var = current_block_->scope->LookupVariable( 6038 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable(
hausner 2015/03/03 23:19:11 Nit: the initializer value for the variable may no
regis 2015/03/03 23:47:09 It does not.
6038 Symbols::SavedExceptionVar(), false); 6039 Symbols::SavedExceptionVar());
6039 LocalVariable* saved_stack_trace_var = current_block_->scope->LookupVariable( 6040 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable(
6040 Symbols::SavedStackTraceVar(), false); 6041 Symbols::SavedStackTraceVar());
6041 SaveExceptionAndStacktrace(exception_var, 6042 SaveExceptionAndStacktrace(current_block_->statements,
6043 exception_var,
6042 stack_trace_var, 6044 stack_trace_var,
6043 saved_exception_var, 6045 saved_exception_var,
6044 saved_stack_trace_var); 6046 saved_stack_trace_var);
6045 6047
6046 // Catch block: add the error to the stream. 6048 // Catch block: add the error to the stream.
6047 // :controller.AddError(:exception, :stack_trace); 6049 // :controller.AddError(:exception, :stack_trace);
6048 // return; // The finally block will close the stream. 6050 // return; // The finally block will close the stream.
6049 LocalVariable* controller = 6051 LocalVariable* controller =
6050 current_block_->scope->LookupVariable(Symbols::Controller(), false); 6052 current_block_->scope->LookupVariable(Symbols::Controller(), false);
6051 ASSERT(controller != NULL); 6053 ASSERT(controller != NULL);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
6132 current_block_->statements->Add(try_catch_node); 6134 current_block_->statements->Add(try_catch_node);
6133 return CloseBlock(); 6135 return CloseBlock();
6134 } 6136 }
6135 6137
6136 6138
6137 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { 6139 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) {
6138 // This is the outermost try-catch of the function. 6140 // This is the outermost try-catch of the function.
6139 ASSERT(try_blocks_list_ != NULL); 6141 ASSERT(try_blocks_list_ != NULL);
6140 ASSERT(try_blocks_list_->outer_try_block() == NULL); 6142 ASSERT(try_blocks_list_->outer_try_block() == NULL);
6141 ASSERT(innermost_function().IsAsyncClosure()); 6143 ASSERT(innermost_function().IsAsyncClosure());
6144 LocalScope* try_scope = current_block_->scope;
6142 6145
6143 try_blocks_list_->enter_catch(); 6146 try_blocks_list_->enter_catch();
6144 6147
6145 OpenBlock(); // Catch handler list. 6148 OpenBlock(); // Catch handler list.
6146 OpenBlock(); // Catch block. 6149 OpenBlock(); // Catch block.
6147 const AbstractType& dynamic_type = 6150 const AbstractType& dynamic_type =
6148 AbstractType::ZoneHandle(Z, Type::DynamicType()); 6151 AbstractType::ZoneHandle(Z, Type::DynamicType());
6149 CatchParamDesc exception_param; 6152 CatchParamDesc exception_param;
6150 CatchParamDesc stack_trace_param; 6153 CatchParamDesc stack_trace_param;
6151 exception_param.token_pos = Scanner::kNoSourcePos; 6154 exception_param.token_pos = Scanner::kNoSourcePos;
6152 exception_param.type = &dynamic_type; 6155 exception_param.type = &dynamic_type;
6153 exception_param.name = &Symbols::ExceptionParameter(); 6156 exception_param.name = &Symbols::ExceptionParameter();
6154 stack_trace_param.token_pos = Scanner::kNoSourcePos; 6157 stack_trace_param.token_pos = Scanner::kNoSourcePos;
6155 stack_trace_param.type = &dynamic_type; 6158 stack_trace_param.type = &dynamic_type;
6156 stack_trace_param.name = &Symbols::StackTraceParameter(); 6159 stack_trace_param.name = &Symbols::StackTraceParameter();
6157 6160
6158 AddCatchParamsToScope( 6161 AddCatchParamsToScope(
6159 &exception_param, &stack_trace_param, current_block_->scope); 6162 &exception_param, &stack_trace_param, current_block_->scope);
6160 6163
6161 LocalVariable* context_var = current_block_->scope->LookupVariable( 6164 LocalVariable* context_var = try_scope->LocalLookupVariable(
hausner 2015/03/03 23:19:11 Nit: line break after =
regis 2015/03/03 23:47:09 ditto
6162 Symbols::SavedTryContextVar(), false); 6165 Symbols::SavedTryContextVar());
6163 ASSERT(context_var != NULL); 6166 ASSERT(context_var != NULL);
6164 6167
6165 LocalVariable* exception_var = current_block_->scope->LookupVariable( 6168 LocalVariable* exception_var = try_scope->LocalLookupVariable(
6166 Symbols::ExceptionVar(), false); 6169 Symbols::ExceptionVar());
6167 if (exception_param.var != NULL) { 6170 if (exception_param.var != NULL) {
6168 // Generate code to load the exception object (:exception_var) into 6171 // Generate code to load the exception object (:exception_var) into
6169 // the exception variable specified in this block. 6172 // the exception variable specified in this block.
6170 ASSERT(exception_var != NULL); 6173 ASSERT(exception_var != NULL);
6171 current_block_->statements->Add(new(Z) StoreLocalNode( 6174 current_block_->statements->Add(new(Z) StoreLocalNode(
6172 Scanner::kNoSourcePos, 6175 Scanner::kNoSourcePos,
6173 exception_param.var, 6176 exception_param.var,
6174 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); 6177 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var)));
6175 } 6178 }
6176 6179
6177 LocalVariable* stack_trace_var = 6180 LocalVariable* stack_trace_var =
6178 current_block_->scope->LookupVariable(Symbols::StackTraceVar(), false); 6181 try_scope->LocalLookupVariable(Symbols::StackTraceVar());
6179 if (stack_trace_param.var != NULL) { 6182 if (stack_trace_param.var != NULL) {
6180 // A stack trace variable is specified in this block, so generate code 6183 // A stack trace variable is specified in this block, so generate code
6181 // to load the stack trace object (:stack_trace_var) into the stack 6184 // to load the stack trace object (:stack_trace_var) into the stack
6182 // trace variable specified in this block. 6185 // trace variable specified in this block.
6183 ASSERT(stack_trace_var != NULL); 6186 ASSERT(stack_trace_var != NULL);
6184 current_block_->statements->Add(new(Z) StoreLocalNode( 6187 current_block_->statements->Add(new(Z) StoreLocalNode(
6185 Scanner::kNoSourcePos, 6188 Scanner::kNoSourcePos,
6186 stack_trace_param.var, 6189 stack_trace_param.var,
6187 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); 6190 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
6188 } 6191 }
6189 LocalVariable* saved_exception_var = current_block_->scope->LookupVariable( 6192 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable(
6190 Symbols::SavedExceptionVar(), false); 6193 Symbols::SavedExceptionVar());
6191 LocalVariable* saved_stack_trace_var = current_block_->scope->LookupVariable( 6194 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable(
6192 Symbols::SavedStackTraceVar(), false); 6195 Symbols::SavedStackTraceVar());
6193 SaveExceptionAndStacktrace(exception_var, 6196 SaveExceptionAndStacktrace(current_block_->statements,
6197 exception_var,
6194 stack_trace_var, 6198 stack_trace_var,
6195 saved_exception_var, 6199 saved_exception_var,
6196 saved_stack_trace_var); 6200 saved_stack_trace_var);
6197 6201
6198 // Complete the async future with an error. This catch block executes 6202 // Complete the async future with an error. This catch block executes
6199 // unconditionally, there is no need to generate a type check for. 6203 // unconditionally, there is no need to generate a type check for.
6200 LocalVariable* async_completer = current_block_->scope->LookupVariable( 6204 LocalVariable* async_completer = current_block_->scope->LookupVariable(
6201 Symbols::AsyncCompleter(), false); 6205 Symbols::AsyncCompleter(), false);
6202 ASSERT(async_completer != NULL); 6206 ASSERT(async_completer != NULL);
6203 ArgumentListNode* completer_args = 6207 ArgumentListNode* completer_args =
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
6243 try_block, 6247 try_block,
6244 context_var, 6248 context_var,
6245 catch_clause, 6249 catch_clause,
6246 NULL, // No finally clause. 6250 NULL, // No finally clause.
6247 try_index); 6251 try_index);
6248 current_block_->statements->Add(try_catch_node); 6252 current_block_->statements->Add(try_catch_node);
6249 return CloseBlock(); 6253 return CloseBlock();
6250 } 6254 }
6251 6255
6252 6256
6253 // Wrap the body of the async or arync* closure in a try/catch block. 6257 // Wrap the body of the async or async* closure in a try/catch block.
6254 void Parser::OpenAsyncTryBlock() { 6258 void Parser::OpenAsyncTryBlock() {
6255 ASSERT(innermost_function().IsAsyncClosure() || 6259 ASSERT(innermost_function().IsAsyncClosure() ||
6256 innermost_function().IsAsyncGenClosure()); 6260 innermost_function().IsAsyncGenClosure());
6257 6261 LocalVariable* context_var = NULL;
6258 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); 6262 LocalVariable* exception_var = NULL;
6259 LocalVariable* context_var = 6263 LocalVariable* stack_trace_var = NULL;
6260 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); 6264 LocalVariable* saved_exception_var = NULL;
6261 if (context_var == NULL) { 6265 LocalVariable* saved_stack_trace_var = NULL;
6262 context_var = new(Z) LocalVariable( 6266 SetupExceptionVariables(current_block_->scope,
6263 TokenPos(), 6267 true,
6264 Symbols::SavedTryContextVar(), 6268 &context_var,
6265 dynamic_type); 6269 &exception_var,
6266 current_block_->scope->AddVariable(context_var); 6270 &stack_trace_var,
6267 } 6271 &saved_exception_var,
6268 LocalVariable* exception_var = 6272 &saved_stack_trace_var);
6269 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar());
6270 if (exception_var == NULL) {
6271 exception_var = new(Z) LocalVariable(
6272 TokenPos(),
6273 Symbols::ExceptionVar(),
6274 dynamic_type);
6275 current_block_->scope->AddVariable(exception_var);
6276 }
6277 LocalVariable* stack_trace_var =
6278 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar());
6279 if (stack_trace_var == NULL) {
6280 stack_trace_var = new(Z) LocalVariable(
6281 TokenPos(),
6282 Symbols::StackTraceVar(),
6283 dynamic_type);
6284 current_block_->scope->AddVariable(stack_trace_var);
6285 }
6286 LocalVariable* saved_exception_var =
6287 current_block_->scope->LocalLookupVariable(Symbols::SavedExceptionVar());
6288 if (saved_exception_var == NULL) {
6289 saved_exception_var = new(Z) LocalVariable(
6290 TokenPos(),
6291 Symbols::SavedExceptionVar(),
6292 dynamic_type);
6293 current_block_->scope->AddVariable(saved_exception_var);
6294 }
6295 LocalVariable* saved_stack_trace_var =
6296 current_block_->scope->LocalLookupVariable(Symbols::SavedStackTraceVar());
6297 if (saved_stack_trace_var == NULL) {
6298 saved_stack_trace_var = new(Z) LocalVariable(
6299 TokenPos(),
6300 Symbols::SavedStackTraceVar(),
6301 dynamic_type);
6302 current_block_->scope->AddVariable(saved_stack_trace_var);
6303 }
6304 6273
6305 // Open the try block. 6274 // Open the try block.
6306 OpenBlock(); 6275 OpenBlock();
6307 // This is the outermost try-catch in the function. 6276 // This is the outermost try-catch in the function.
6308 ASSERT(try_blocks_list_ == NULL); 6277 ASSERT(try_blocks_list_ == NULL);
6309 PushTryBlock(current_block_); 6278 PushTryBlock(current_block_);
6310 6279
6311 SetupSavedTryContext(context_var); 6280 SetupSavedTryContext(context_var);
6312 } 6281 }
6313 6282
(...skipping 2368 matching lines...) Expand 10 before | Expand all | Expand 10 after
8682 } 8651 }
8683 stack_trace_param->var = var; 8652 stack_trace_param->var = var;
8684 } 8653 }
8685 } 8654 }
8686 8655
8687 8656
8688 // Generate code to load the exception object (:exception_var) into 8657 // Generate code to load the exception object (:exception_var) into
8689 // the saved exception variable (:saved_exception_var) used to rethrow. 8658 // the saved exception variable (:saved_exception_var) used to rethrow.
8690 // Generate code to load the stack trace object (:stack_trace_var) into 8659 // Generate code to load the stack trace object (:stack_trace_var) into
8691 // the saved stacktrace variable (:saved_stack_trace_var) used to rethrow. 8660 // the saved stacktrace variable (:saved_stack_trace_var) used to rethrow.
8692 void Parser::SaveExceptionAndStacktrace(LocalVariable* exception_var, 8661 void Parser::SaveExceptionAndStacktrace(SequenceNode* statements,
8662 LocalVariable* exception_var,
8693 LocalVariable* stack_trace_var, 8663 LocalVariable* stack_trace_var,
8694 LocalVariable* saved_exception_var, 8664 LocalVariable* saved_exception_var,
8695 LocalVariable* saved_stack_trace_var) { 8665 LocalVariable* saved_stack_trace_var) {
8696 ASSERT(innermost_function().IsAsyncClosure() || 8666 ASSERT(innermost_function().IsAsyncClosure() ||
8697 innermost_function().IsAsyncFunction() || 8667 innermost_function().IsAsyncFunction() ||
8698 innermost_function().IsSyncGenClosure() || 8668 innermost_function().IsSyncGenClosure() ||
8699 innermost_function().IsSyncGenerator() || 8669 innermost_function().IsSyncGenerator() ||
8700 innermost_function().IsAsyncGenClosure() || 8670 innermost_function().IsAsyncGenClosure() ||
8701 innermost_function().IsAsyncGenerator()); 8671 innermost_function().IsAsyncGenerator());
8702 8672
8703 ASSERT(saved_exception_var != NULL); 8673 ASSERT(saved_exception_var != NULL);
8704 ASSERT(exception_var != NULL); 8674 ASSERT(exception_var != NULL);
8705 current_block_->statements->Add(new(Z) StoreLocalNode( 8675 statements->Add(new(Z) StoreLocalNode(
8706 Scanner::kNoSourcePos, 8676 Scanner::kNoSourcePos,
8707 saved_exception_var, 8677 saved_exception_var,
8708 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); 8678 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var)));
8709 8679
8710 ASSERT(saved_stack_trace_var != NULL); 8680 ASSERT(saved_stack_trace_var != NULL);
8711 ASSERT(stack_trace_var != NULL); 8681 ASSERT(stack_trace_var != NULL);
8712 current_block_->statements->Add(new(Z) StoreLocalNode( 8682 statements->Add(new(Z) StoreLocalNode(
8713 Scanner::kNoSourcePos, 8683 Scanner::kNoSourcePos,
8714 saved_stack_trace_var, 8684 saved_stack_trace_var,
8715 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); 8685 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
8716 } 8686 }
8717 8687
8718 8688
8719 SequenceNode* Parser::ParseFinallyBlock() { 8689 SequenceNode* Parser::ParseFinallyBlock(
8690 bool is_async,
8691 LocalVariable* exception_var,
8692 LocalVariable* stack_trace_var,
8693 LocalVariable* rethrow_exception_var,
8694 LocalVariable* rethrow_stack_trace_var) {
8720 TRACE_PARSER("ParseFinallyBlock"); 8695 TRACE_PARSER("ParseFinallyBlock");
8721 OpenBlock(); 8696 OpenBlock();
8722 ExpectToken(Token::kLBRACE); 8697 ExpectToken(Token::kLBRACE);
8723 8698
8724 // In case of async closures we need to restore the saved try index of an 8699 // In case of async closures we need to restore the saved try index of an
8725 // outer try block (if it exists). The current try block has already been 8700 // outer try block (if it exists). The current try block has already been
8726 // removed from the stack of try blocks. 8701 // removed from the stack of try blocks.
8727 if ((innermost_function().IsAsyncClosure() || 8702 if (is_async && (try_blocks_list_ != NULL)) {
8728 innermost_function().IsAsyncFunction() ||
8729 innermost_function().IsSyncGenClosure() ||
8730 innermost_function().IsSyncGenerator() ||
8731 innermost_function().IsAsyncGenerator() ||
8732 innermost_function().IsAsyncGenClosure()) &&
8733 (try_blocks_list_ != NULL)) {
8734 LocalScope* scope = try_blocks_list_->try_block()->scope; 8703 LocalScope* scope = try_blocks_list_->try_block()->scope;
8735 if (scope->function_level() == current_block_->scope->function_level()) { 8704 if (scope->function_level() == current_block_->scope->function_level()) {
8736 current_block_->statements->Add( 8705 current_block_->statements->Add(
8737 AwaitTransformer::RestoreSavedTryContext( 8706 AwaitTransformer::RestoreSavedTryContext(
8738 Z, scope->parent(), try_blocks_list_->try_index())); 8707 Z, scope->parent(), try_blocks_list_->try_index()));
8739 } 8708 }
8709 SaveExceptionAndStacktrace(current_block_->statements,
hausner 2015/03/03 23:19:11 Strictly speaking, this is only necessary if the f
regis 2015/03/03 23:47:09 Yes, I added a comment and a TODO(hausner) :-) I
8710 exception_var,
8711 stack_trace_var,
8712 rethrow_exception_var,
8713 rethrow_stack_trace_var);
8740 } 8714 }
8741 8715
8742 ParseStatementSequence(); 8716 ParseStatementSequence();
8743 ExpectToken(Token::kRBRACE); 8717 ExpectToken(Token::kRBRACE);
8744 SequenceNode* finally_block = CloseBlock(); 8718 SequenceNode* finally_block = CloseBlock();
8745 return finally_block; 8719 return finally_block;
8746 } 8720 }
8747 8721
8748 8722
8749 void Parser::PushTryBlock(Block* try_block) { 8723 void Parser::PushTryBlock(Block* try_block) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
8798 return; 8772 return;
8799 } 8773 }
8800 JumpNode* jump_node = node->AsJumpNode(); 8774 JumpNode* jump_node = node->AsJumpNode();
8801 ASSERT(jump_node != NULL); 8775 ASSERT(jump_node != NULL);
8802 jump_node->AddInlinedFinallyNode(finally_node); 8776 jump_node->AddInlinedFinallyNode(finally_node);
8803 } 8777 }
8804 8778
8805 8779
8806 SequenceNode* Parser::ParseCatchClauses( 8780 SequenceNode* Parser::ParseCatchClauses(
8807 intptr_t handler_pos, 8781 intptr_t handler_pos,
8782 bool is_async,
8808 LocalVariable* exception_var, 8783 LocalVariable* exception_var,
8809 LocalVariable* stack_trace_var, 8784 LocalVariable* stack_trace_var,
8810 LocalVariable* rethrow_exception_var, 8785 LocalVariable* rethrow_exception_var,
8811 LocalVariable* rethrow_stack_trace_var, 8786 LocalVariable* rethrow_stack_trace_var,
8812 const GrowableObjectArray& handler_types, 8787 const GrowableObjectArray& handler_types,
8813 bool* needs_stack_trace) { 8788 bool* needs_stack_trace) {
8814 // All catch blocks are merged into an if-then-else sequence of the 8789 // All catch blocks are merged into an if-then-else sequence of the
8815 // different types specified using the 'is' operator. While parsing 8790 // different types specified using the 'is' operator. While parsing
8816 // record the type tests (either a ComparisonNode or else the LiteralNode 8791 // record the type tests (either a ComparisonNode or else the LiteralNode
8817 // true for a generic catch) and the catch bodies in a pair of parallel 8792 // true for a generic catch) and the catch bodies in a pair of parallel
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
8875 ASSERT(stack_trace_var != NULL); 8850 ASSERT(stack_trace_var != NULL);
8876 current_block_->statements->Add(new(Z) StoreLocalNode( 8851 current_block_->statements->Add(new(Z) StoreLocalNode(
8877 catch_pos, stack_trace_param.var, new(Z) LoadLocalNode( 8852 catch_pos, stack_trace_param.var, new(Z) LoadLocalNode(
8878 catch_pos, stack_trace_var))); 8853 catch_pos, stack_trace_var)));
8879 } 8854 }
8880 8855
8881 // Add nested block with user-defined code. This block allows 8856 // Add nested block with user-defined code. This block allows
8882 // declarations in the body to shadow the catch parameters. 8857 // declarations in the body to shadow the catch parameters.
8883 CheckToken(Token::kLBRACE); 8858 CheckToken(Token::kLBRACE);
8884 8859
8885 // In case of async closures we need to restore the saved try index of an
8886 // outer try block (if it exists).
8887 ASSERT(try_blocks_list_ != NULL);
8888 if (innermost_function().IsAsyncClosure() ||
8889 innermost_function().IsAsyncFunction() ||
8890 innermost_function().IsSyncGenClosure() ||
8891 innermost_function().IsSyncGenerator() ||
8892 innermost_function().IsAsyncGenerator() ||
8893 innermost_function().IsAsyncGenClosure()) {
8894 const TryBlocks* try_block = try_blocks_list_->outer_try_block();
8895 if (try_block != NULL) {
8896 LocalScope* scope = try_block->try_block()->scope;
8897 if (scope->function_level() ==
8898 current_block_->scope->function_level()) {
8899 current_block_->statements->Add(
8900 AwaitTransformer::RestoreSavedTryContext(
8901 Z, scope->parent(), try_block->try_index()));
8902 }
8903 }
8904 SaveExceptionAndStacktrace(exception_var,
8905 stack_trace_var,
8906 rethrow_exception_var,
8907 rethrow_stack_trace_var);
8908 }
8909
8910 current_block_->statements->Add(ParseNestedStatement(false, NULL)); 8860 current_block_->statements->Add(ParseNestedStatement(false, NULL));
8911 catch_blocks.Add(CloseBlock()); 8861 catch_blocks.Add(CloseBlock());
8912 8862
8913 const bool is_bad_type = 8863 const bool is_bad_type =
8914 exception_param.type->IsMalformed() || 8864 exception_param.type->IsMalformed() ||
8915 exception_param.type->IsMalbounded(); 8865 exception_param.type->IsMalbounded();
8916 if (exception_param.type->IsDynamicType() || is_bad_type) { 8866 if (exception_param.type->IsDynamicType() || is_bad_type) {
8917 // There is no exception type or else it is malformed or malbounded. 8867 // There is no exception type or else it is malformed or malbounded.
8918 // In the first case, unconditionally execute the catch body. In the 8868 // In the first case, unconditionally execute the catch body. In the
8919 // second case, unconditionally throw. 8869 // second case, unconditionally throw.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
8993 } 8943 }
8994 // If the last body was entered conditionally and there is no need to add 8944 // If the last body was entered conditionally and there is no need to add
8995 // a rethrow, use an empty else body (current = NULL above). 8945 // a rethrow, use an empty else body (current = NULL above).
8996 while (!type_tests.is_empty()) { 8946 while (!type_tests.is_empty()) {
8997 AstNode* type_test = type_tests.RemoveLast(); 8947 AstNode* type_test = type_tests.RemoveLast();
8998 SequenceNode* catch_block = catch_blocks.RemoveLast(); 8948 SequenceNode* catch_block = catch_blocks.RemoveLast();
8999 current_block_->statements->Add(new(Z) IfNode( 8949 current_block_->statements->Add(new(Z) IfNode(
9000 type_test->token_pos(), type_test, catch_block, current)); 8950 type_test->token_pos(), type_test, catch_block, current));
9001 current = CloseBlock(); 8951 current = CloseBlock();
9002 } 8952 }
9003 // Restore :saved_try_context_var before executing the catch clauses. 8953 // In case of async closures, restore :saved_try_context_var before executing
8954 // the catch clauses.
9004 if (current != NULL) { 8955 if (current != NULL) {
hausner 2015/03/03 23:19:11 Can this be simplified to if (is_async && (current
regis 2015/03/03 23:47:09 Done.
9005 ASSERT(try_blocks_list_ != NULL); 8956 ASSERT(try_blocks_list_ != NULL);
9006 if (innermost_function().IsAsyncClosure() || 8957 if (is_async) {
9007 innermost_function().IsAsyncFunction() || 8958 SequenceNode* async_code = new(Z) SequenceNode(handler_pos, NULL);
9008 innermost_function().IsSyncGenClosure() ||
9009 innermost_function().IsSyncGenerator() ||
9010 innermost_function().IsAsyncGenerator() ||
9011 innermost_function().IsAsyncGenClosure()) {
9012 const TryBlocks* try_block = try_blocks_list_->outer_try_block(); 8959 const TryBlocks* try_block = try_blocks_list_->outer_try_block();
9013 if (try_block != NULL) { 8960 if (try_block != NULL) {
9014 LocalScope* scope = try_block->try_block()->scope; 8961 LocalScope* scope = try_block->try_block()->scope;
9015 if (scope->function_level() == 8962 if (scope->function_level() ==
9016 current_block_->scope->function_level()) { 8963 current_block_->scope->function_level()) {
9017 SequenceNode* restore_code = new(Z) SequenceNode(handler_pos, NULL); 8964 async_code->Add(
9018 restore_code->Add(
9019 AwaitTransformer::RestoreSavedTryContext( 8965 AwaitTransformer::RestoreSavedTryContext(
9020 Z, scope->parent(), try_block->try_index())); 8966 Z, scope->parent(), try_block->try_index()));
9021 restore_code->Add(current);
9022 current = restore_code;
9023 } 8967 }
9024 } 8968 }
8969 SaveExceptionAndStacktrace(async_code,
Ivan Posva 2015/03/03 22:57:57 Please add comment what is being saved here and wh
regis 2015/03/03 23:47:09 Done.
8970 exception_var,
8971 stack_trace_var,
8972 rethrow_exception_var,
8973 rethrow_stack_trace_var);
8974 async_code->Add(current);
8975 current = async_code;
9025 } 8976 }
9026 } 8977 }
9027 return current; 8978 return current;
9028 } 8979 }
9029 8980
9030 8981
9031 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { 8982 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) {
9032 const String& async_saved_try_ctx_name = String::ZoneHandle(Z, 8983 const String& async_saved_try_ctx_name = String::ZoneHandle(Z,
9033 Symbols::New(String::Handle(Z, 8984 Symbols::New(String::Handle(Z,
9034 String::NewFormatted("%s%d", 8985 String::NewFormatted("%s%d",
(...skipping 10 matching lines...) Expand all
9045 async_saved_try_ctx_name, false); 8996 async_saved_try_ctx_name, false);
9046 ASSERT(async_saved_try_ctx != NULL); 8997 ASSERT(async_saved_try_ctx != NULL);
9047 ASSERT(saved_try_context != NULL); 8998 ASSERT(saved_try_context != NULL);
9048 current_block_->statements->Add(new(Z) StoreLocalNode( 8999 current_block_->statements->Add(new(Z) StoreLocalNode(
9049 Scanner::kNoSourcePos, 9000 Scanner::kNoSourcePos,
9050 async_saved_try_ctx, 9001 async_saved_try_ctx,
9051 new(Z) LoadLocalNode(Scanner::kNoSourcePos, saved_try_context))); 9002 new(Z) LoadLocalNode(Scanner::kNoSourcePos, saved_try_context)));
9052 } 9003 }
9053 9004
9054 9005
9006 // We create three variables for exceptions:
9007 // ':saved_try_context_var' - Used to save the context before the start of
9008 // the try block. The context register is
9009 // restored from this variable before
9010 // processing the catch block handler.
9011 // ':exception_var' - Used to save the current exception object that was
9012 // thrown.
9013 // ':stack_trace_var' - Used to save the current stack trace object which
9014 // the stack trace was copied into when an exception
9015 // was thrown.
9016 // :exception_var and :stack_trace_var get set with the exception object
9017 // and the stack trace object when an exception is thrown. These three
9018 // implicit variables can never be captured.
9019 //
9020 // In case of async code, we create two additional variables:
9021 // ':saved_exception_var' - Used to capture the exception object above.
9022 // ':saved_stack_trace_var' - Used to capture the stack trace object above.
9023 void Parser::SetupExceptionVariables(LocalScope* try_scope,
9024 bool is_async,
9025 LocalVariable** context_var,
9026 LocalVariable** exception_var,
9027 LocalVariable** stack_trace_var,
9028 LocalVariable** saved_exception_var,
9029 LocalVariable** saved_stack_trace_var) {
9030 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
9031 // Consecutive try statements share the same set of variables.
9032 *context_var = try_scope->LocalLookupVariable(Symbols::SavedTryContextVar());
9033 if (*context_var == NULL) {
9034 *context_var = new(Z) LocalVariable(
9035 TokenPos(),
9036 Symbols::SavedTryContextVar(),
9037 dynamic_type);
9038 try_scope->AddVariable(*context_var);
9039 }
9040 *exception_var = try_scope->LocalLookupVariable(Symbols::ExceptionVar());
9041 if (*exception_var == NULL) {
9042 *exception_var = new(Z) LocalVariable(
9043 TokenPos(),
9044 Symbols::ExceptionVar(),
9045 dynamic_type);
9046 try_scope->AddVariable(*exception_var);
9047 }
9048 *stack_trace_var = try_scope->LocalLookupVariable(Symbols::StackTraceVar());
9049 if (*stack_trace_var == NULL) {
9050 *stack_trace_var = new(Z) LocalVariable(
9051 TokenPos(),
9052 Symbols::StackTraceVar(),
9053 dynamic_type);
9054 try_scope->AddVariable(*stack_trace_var);
9055 }
9056 if (is_async) {
9057 *saved_exception_var = try_scope->LocalLookupVariable(
9058 Symbols::SavedExceptionVar());
9059 if (*saved_exception_var == NULL) {
9060 *saved_exception_var = new(Z) LocalVariable(
9061 TokenPos(),
9062 Symbols::SavedExceptionVar(),
9063 dynamic_type);
9064 try_scope->AddVariable(*saved_exception_var);
9065 }
9066 *saved_stack_trace_var = try_scope->LocalLookupVariable(
9067 Symbols::SavedStackTraceVar());
9068 if (*saved_stack_trace_var == NULL) {
9069 *saved_stack_trace_var = new(Z) LocalVariable(
9070 TokenPos(),
9071 Symbols::SavedStackTraceVar(),
9072 dynamic_type);
9073 try_scope->AddVariable(*saved_stack_trace_var);
9074 }
9075 }
9076 }
9077
9078
9055 AstNode* Parser::ParseTryStatement(String* label_name) { 9079 AstNode* Parser::ParseTryStatement(String* label_name) {
9056 TRACE_PARSER("ParseTryStatement"); 9080 TRACE_PARSER("ParseTryStatement");
9057
9058 // We create three variables for exceptions here:
9059 // ':saved_try_context_var' - Used to save the context before the start of
9060 // the try block. The context register is
9061 // restored from this variable before
9062 // processing the catch block handler.
9063 // ':exception_var' - Used to save the current exception object that was
9064 // thrown.
9065 // ':stack_trace_var' - Used to save the current stack trace object which
9066 // the stack trace was copied into when an exception
9067 // was thrown.
9068 // :exception_var and :stack_trace_var get set with the exception object
9069 // and the stack trace object when an exception is thrown. These three
9070 // implicit variables can never be captured.
9071 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
9072 // Consecutive try statements share the same set of variables.
9073 LocalVariable* context_var =
9074 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar());
9075 if (context_var == NULL) {
9076 context_var = new(Z) LocalVariable(
9077 TokenPos(),
9078 Symbols::SavedTryContextVar(),
9079 dynamic_type);
9080 current_block_->scope->AddVariable(context_var);
9081 }
9082 LocalVariable* exception_var =
9083 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar());
9084 if (exception_var == NULL) {
9085 exception_var = new(Z) LocalVariable(
9086 TokenPos(),
9087 Symbols::ExceptionVar(),
9088 dynamic_type);
9089 current_block_->scope->AddVariable(exception_var);
9090 }
9091 LocalVariable* stack_trace_var =
9092 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar());
9093 if (stack_trace_var == NULL) {
9094 stack_trace_var = new(Z) LocalVariable(
9095 TokenPos(),
9096 Symbols::StackTraceVar(),
9097 dynamic_type);
9098 current_block_->scope->AddVariable(stack_trace_var);
9099 }
9100 LocalVariable* saved_exception_var = NULL;
9101 LocalVariable* saved_stack_trace_var = NULL;
9102 const bool is_async = innermost_function().IsAsyncClosure() || 9081 const bool is_async = innermost_function().IsAsyncClosure() ||
9103 innermost_function().IsAsyncFunction() || 9082 innermost_function().IsAsyncFunction() ||
9104 innermost_function().IsSyncGenClosure() || 9083 innermost_function().IsSyncGenClosure() ||
9105 innermost_function().IsSyncGenerator() || 9084 innermost_function().IsSyncGenerator() ||
9106 innermost_function().IsAsyncGenClosure() || 9085 innermost_function().IsAsyncGenClosure() ||
9107 innermost_function().IsAsyncGenerator(); 9086 innermost_function().IsAsyncGenerator();
9108 if (is_async) { 9087 LocalVariable* context_var = NULL;
9109 saved_exception_var = current_block_->scope->LocalLookupVariable( 9088 LocalVariable* exception_var = NULL;
9110 Symbols::SavedExceptionVar()); 9089 LocalVariable* stack_trace_var = NULL;
9111 if (saved_exception_var == NULL) { 9090 LocalVariable* saved_exception_var = NULL;
9112 saved_exception_var = new(Z) LocalVariable( 9091 LocalVariable* saved_stack_trace_var = NULL;
9113 TokenPos(), 9092 SetupExceptionVariables(current_block_->scope,
9114 Symbols::SavedExceptionVar(), 9093 is_async,
9115 dynamic_type); 9094 &context_var,
9116 current_block_->scope->AddVariable(saved_exception_var); 9095 &exception_var,
9117 } 9096 &stack_trace_var,
9118 saved_stack_trace_var = current_block_->scope->LocalLookupVariable( 9097 &saved_exception_var,
9119 Symbols::SavedStackTraceVar()); 9098 &saved_stack_trace_var);
9120 if (saved_stack_trace_var == NULL) {
9121 saved_stack_trace_var = new(Z) LocalVariable(
9122 TokenPos(),
9123 Symbols::SavedStackTraceVar(),
9124 dynamic_type);
9125 current_block_->scope->AddVariable(saved_stack_trace_var);
9126 }
9127 }
9128 9099
9129 const intptr_t try_pos = TokenPos(); 9100 const intptr_t try_pos = TokenPos();
9130 ConsumeToken(); // Consume the 'try'. 9101 ConsumeToken(); // Consume the 'try'.
9131 9102
9132 SourceLabel* try_label = NULL; 9103 SourceLabel* try_label = NULL;
9133 if (label_name != NULL) { 9104 if (label_name != NULL) {
9134 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); 9105 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement);
9135 OpenBlock(); 9106 OpenBlock();
9136 current_block_->scope->AddLabel(try_label); 9107 current_block_->scope->AddLabel(try_label);
9137 } 9108 }
(...skipping 16 matching lines...) Expand all
9154 ReportError("catch or finally clause expected"); 9125 ReportError("catch or finally clause expected");
9155 } 9126 }
9156 9127
9157 // Now parse the 'catch' blocks if any. 9128 // Now parse the 'catch' blocks if any.
9158 try_blocks_list_->enter_catch(); 9129 try_blocks_list_->enter_catch();
9159 const intptr_t handler_pos = TokenPos(); 9130 const intptr_t handler_pos = TokenPos();
9160 const GrowableObjectArray& handler_types = 9131 const GrowableObjectArray& handler_types =
9161 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); 9132 GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
9162 bool needs_stack_trace = false; 9133 bool needs_stack_trace = false;
9163 SequenceNode* catch_handler_list = 9134 SequenceNode* catch_handler_list =
9164 ParseCatchClauses(handler_pos, exception_var, stack_trace_var, 9135 ParseCatchClauses(handler_pos,
9136 is_async,
9137 exception_var,
9138 stack_trace_var,
9165 is_async ? saved_exception_var : exception_var, 9139 is_async ? saved_exception_var : exception_var,
9166 is_async ? saved_stack_trace_var : stack_trace_var, 9140 is_async ? saved_stack_trace_var : stack_trace_var,
9167 handler_types, &needs_stack_trace); 9141 handler_types,
9142 &needs_stack_trace);
9168 9143
9169 TryBlocks* inner_try_block = PopTryBlock(); 9144 TryBlocks* inner_try_block = PopTryBlock();
9170 const intptr_t try_index = inner_try_block->try_index(); 9145 const intptr_t try_index = inner_try_block->try_index();
9171 TryBlocks* outer_try_block = try_blocks_list_; 9146 TryBlocks* outer_try_block = try_blocks_list_;
9172 const intptr_t outer_try_index = (outer_try_block != NULL) 9147 const intptr_t outer_try_index = (outer_try_block != NULL)
9173 ? outer_try_block->try_index() 9148 ? outer_try_block->try_index()
9174 : CatchClauseNode::kInvalidTryIndex; 9149 : CatchClauseNode::kInvalidTryIndex;
9175 9150
9176 // Finally parse the 'finally' block. 9151 // Finally parse the 'finally' block.
9177 SequenceNode* finally_block = NULL; 9152 SequenceNode* finally_block = NULL;
9178 if (CurrentToken() == Token::kFINALLY) { 9153 if (CurrentToken() == Token::kFINALLY) {
9179 ConsumeToken(); // Consume the 'finally'. 9154 ConsumeToken(); // Consume the 'finally'.
9180 const intptr_t finally_pos = TokenPos(); 9155 const intptr_t finally_pos = TokenPos();
9181 // Add the finally block to the exit points recorded so far. 9156 // Add the finally block to the exit points recorded so far.
9182 intptr_t node_index = 0; 9157 intptr_t node_index = 0;
9183 AstNode* node_to_inline = 9158 AstNode* node_to_inline =
9184 inner_try_block->GetNodeToInlineFinally(node_index); 9159 inner_try_block->GetNodeToInlineFinally(node_index);
9185 while (node_to_inline != NULL) { 9160 while (node_to_inline != NULL) {
9186 finally_block = ParseFinallyBlock(); 9161 finally_block = ParseFinallyBlock(
9162 is_async,
9163 exception_var,
9164 stack_trace_var,
9165 is_async ? saved_exception_var : exception_var,
9166 is_async ? saved_stack_trace_var : stack_trace_var);
9187 InlinedFinallyNode* node = new(Z) InlinedFinallyNode(finally_pos, 9167 InlinedFinallyNode* node = new(Z) InlinedFinallyNode(finally_pos,
9188 finally_block, 9168 finally_block,
9189 context_var, 9169 context_var,
9190 outer_try_index); 9170 outer_try_index);
9191 AddFinallyBlockToNode(node_to_inline, node); 9171 AddFinallyBlockToNode(node_to_inline, node);
9192 node_index += 1; 9172 node_index += 1;
9193 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); 9173 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index);
9194 tokens_iterator_.SetCurrentPosition(finally_pos); 9174 tokens_iterator_.SetCurrentPosition(finally_pos);
9195 } 9175 }
9196 finally_block = ParseFinallyBlock(); 9176 finally_block = ParseFinallyBlock(
9177 is_async,
9178 exception_var,
9179 stack_trace_var,
9180 is_async ? saved_exception_var : exception_var,
9181 is_async ? saved_stack_trace_var : stack_trace_var);
9197 } 9182 }
9198 9183
9199 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( 9184 CatchClauseNode* catch_clause = new(Z) CatchClauseNode(
9200 handler_pos, 9185 handler_pos,
9201 catch_handler_list, 9186 catch_handler_list,
9202 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), 9187 Array::ZoneHandle(Z, Array::MakeArray(handler_types)),
9203 context_var, 9188 context_var,
9204 exception_var, 9189 exception_var,
9205 stack_trace_var, 9190 stack_trace_var,
9206 is_async ? saved_exception_var : exception_var, 9191 is_async ? saved_exception_var : exception_var,
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
9539 // instead of :exception_var and :stack_trace_var. 9524 // instead of :exception_var and :stack_trace_var.
9540 // These variables are bound in the block containing the try. 9525 // These variables are bound in the block containing the try.
9541 // Look in the try scope directly. 9526 // Look in the try scope directly.
9542 LocalScope* scope = try_blocks_list_->try_block()->scope->parent(); 9527 LocalScope* scope = try_blocks_list_->try_block()->scope->parent();
9543 ASSERT(scope != NULL); 9528 ASSERT(scope != NULL);
9544 LocalVariable* excp_var; 9529 LocalVariable* excp_var;
9545 LocalVariable* trace_var; 9530 LocalVariable* trace_var;
9546 if (innermost_function().IsAsyncClosure() || 9531 if (innermost_function().IsAsyncClosure() ||
9547 innermost_function().IsAsyncFunction() || 9532 innermost_function().IsAsyncFunction() ||
9548 innermost_function().IsSyncGenClosure() || 9533 innermost_function().IsSyncGenClosure() ||
9549 innermost_function().IsSyncGenerator()) { 9534 innermost_function().IsSyncGenerator()) {
regis 2015/03/03 23:47:09 Matthias, is the list above correct?
regis 2015/03/03 23:54:45 OK, I'm submitting, but we should verify all the l
hausner 2015/03/03 23:59:40 Good catch. It seems that we also need to include
9550 excp_var = scope->LocalLookupVariable(Symbols::SavedExceptionVar()); 9535 excp_var = scope->LocalLookupVariable(Symbols::SavedExceptionVar());
9551 trace_var = scope->LocalLookupVariable(Symbols::SavedStackTraceVar()); 9536 trace_var = scope->LocalLookupVariable(Symbols::SavedStackTraceVar());
9552 } else { 9537 } else {
9553 excp_var = scope->LocalLookupVariable(Symbols::ExceptionVar()); 9538 excp_var = scope->LocalLookupVariable(Symbols::ExceptionVar());
9554 trace_var = scope->LocalLookupVariable(Symbols::StackTraceVar()); 9539 trace_var = scope->LocalLookupVariable(Symbols::StackTraceVar());
9555 } 9540 }
9556 ASSERT(excp_var != NULL); 9541 ASSERT(excp_var != NULL);
9557 ASSERT(trace_var != NULL); 9542 ASSERT(trace_var != NULL);
9558 9543
9559 statement = new(Z) ThrowNode( 9544 statement = new(Z) ThrowNode(
(...skipping 3636 matching lines...) Expand 10 before | Expand all | Expand 10 after
13196 void Parser::SkipQualIdent() { 13181 void Parser::SkipQualIdent() {
13197 ASSERT(IsIdentifier()); 13182 ASSERT(IsIdentifier());
13198 ConsumeToken(); 13183 ConsumeToken();
13199 if (CurrentToken() == Token::kPERIOD) { 13184 if (CurrentToken() == Token::kPERIOD) {
13200 ConsumeToken(); // Consume the kPERIOD token. 13185 ConsumeToken(); // Consume the kPERIOD token.
13201 ExpectIdentifier("identifier expected after '.'"); 13186 ExpectIdentifier("identifier expected after '.'");
13202 } 13187 }
13203 } 13188 }
13204 13189
13205 } // namespace dart 13190 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698