| 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 6016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6027 ASSERT(stack_trace_var != NULL); | 6027 ASSERT(stack_trace_var != NULL); |
| 6028 if (stack_trace_param.var != NULL) { | 6028 if (stack_trace_param.var != NULL) { |
| 6029 // A stack trace variable is specified in this block, so generate code | 6029 // 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 | 6030 // to load the stack trace object (:stack_trace_var) into the stack |
| 6031 // trace variable specified in this block. | 6031 // trace variable specified in this block. |
| 6032 current_block_->statements->Add(new(Z) StoreLocalNode( | 6032 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 6033 Scanner::kNoSourcePos, | 6033 Scanner::kNoSourcePos, |
| 6034 stack_trace_param.var, | 6034 stack_trace_param.var, |
| 6035 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); | 6035 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); |
| 6036 } | 6036 } |
| 6037 | 6037 LocalVariable* saved_exception_var = current_block_->scope->LookupVariable( |
| 6038 SaveExceptionAndStacktrace(exception_var, stack_trace_var); | 6038 Symbols::SavedExceptionVar(), false); |
| 6039 LocalVariable* saved_stack_trace_var = current_block_->scope->LookupVariable( |
| 6040 Symbols::SavedStackTraceVar(), false); |
| 6041 SaveExceptionAndStacktrace(exception_var, |
| 6042 stack_trace_var, |
| 6043 saved_exception_var, |
| 6044 saved_stack_trace_var); |
| 6039 | 6045 |
| 6040 // Catch block: add the error to the stream. | 6046 // Catch block: add the error to the stream. |
| 6041 // :controller.AddError(:exception, :stack_trace); | 6047 // :controller.AddError(:exception, :stack_trace); |
| 6042 // return; // The finally block will close the stream. | 6048 // return; // The finally block will close the stream. |
| 6043 LocalVariable* controller = | 6049 LocalVariable* controller = |
| 6044 current_block_->scope->LookupVariable(Symbols::Controller(), false); | 6050 current_block_->scope->LookupVariable(Symbols::Controller(), false); |
| 6045 ASSERT(controller != NULL); | 6051 ASSERT(controller != NULL); |
| 6046 ArgumentListNode* args = | 6052 ArgumentListNode* args = |
| 6047 new(Z) ArgumentListNode(Scanner::kNoSourcePos); | 6053 new(Z) ArgumentListNode(Scanner::kNoSourcePos); |
| 6048 args->Add(new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var)); | 6054 args->Add(new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var)); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6102 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); | 6108 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| 6103 handler_types.Add(dynamic_type); // Catch block handles all exceptions. | 6109 handler_types.Add(dynamic_type); // Catch block handles all exceptions. |
| 6104 | 6110 |
| 6105 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( | 6111 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( |
| 6106 Scanner::kNoSourcePos, | 6112 Scanner::kNoSourcePos, |
| 6107 catch_handler_list, | 6113 catch_handler_list, |
| 6108 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), | 6114 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), |
| 6109 context_var, | 6115 context_var, |
| 6110 exception_var, | 6116 exception_var, |
| 6111 stack_trace_var, | 6117 stack_trace_var, |
| 6118 saved_exception_var, |
| 6119 saved_stack_trace_var, |
| 6112 AllocateTryIndex(), | 6120 AllocateTryIndex(), |
| 6113 true); | 6121 true); |
| 6114 | 6122 |
| 6115 const intptr_t try_index = try_block->try_index(); | 6123 const intptr_t try_index = try_block->try_index(); |
| 6116 | 6124 |
| 6117 AstNode* try_catch_node = | 6125 AstNode* try_catch_node = |
| 6118 new(Z) TryCatchNode(Scanner::kNoSourcePos, | 6126 new(Z) TryCatchNode(Scanner::kNoSourcePos, |
| 6119 body, | 6127 body, |
| 6120 context_var, | 6128 context_var, |
| 6121 catch_clause, | 6129 catch_clause, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6171 if (stack_trace_param.var != NULL) { | 6179 if (stack_trace_param.var != NULL) { |
| 6172 // A stack trace variable is specified in this block, so generate code | 6180 // A stack trace variable is specified in this block, so generate code |
| 6173 // to load the stack trace object (:stack_trace_var) into the stack | 6181 // to load the stack trace object (:stack_trace_var) into the stack |
| 6174 // trace variable specified in this block. | 6182 // trace variable specified in this block. |
| 6175 ASSERT(stack_trace_var != NULL); | 6183 ASSERT(stack_trace_var != NULL); |
| 6176 current_block_->statements->Add(new(Z) StoreLocalNode( | 6184 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 6177 Scanner::kNoSourcePos, | 6185 Scanner::kNoSourcePos, |
| 6178 stack_trace_param.var, | 6186 stack_trace_param.var, |
| 6179 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); | 6187 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); |
| 6180 } | 6188 } |
| 6181 | 6189 LocalVariable* saved_exception_var = current_block_->scope->LookupVariable( |
| 6182 SaveExceptionAndStacktrace(exception_var, stack_trace_var); | 6190 Symbols::SavedExceptionVar(), false); |
| 6191 LocalVariable* saved_stack_trace_var = current_block_->scope->LookupVariable( |
| 6192 Symbols::SavedStackTraceVar(), false); |
| 6193 SaveExceptionAndStacktrace(exception_var, |
| 6194 stack_trace_var, |
| 6195 saved_exception_var, |
| 6196 saved_stack_trace_var); |
| 6183 | 6197 |
| 6184 // Complete the async future with an error. This catch block executes | 6198 // Complete the async future with an error. This catch block executes |
| 6185 // unconditionally, there is no need to generate a type check for. | 6199 // unconditionally, there is no need to generate a type check for. |
| 6186 LocalVariable* async_completer = current_block_->scope->LookupVariable( | 6200 LocalVariable* async_completer = current_block_->scope->LookupVariable( |
| 6187 Symbols::AsyncCompleter(), false); | 6201 Symbols::AsyncCompleter(), false); |
| 6188 ASSERT(async_completer != NULL); | 6202 ASSERT(async_completer != NULL); |
| 6189 ArgumentListNode* completer_args = | 6203 ArgumentListNode* completer_args = |
| 6190 new (Z) ArgumentListNode(Scanner::kNoSourcePos); | 6204 new (Z) ArgumentListNode(Scanner::kNoSourcePos); |
| 6191 completer_args->Add( | 6205 completer_args->Add( |
| 6192 new (Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var)); | 6206 new (Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 6213 TryBlocks* inner_try_block = PopTryBlock(); | 6227 TryBlocks* inner_try_block = PopTryBlock(); |
| 6214 const intptr_t try_index = inner_try_block->try_index(); | 6228 const intptr_t try_index = inner_try_block->try_index(); |
| 6215 | 6229 |
| 6216 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( | 6230 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( |
| 6217 Scanner::kNoSourcePos, | 6231 Scanner::kNoSourcePos, |
| 6218 catch_handler_list, | 6232 catch_handler_list, |
| 6219 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), | 6233 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), |
| 6220 context_var, | 6234 context_var, |
| 6221 exception_var, | 6235 exception_var, |
| 6222 stack_trace_var, | 6236 stack_trace_var, |
| 6237 saved_exception_var, |
| 6238 saved_stack_trace_var, |
| 6223 CatchClauseNode::kInvalidTryIndex, | 6239 CatchClauseNode::kInvalidTryIndex, |
| 6224 true); | 6240 true); |
| 6225 AstNode* try_catch_node = new (Z) TryCatchNode( | 6241 AstNode* try_catch_node = new (Z) TryCatchNode( |
| 6226 Scanner::kNoSourcePos, | 6242 Scanner::kNoSourcePos, |
| 6227 try_block, | 6243 try_block, |
| 6228 context_var, | 6244 context_var, |
| 6229 catch_clause, | 6245 catch_clause, |
| 6230 NULL, // No finally clause. | 6246 NULL, // No finally clause. |
| 6231 try_index); | 6247 try_index); |
| 6232 current_block_->statements->Add(try_catch_node); | 6248 current_block_->statements->Add(try_catch_node); |
| 6233 return CloseBlock(); | 6249 return CloseBlock(); |
| 6234 } | 6250 } |
| 6235 | 6251 |
| 6236 | 6252 |
| 6237 // Wrap the body of the async or arync* closure in a try/catch block. | 6253 // Wrap the body of the async or arync* closure in a try/catch block. |
| 6238 void Parser::OpenAsyncTryBlock() { | 6254 void Parser::OpenAsyncTryBlock() { |
| 6239 ASSERT(innermost_function().IsAsyncClosure() || | 6255 ASSERT(innermost_function().IsAsyncClosure() || |
| 6240 innermost_function().IsAsyncGenClosure()); | 6256 innermost_function().IsAsyncGenClosure()); |
| 6241 | 6257 |
| 6258 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 6242 LocalVariable* context_var = | 6259 LocalVariable* context_var = |
| 6243 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); | 6260 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
| 6244 if (context_var == NULL) { | 6261 if (context_var == NULL) { |
| 6245 context_var = new(Z) LocalVariable( | 6262 context_var = new(Z) LocalVariable( |
| 6246 TokenPos(), | 6263 TokenPos(), |
| 6247 Symbols::SavedTryContextVar(), | 6264 Symbols::SavedTryContextVar(), |
| 6248 Type::ZoneHandle(Z, Type::DynamicType())); | 6265 dynamic_type); |
| 6249 current_block_->scope->AddVariable(context_var); | 6266 current_block_->scope->AddVariable(context_var); |
| 6250 } | 6267 } |
| 6251 LocalVariable* exception_var = | 6268 LocalVariable* exception_var = |
| 6252 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); | 6269 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); |
| 6253 if (exception_var == NULL) { | 6270 if (exception_var == NULL) { |
| 6254 exception_var = new(Z) LocalVariable( | 6271 exception_var = new(Z) LocalVariable( |
| 6255 TokenPos(), | 6272 TokenPos(), |
| 6256 Symbols::ExceptionVar(), | 6273 Symbols::ExceptionVar(), |
| 6257 Type::ZoneHandle(Z, Type::DynamicType())); | 6274 dynamic_type); |
| 6258 current_block_->scope->AddVariable(exception_var); | 6275 current_block_->scope->AddVariable(exception_var); |
| 6259 } | 6276 } |
| 6260 LocalVariable* stack_trace_var = | 6277 LocalVariable* stack_trace_var = |
| 6261 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar()); | 6278 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar()); |
| 6262 if (stack_trace_var == NULL) { | 6279 if (stack_trace_var == NULL) { |
| 6263 stack_trace_var = new(Z) LocalVariable( | 6280 stack_trace_var = new(Z) LocalVariable( |
| 6264 TokenPos(), | 6281 TokenPos(), |
| 6265 Symbols::StackTraceVar(), | 6282 Symbols::StackTraceVar(), |
| 6266 Type::ZoneHandle(Z, Type::DynamicType())); | 6283 dynamic_type); |
| 6267 current_block_->scope->AddVariable(stack_trace_var); | 6284 current_block_->scope->AddVariable(stack_trace_var); |
| 6268 } | 6285 } |
| 6269 | 6286 LocalVariable* saved_exception_var = |
| 6270 SetupSavedExceptionAndStacktrace(); | 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 } |
| 6271 | 6304 |
| 6272 // Open the try block. | 6305 // Open the try block. |
| 6273 OpenBlock(); | 6306 OpenBlock(); |
| 6274 // This is the outermost try-catch in the function. | 6307 // This is the outermost try-catch in the function. |
| 6275 ASSERT(try_blocks_list_ == NULL); | 6308 ASSERT(try_blocks_list_ == NULL); |
| 6276 PushTryBlock(current_block_); | 6309 PushTryBlock(current_block_); |
| 6277 | 6310 |
| 6278 SetupSavedTryContext(context_var); | 6311 SetupSavedTryContext(context_var); |
| 6279 } | 6312 } |
| 6280 | 6313 |
| (...skipping 2364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8645 // The name of the exception param is reused for the stack trace param. | 8678 // The name of the exception param is reused for the stack trace param. |
| 8646 ReportError(stack_trace_param->token_pos, | 8679 ReportError(stack_trace_param->token_pos, |
| 8647 "name '%s' already exists in scope", | 8680 "name '%s' already exists in scope", |
| 8648 stack_trace_param->name->ToCString()); | 8681 stack_trace_param->name->ToCString()); |
| 8649 } | 8682 } |
| 8650 stack_trace_param->var = var; | 8683 stack_trace_param->var = var; |
| 8651 } | 8684 } |
| 8652 } | 8685 } |
| 8653 | 8686 |
| 8654 | 8687 |
| 8655 // Populate current scope of the try block with the saved exception and saved | |
| 8656 // stack trace. | |
| 8657 void Parser::SetupSavedExceptionAndStacktrace() { | |
| 8658 ASSERT(innermost_function().IsAsyncClosure() || | |
| 8659 innermost_function().IsAsyncFunction() || | |
| 8660 innermost_function().IsSyncGenClosure() || | |
| 8661 innermost_function().IsSyncGenerator() || | |
| 8662 innermost_function().IsAsyncGenerator() || | |
| 8663 innermost_function().IsAsyncGenClosure()); | |
| 8664 // Add :saved_exception_var and :saved_stack_trace_var to current scope. | |
| 8665 // They will automatically get captured. | |
| 8666 // Parallel try statements share the same set of variables. | |
| 8667 LocalVariable* saved_exception_var = | |
| 8668 current_block_->scope->LocalLookupVariable(Symbols::SavedExceptionVar()); | |
| 8669 if (saved_exception_var == NULL) { | |
| 8670 saved_exception_var = new (Z) LocalVariable( | |
| 8671 Scanner::kNoSourcePos, | |
| 8672 Symbols::SavedExceptionVar(), | |
| 8673 Type::ZoneHandle(Z, Type::DynamicType())); | |
| 8674 saved_exception_var->set_is_final(); | |
| 8675 current_block_->scope->AddVariable(saved_exception_var); | |
| 8676 } | |
| 8677 LocalVariable* saved_stack_trace_var = | |
| 8678 current_block_->scope->LocalLookupVariable(Symbols::SavedStackTraceVar()); | |
| 8679 if (saved_stack_trace_var == NULL) { | |
| 8680 saved_stack_trace_var = new (Z) LocalVariable( | |
| 8681 Scanner::kNoSourcePos, | |
| 8682 Symbols::SavedStackTraceVar(), | |
| 8683 Type::ZoneHandle(Z, Type::DynamicType())); | |
| 8684 saved_exception_var->set_is_final(); | |
| 8685 current_block_->scope->AddVariable(saved_stack_trace_var); | |
| 8686 } | |
| 8687 } | |
| 8688 | |
| 8689 | |
| 8690 // Generate code to load the exception object (:exception_var) into | 8688 // Generate code to load the exception object (:exception_var) into |
| 8691 // the saved exception variable (:saved_exception_var) used to rethrow. | 8689 // the saved exception variable (:saved_exception_var) used to rethrow. |
| 8690 // Generate code to load the stack trace object (:stack_trace_var) into |
| 8691 // the saved stacktrace variable (:saved_stack_trace_var) used to rethrow. |
| 8692 void Parser::SaveExceptionAndStacktrace(LocalVariable* exception_var, | 8692 void Parser::SaveExceptionAndStacktrace(LocalVariable* exception_var, |
| 8693 LocalVariable* stack_trace_var) { | 8693 LocalVariable* stack_trace_var, |
| 8694 LocalVariable* saved_exception_var, |
| 8695 LocalVariable* saved_stack_trace_var) { |
| 8694 ASSERT(innermost_function().IsAsyncClosure() || | 8696 ASSERT(innermost_function().IsAsyncClosure() || |
| 8695 innermost_function().IsAsyncFunction() || | 8697 innermost_function().IsAsyncFunction() || |
| 8696 innermost_function().IsSyncGenClosure() || | 8698 innermost_function().IsSyncGenClosure() || |
| 8697 innermost_function().IsSyncGenerator() || | 8699 innermost_function().IsSyncGenerator() || |
| 8698 innermost_function().IsAsyncGenClosure() || | 8700 innermost_function().IsAsyncGenClosure() || |
| 8699 innermost_function().IsAsyncGenerator()); | 8701 innermost_function().IsAsyncGenerator()); |
| 8700 LocalVariable* saved_exception_var = current_block_->scope->LookupVariable( | 8702 |
| 8701 Symbols::SavedExceptionVar(), false); | |
| 8702 ASSERT(saved_exception_var != NULL); | 8703 ASSERT(saved_exception_var != NULL); |
| 8703 ASSERT(exception_var != NULL); | 8704 ASSERT(exception_var != NULL); |
| 8704 current_block_->statements->Add(new(Z) StoreLocalNode( | 8705 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 8705 Scanner::kNoSourcePos, | 8706 Scanner::kNoSourcePos, |
| 8706 saved_exception_var, | 8707 saved_exception_var, |
| 8707 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); | 8708 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); |
| 8708 | 8709 |
| 8709 // Generate code to load the stack trace object (:stack_trace_var) into | |
| 8710 // the saved stacktrace variable (:saved_stack_trace_var) used to rethrow. | |
| 8711 LocalVariable* saved_stack_trace_var = current_block_->scope->LookupVariable( | |
| 8712 Symbols::SavedStackTraceVar(), false); | |
| 8713 ASSERT(saved_stack_trace_var != NULL); | 8710 ASSERT(saved_stack_trace_var != NULL); |
| 8714 ASSERT(stack_trace_var != NULL); | 8711 ASSERT(stack_trace_var != NULL); |
| 8715 current_block_->statements->Add(new(Z) StoreLocalNode( | 8712 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 8716 Scanner::kNoSourcePos, | 8713 Scanner::kNoSourcePos, |
| 8717 saved_stack_trace_var, | 8714 saved_stack_trace_var, |
| 8718 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); | 8715 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); |
| 8719 } | 8716 } |
| 8720 | 8717 |
| 8721 | 8718 |
| 8722 SequenceNode* Parser::ParseFinallyBlock() { | 8719 SequenceNode* Parser::ParseFinallyBlock() { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8803 JumpNode* jump_node = node->AsJumpNode(); | 8800 JumpNode* jump_node = node->AsJumpNode(); |
| 8804 ASSERT(jump_node != NULL); | 8801 ASSERT(jump_node != NULL); |
| 8805 jump_node->AddInlinedFinallyNode(finally_node); | 8802 jump_node->AddInlinedFinallyNode(finally_node); |
| 8806 } | 8803 } |
| 8807 | 8804 |
| 8808 | 8805 |
| 8809 SequenceNode* Parser::ParseCatchClauses( | 8806 SequenceNode* Parser::ParseCatchClauses( |
| 8810 intptr_t handler_pos, | 8807 intptr_t handler_pos, |
| 8811 LocalVariable* exception_var, | 8808 LocalVariable* exception_var, |
| 8812 LocalVariable* stack_trace_var, | 8809 LocalVariable* stack_trace_var, |
| 8810 LocalVariable* rethrow_exception_var, |
| 8811 LocalVariable* rethrow_stack_trace_var, |
| 8813 const GrowableObjectArray& handler_types, | 8812 const GrowableObjectArray& handler_types, |
| 8814 bool* needs_stack_trace) { | 8813 bool* needs_stack_trace) { |
| 8815 // All catch blocks are merged into an if-then-else sequence of the | 8814 // All catch blocks are merged into an if-then-else sequence of the |
| 8816 // different types specified using the 'is' operator. While parsing | 8815 // different types specified using the 'is' operator. While parsing |
| 8817 // record the type tests (either a ComparisonNode or else the LiteralNode | 8816 // record the type tests (either a ComparisonNode or else the LiteralNode |
| 8818 // true for a generic catch) and the catch bodies in a pair of parallel | 8817 // true for a generic catch) and the catch bodies in a pair of parallel |
| 8819 // lists. Afterward, construct the nested if-then-else. | 8818 // lists. Afterward, construct the nested if-then-else. |
| 8820 bool generic_catch_seen = false; | 8819 bool generic_catch_seen = false; |
| 8821 GrowableArray<AstNode*> type_tests; | 8820 GrowableArray<AstNode*> type_tests; |
| 8822 GrowableArray<SequenceNode*> catch_blocks; | 8821 GrowableArray<SequenceNode*> catch_blocks; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8895 const TryBlocks* try_block = try_blocks_list_->outer_try_block(); | 8894 const TryBlocks* try_block = try_blocks_list_->outer_try_block(); |
| 8896 if (try_block != NULL) { | 8895 if (try_block != NULL) { |
| 8897 LocalScope* scope = try_block->try_block()->scope; | 8896 LocalScope* scope = try_block->try_block()->scope; |
| 8898 if (scope->function_level() == | 8897 if (scope->function_level() == |
| 8899 current_block_->scope->function_level()) { | 8898 current_block_->scope->function_level()) { |
| 8900 current_block_->statements->Add( | 8899 current_block_->statements->Add( |
| 8901 AwaitTransformer::RestoreSavedTryContext( | 8900 AwaitTransformer::RestoreSavedTryContext( |
| 8902 Z, scope->parent(), try_block->try_index())); | 8901 Z, scope->parent(), try_block->try_index())); |
| 8903 } | 8902 } |
| 8904 } | 8903 } |
| 8905 SaveExceptionAndStacktrace(exception_var, stack_trace_var); | 8904 SaveExceptionAndStacktrace(exception_var, |
| 8905 stack_trace_var, |
| 8906 rethrow_exception_var, |
| 8907 rethrow_stack_trace_var); |
| 8906 } | 8908 } |
| 8907 | 8909 |
| 8908 current_block_->statements->Add(ParseNestedStatement(false, NULL)); | 8910 current_block_->statements->Add(ParseNestedStatement(false, NULL)); |
| 8909 catch_blocks.Add(CloseBlock()); | 8911 catch_blocks.Add(CloseBlock()); |
| 8910 | 8912 |
| 8911 const bool is_bad_type = | 8913 const bool is_bad_type = |
| 8912 exception_param.type->IsMalformed() || | 8914 exception_param.type->IsMalformed() || |
| 8913 exception_param.type->IsMalbounded(); | 8915 exception_param.type->IsMalbounded(); |
| 8914 if (exception_param.type->IsDynamicType() || is_bad_type) { | 8916 if (exception_param.type->IsDynamicType() || is_bad_type) { |
| 8915 // There is no exception type or else it is malformed or malbounded. | 8917 // There is no exception type or else it is malformed or malbounded. |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9059 // restored from this variable before | 9061 // restored from this variable before |
| 9060 // processing the catch block handler. | 9062 // processing the catch block handler. |
| 9061 // ':exception_var' - Used to save the current exception object that was | 9063 // ':exception_var' - Used to save the current exception object that was |
| 9062 // thrown. | 9064 // thrown. |
| 9063 // ':stack_trace_var' - Used to save the current stack trace object which | 9065 // ':stack_trace_var' - Used to save the current stack trace object which |
| 9064 // the stack trace was copied into when an exception | 9066 // the stack trace was copied into when an exception |
| 9065 // was thrown. | 9067 // was thrown. |
| 9066 // :exception_var and :stack_trace_var get set with the exception object | 9068 // :exception_var and :stack_trace_var get set with the exception object |
| 9067 // and the stack trace object when an exception is thrown. These three | 9069 // and the stack trace object when an exception is thrown. These three |
| 9068 // implicit variables can never be captured. | 9070 // implicit variables can never be captured. |
| 9069 // Parallel try statements share the same set of variables. | 9071 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 9072 // Consecutive try statements share the same set of variables. |
| 9070 LocalVariable* context_var = | 9073 LocalVariable* context_var = |
| 9071 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); | 9074 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
| 9072 if (context_var == NULL) { | 9075 if (context_var == NULL) { |
| 9073 context_var = new(Z) LocalVariable( | 9076 context_var = new(Z) LocalVariable( |
| 9074 TokenPos(), | 9077 TokenPos(), |
| 9075 Symbols::SavedTryContextVar(), | 9078 Symbols::SavedTryContextVar(), |
| 9076 Type::ZoneHandle(Z, Type::DynamicType())); | 9079 dynamic_type); |
| 9077 current_block_->scope->AddVariable(context_var); | 9080 current_block_->scope->AddVariable(context_var); |
| 9078 } | 9081 } |
| 9079 LocalVariable* exception_var = | 9082 LocalVariable* exception_var = |
| 9080 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); | 9083 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); |
| 9081 if (exception_var == NULL) { | 9084 if (exception_var == NULL) { |
| 9082 exception_var = new(Z) LocalVariable( | 9085 exception_var = new(Z) LocalVariable( |
| 9083 TokenPos(), | 9086 TokenPos(), |
| 9084 Symbols::ExceptionVar(), | 9087 Symbols::ExceptionVar(), |
| 9085 Type::ZoneHandle(Z, Type::DynamicType())); | 9088 dynamic_type); |
| 9086 current_block_->scope->AddVariable(exception_var); | 9089 current_block_->scope->AddVariable(exception_var); |
| 9087 } | 9090 } |
| 9088 LocalVariable* stack_trace_var = | 9091 LocalVariable* stack_trace_var = |
| 9089 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar()); | 9092 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar()); |
| 9090 if (stack_trace_var == NULL) { | 9093 if (stack_trace_var == NULL) { |
| 9091 stack_trace_var = new(Z) LocalVariable( | 9094 stack_trace_var = new(Z) LocalVariable( |
| 9092 TokenPos(), | 9095 TokenPos(), |
| 9093 Symbols::StackTraceVar(), | 9096 Symbols::StackTraceVar(), |
| 9094 Type::ZoneHandle(Z, Type::DynamicType())); | 9097 dynamic_type); |
| 9095 current_block_->scope->AddVariable(stack_trace_var); | 9098 current_block_->scope->AddVariable(stack_trace_var); |
| 9096 } | 9099 } |
| 9097 | 9100 LocalVariable* saved_exception_var = NULL; |
| 9098 if (innermost_function().IsAsyncClosure() || | 9101 LocalVariable* saved_stack_trace_var = NULL; |
| 9099 innermost_function().IsAsyncFunction() || | 9102 const bool is_async = innermost_function().IsAsyncClosure() || |
| 9100 innermost_function().IsSyncGenClosure() || | 9103 innermost_function().IsAsyncFunction() || |
| 9101 innermost_function().IsSyncGenerator() || | 9104 innermost_function().IsSyncGenClosure() || |
| 9102 innermost_function().IsAsyncGenClosure() || | 9105 innermost_function().IsSyncGenerator() || |
| 9103 innermost_function().IsAsyncGenerator()) { | 9106 innermost_function().IsAsyncGenClosure() || |
| 9104 SetupSavedExceptionAndStacktrace(); | 9107 innermost_function().IsAsyncGenerator(); |
| 9108 if (is_async) { |
| 9109 saved_exception_var = current_block_->scope->LocalLookupVariable( |
| 9110 Symbols::SavedExceptionVar()); |
| 9111 if (saved_exception_var == NULL) { |
| 9112 saved_exception_var = new(Z) LocalVariable( |
| 9113 TokenPos(), |
| 9114 Symbols::SavedExceptionVar(), |
| 9115 dynamic_type); |
| 9116 current_block_->scope->AddVariable(saved_exception_var); |
| 9117 } |
| 9118 saved_stack_trace_var = current_block_->scope->LocalLookupVariable( |
| 9119 Symbols::SavedStackTraceVar()); |
| 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 } |
| 9105 } | 9127 } |
| 9106 | 9128 |
| 9107 const intptr_t try_pos = TokenPos(); | 9129 const intptr_t try_pos = TokenPos(); |
| 9108 ConsumeToken(); // Consume the 'try'. | 9130 ConsumeToken(); // Consume the 'try'. |
| 9109 | 9131 |
| 9110 SourceLabel* try_label = NULL; | 9132 SourceLabel* try_label = NULL; |
| 9111 if (label_name != NULL) { | 9133 if (label_name != NULL) { |
| 9112 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); | 9134 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); |
| 9113 OpenBlock(); | 9135 OpenBlock(); |
| 9114 current_block_->scope->AddLabel(try_label); | 9136 current_block_->scope->AddLabel(try_label); |
| 9115 } | 9137 } |
| 9116 | 9138 |
| 9117 // Now parse the 'try' block. | 9139 // Now parse the 'try' block. |
| 9118 OpenBlock(); | 9140 OpenBlock(); |
| 9119 PushTryBlock(current_block_); | 9141 PushTryBlock(current_block_); |
| 9120 ExpectToken(Token::kLBRACE); | 9142 ExpectToken(Token::kLBRACE); |
| 9121 | 9143 |
| 9122 if (innermost_function().IsAsyncClosure() || | 9144 if (is_async) { |
| 9123 innermost_function().IsAsyncFunction() || | |
| 9124 innermost_function().IsSyncGenClosure() || | |
| 9125 innermost_function().IsSyncGenerator() || | |
| 9126 innermost_function().IsAsyncGenerator() || | |
| 9127 innermost_function().IsAsyncGenClosure()) { | |
| 9128 SetupSavedTryContext(context_var); | 9145 SetupSavedTryContext(context_var); |
| 9129 } | 9146 } |
| 9130 | 9147 |
| 9131 ParseStatementSequence(); | 9148 ParseStatementSequence(); |
| 9132 ExpectToken(Token::kRBRACE); | 9149 ExpectToken(Token::kRBRACE); |
| 9133 SequenceNode* try_block = CloseBlock(); | 9150 SequenceNode* try_block = CloseBlock(); |
| 9134 | 9151 |
| 9135 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && | 9152 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && |
| 9136 (CurrentToken() != Token::kFINALLY)) { | 9153 (CurrentToken() != Token::kFINALLY)) { |
| 9137 ReportError("catch or finally clause expected"); | 9154 ReportError("catch or finally clause expected"); |
| 9138 } | 9155 } |
| 9139 | 9156 |
| 9140 // Now parse the 'catch' blocks if any. | 9157 // Now parse the 'catch' blocks if any. |
| 9141 try_blocks_list_->enter_catch(); | 9158 try_blocks_list_->enter_catch(); |
| 9142 const intptr_t handler_pos = TokenPos(); | 9159 const intptr_t handler_pos = TokenPos(); |
| 9143 const GrowableObjectArray& handler_types = | 9160 const GrowableObjectArray& handler_types = |
| 9144 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); | 9161 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| 9145 bool needs_stack_trace = false; | 9162 bool needs_stack_trace = false; |
| 9146 SequenceNode* catch_handler_list = | 9163 SequenceNode* catch_handler_list = |
| 9147 ParseCatchClauses(handler_pos, exception_var, stack_trace_var, | 9164 ParseCatchClauses(handler_pos, exception_var, stack_trace_var, |
| 9165 is_async ? saved_exception_var : exception_var, |
| 9166 is_async ? saved_stack_trace_var : stack_trace_var, |
| 9148 handler_types, &needs_stack_trace); | 9167 handler_types, &needs_stack_trace); |
| 9149 | 9168 |
| 9150 TryBlocks* inner_try_block = PopTryBlock(); | 9169 TryBlocks* inner_try_block = PopTryBlock(); |
| 9151 const intptr_t try_index = inner_try_block->try_index(); | 9170 const intptr_t try_index = inner_try_block->try_index(); |
| 9152 TryBlocks* outer_try_block = try_blocks_list_; | 9171 TryBlocks* outer_try_block = try_blocks_list_; |
| 9153 const intptr_t outer_try_index = (outer_try_block != NULL) | 9172 const intptr_t outer_try_index = (outer_try_block != NULL) |
| 9154 ? outer_try_block->try_index() | 9173 ? outer_try_block->try_index() |
| 9155 : CatchClauseNode::kInvalidTryIndex; | 9174 : CatchClauseNode::kInvalidTryIndex; |
| 9156 | 9175 |
| 9157 // Finally parse the 'finally' block. | 9176 // Finally parse the 'finally' block. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 9177 finally_block = ParseFinallyBlock(); | 9196 finally_block = ParseFinallyBlock(); |
| 9178 } | 9197 } |
| 9179 | 9198 |
| 9180 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( | 9199 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( |
| 9181 handler_pos, | 9200 handler_pos, |
| 9182 catch_handler_list, | 9201 catch_handler_list, |
| 9183 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), | 9202 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), |
| 9184 context_var, | 9203 context_var, |
| 9185 exception_var, | 9204 exception_var, |
| 9186 stack_trace_var, | 9205 stack_trace_var, |
| 9206 is_async ? saved_exception_var : exception_var, |
| 9207 is_async ? saved_stack_trace_var : stack_trace_var, |
| 9187 (finally_block != NULL) ? | 9208 (finally_block != NULL) ? |
| 9188 AllocateTryIndex() : CatchClauseNode::kInvalidTryIndex, | 9209 AllocateTryIndex() : CatchClauseNode::kInvalidTryIndex, |
| 9189 needs_stack_trace); | 9210 needs_stack_trace); |
| 9190 | 9211 |
| 9191 // Now create the try/catch ast node and return it. If there is a label | 9212 // Now create the try/catch ast node and return it. If there is a label |
| 9192 // on the try/catch, close the block that's embedding the try statement | 9213 // on the try/catch, close the block that's embedding the try statement |
| 9193 // and attach the label to it. | 9214 // and attach the label to it. |
| 9194 AstNode* try_catch_node = new(Z) TryCatchNode( | 9215 AstNode* try_catch_node = new(Z) TryCatchNode( |
| 9195 try_pos, try_block, context_var, catch_clause, finally_block, try_index); | 9216 try_pos, try_block, context_var, catch_clause, finally_block, try_index); |
| 9196 | 9217 |
| (...skipping 3978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13175 void Parser::SkipQualIdent() { | 13196 void Parser::SkipQualIdent() { |
| 13176 ASSERT(IsIdentifier()); | 13197 ASSERT(IsIdentifier()); |
| 13177 ConsumeToken(); | 13198 ConsumeToken(); |
| 13178 if (CurrentToken() == Token::kPERIOD) { | 13199 if (CurrentToken() == Token::kPERIOD) { |
| 13179 ConsumeToken(); // Consume the kPERIOD token. | 13200 ConsumeToken(); // Consume the kPERIOD token. |
| 13180 ExpectIdentifier("identifier expected after '.'"); | 13201 ExpectIdentifier("identifier expected after '.'"); |
| 13181 } | 13202 } |
| 13182 } | 13203 } |
| 13183 | 13204 |
| 13184 } // namespace dart | 13205 } // namespace dart |
| OLD | NEW |