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

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

Issue 973103002: One more fix to async machinery (rethrow in finally, issue 22595). (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 6016 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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