Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |