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

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

Issue 1569523002: Fix VM bug with try-catch inside of try-finally. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: added comment Created 4 years, 11 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
« no previous file with comments | « runtime/vm/flow_graph_compiler.cc ('k') | tests/language/try_finally_regress_25333_test.dart » ('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 #include "vm/flags.h" 6 #include "vm/flags.h"
7 7
8 #ifndef DART_PRECOMPILED 8 #ifndef DART_PRECOMPILED
9 9
10 #include "lib/invocation_mirror.h" 10 #include "lib/invocation_mirror.h"
(...skipping 6447 matching lines...) Expand 10 before | Expand all | Expand 10 after
6458 true); 6458 true);
6459 6459
6460 const intptr_t try_index = try_statement->try_index(); 6460 const intptr_t try_index = try_statement->try_index();
6461 6461
6462 AstNode* try_catch_node = 6462 AstNode* try_catch_node =
6463 new(Z) TryCatchNode(Scanner::kNoSourcePos, 6463 new(Z) TryCatchNode(Scanner::kNoSourcePos,
6464 body, 6464 body,
6465 context_var, 6465 context_var,
6466 catch_clause, 6466 catch_clause,
6467 finally_clause, 6467 finally_clause,
6468 try_index); 6468 try_index,
6469 finally_clause);
6469 current_block_->statements->Add(try_catch_node); 6470 current_block_->statements->Add(try_catch_node);
6470 return CloseBlock(); 6471 return CloseBlock();
6471 } 6472 }
6472 6473
6473 6474
6474 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { 6475 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) {
6475 // This is the outermost try-catch of the function. 6476 // This is the outermost try-catch of the function.
6476 ASSERT(try_stack_ != NULL); 6477 ASSERT(try_stack_ != NULL);
6477 ASSERT(try_stack_->outer_try() == NULL); 6478 ASSERT(try_stack_->outer_try() == NULL);
6478 ASSERT(innermost_function().IsAsyncClosure()); 6479 ASSERT(innermost_function().IsAsyncClosure());
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
6574 saved_exception_var, 6575 saved_exception_var,
6575 saved_stack_trace_var, 6576 saved_stack_trace_var,
6576 CatchClauseNode::kInvalidTryIndex, 6577 CatchClauseNode::kInvalidTryIndex,
6577 true); 6578 true);
6578 AstNode* try_catch_node = new (Z) TryCatchNode( 6579 AstNode* try_catch_node = new (Z) TryCatchNode(
6579 Scanner::kNoSourcePos, 6580 Scanner::kNoSourcePos,
6580 try_block, 6581 try_block,
6581 context_var, 6582 context_var,
6582 catch_clause, 6583 catch_clause,
6583 NULL, // No finally clause. 6584 NULL, // No finally clause.
6584 try_index); 6585 try_index,
6586 NULL); // No rethrow-finally clause.
6585 current_block_->statements->Add(try_catch_node); 6587 current_block_->statements->Add(try_catch_node);
6586 return CloseBlock(); 6588 return CloseBlock();
6587 } 6589 }
6588 6590
6589 6591
6590 // Wrap the body of the async or async* closure in a try/catch block. 6592 // Wrap the body of the async or async* closure in a try/catch block.
6591 void Parser::OpenAsyncTryBlock() { 6593 void Parser::OpenAsyncTryBlock() {
6592 ASSERT(innermost_function().IsAsyncClosure() || 6594 ASSERT(innermost_function().IsAsyncClosure() ||
6593 innermost_function().IsAsyncGenClosure()); 6595 innermost_function().IsAsyncGenClosure());
6594 LocalVariable* context_var = NULL; 6596 LocalVariable* context_var = NULL;
(...skipping 2334 matching lines...) Expand 10 before | Expand all | Expand 10 after
8929 stack_trace_var, 8931 stack_trace_var,
8930 AllocateTryIndex(), 8932 AllocateTryIndex(),
8931 true); // Needs stack trace. 8933 true); // Needs stack trace.
8932 8934
8933 AstNode* try_catch_node = 8935 AstNode* try_catch_node =
8934 new(Z) TryCatchNode(await_for_pos, 8936 new(Z) TryCatchNode(await_for_pos,
8935 try_block, 8937 try_block,
8936 context_var, 8938 context_var,
8937 catch_clause, 8939 catch_clause,
8938 finally_clause, 8940 finally_clause,
8939 try_index); 8941 try_index,
8942 finally_clause);
8940 8943
8941 ASSERT(current_block_ == loop_block); 8944 ASSERT(current_block_ == loop_block);
8942 loop_block->statements->Add(try_catch_node); 8945 loop_block->statements->Add(try_catch_node);
8943 8946
8944 return CloseBlock(); // Implicit block around while loop. 8947 return CloseBlock(); // Implicit block around while loop.
8945 } 8948 }
8946 8949
8947 8950
8948 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, 8951 AstNode* Parser::ParseForInStatement(intptr_t forin_pos,
8949 SourceLabel* label) { 8952 SourceLabel* label) {
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after
9755 const intptr_t try_index = try_statement->try_index(); 9758 const intptr_t try_index = try_statement->try_index();
9756 TryStack* outer_try = try_stack_; 9759 TryStack* outer_try = try_stack_;
9757 const intptr_t outer_try_index = (outer_try != NULL) ? 9760 const intptr_t outer_try_index = (outer_try != NULL) ?
9758 outer_try->try_index() : CatchClauseNode::kInvalidTryIndex; 9761 outer_try->try_index() : CatchClauseNode::kInvalidTryIndex;
9759 9762
9760 // Finally, parse or generate the 'finally' clause. 9763 // Finally, parse or generate the 'finally' clause.
9761 // A finally clause is required in async code to restore the saved try context 9764 // A finally clause is required in async code to restore the saved try context
9762 // of an existing outer try. Generate a finally clause to this purpose if it 9765 // of an existing outer try. Generate a finally clause to this purpose if it
9763 // is not declared. 9766 // is not declared.
9764 SequenceNode* finally_clause = NULL; 9767 SequenceNode* finally_clause = NULL;
9768 SequenceNode* rethrow_clause = NULL;
9765 const bool parse = CurrentToken() == Token::kFINALLY; 9769 const bool parse = CurrentToken() == Token::kFINALLY;
9766 if (parse || (is_async && (try_stack_ != NULL))) { 9770 if (parse || (is_async && (try_stack_ != NULL))) {
9767 if (parse) { 9771 if (parse) {
9768 ConsumeToken(); // Consume the 'finally'. 9772 ConsumeToken(); // Consume the 'finally'.
9769 } 9773 }
9770 const intptr_t finally_pos = TokenPos(); 9774 const intptr_t finally_pos = TokenPos();
9771 // Add the finally block to the exit points recorded so far. 9775 // Add the finally block to the exit points recorded so far.
9772 intptr_t node_index = 0; 9776 intptr_t node_index = 0;
9773 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); 9777 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index);
9774 while (node_to_inline != NULL) { 9778 while (node_to_inline != NULL) {
(...skipping 13 matching lines...) Expand all
9788 node_to_inline = try_statement->GetNodeToInlineFinally(node_index); 9792 node_to_inline = try_statement->GetNodeToInlineFinally(node_index);
9789 tokens_iterator_.SetCurrentPosition(finally_pos); 9793 tokens_iterator_.SetCurrentPosition(finally_pos);
9790 } 9794 }
9791 finally_clause = EnsureFinallyClause( 9795 finally_clause = EnsureFinallyClause(
9792 parse, 9796 parse,
9793 is_async, 9797 is_async,
9794 exception_var, 9798 exception_var,
9795 stack_trace_var, 9799 stack_trace_var,
9796 is_async ? saved_exception_var : exception_var, 9800 is_async ? saved_exception_var : exception_var,
9797 is_async ? saved_stack_trace_var : stack_trace_var); 9801 is_async ? saved_stack_trace_var : stack_trace_var);
9802 if (finally_clause != NULL) {
9803 // Re-parse to create a duplicate of finally clause to avoid unintended
9804 // sharing of try-indices if the finally-block contains a try-catch.
9805 // The flow graph builder emits two copies of the finally-block if the
9806 // try-block has a normal exit: one for the exception- and one for the
9807 // non-exception case (see EffectGraphVisitor::VisitTryCatchNode)
9808 tokens_iterator_.SetCurrentPosition(finally_pos);
9809 rethrow_clause = EnsureFinallyClause(
9810 parse,
9811 is_async,
9812 exception_var,
9813 stack_trace_var,
9814 is_async ? saved_exception_var : exception_var,
9815 is_async ? saved_stack_trace_var : stack_trace_var);
9816 }
9798 } 9817 }
9799 9818
9800 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( 9819 CatchClauseNode* catch_clause = new(Z) CatchClauseNode(
9801 handler_pos, 9820 handler_pos,
9802 catch_handler_list, 9821 catch_handler_list,
9803 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), 9822 Array::ZoneHandle(Z, Array::MakeArray(handler_types)),
9804 context_var, 9823 context_var,
9805 exception_var, 9824 exception_var,
9806 stack_trace_var, 9825 stack_trace_var,
9807 is_async ? saved_exception_var : exception_var, 9826 is_async ? saved_exception_var : exception_var,
9808 is_async ? saved_stack_trace_var : stack_trace_var, 9827 is_async ? saved_stack_trace_var : stack_trace_var,
9809 (finally_clause != NULL) ? 9828 (finally_clause != NULL) ?
9810 AllocateTryIndex() : CatchClauseNode::kInvalidTryIndex, 9829 AllocateTryIndex() : CatchClauseNode::kInvalidTryIndex,
9811 needs_stack_trace); 9830 needs_stack_trace);
9812 9831
9813 // Now create the try/catch ast node and return it. If there is a label 9832 // Now create the try/catch ast node and return it. If there is a label
9814 // on the try/catch, close the block that's embedding the try statement 9833 // on the try/catch, close the block that's embedding the try statement
9815 // and attach the label to it. 9834 // and attach the label to it.
9816 AstNode* try_catch_node = new(Z) TryCatchNode( 9835 AstNode* try_catch_node = new(Z) TryCatchNode(
9817 try_pos, try_block, context_var, catch_clause, finally_clause, try_index); 9836 try_pos, try_block, context_var, catch_clause, finally_clause, try_index,
9837 rethrow_clause);
9818 9838
9819 if (try_label != NULL) { 9839 if (try_label != NULL) {
9820 current_block_->statements->Add(try_catch_node); 9840 current_block_->statements->Add(try_catch_node);
9821 SequenceNode* sequence = CloseBlock(); 9841 SequenceNode* sequence = CloseBlock();
9822 sequence->set_label(try_label); 9842 sequence->set_label(try_label);
9823 try_catch_node = sequence; 9843 try_catch_node = sequence;
9824 } 9844 }
9825 9845
9826 return try_catch_node; 9846 return try_catch_node;
9827 } 9847 }
(...skipping 4680 matching lines...) Expand 10 before | Expand all | Expand 10 after
14508 const ArgumentListNode& function_args, 14528 const ArgumentListNode& function_args,
14509 const LocalVariable* temp_for_last_arg, 14529 const LocalVariable* temp_for_last_arg,
14510 bool is_super_invocation) { 14530 bool is_super_invocation) {
14511 UNREACHABLE(); 14531 UNREACHABLE();
14512 return NULL; 14532 return NULL;
14513 } 14533 }
14514 14534
14515 } // namespace dart 14535 } // namespace dart
14516 14536
14517 #endif // DART_PRECOMPILED 14537 #endif // DART_PRECOMPILED
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler.cc ('k') | tests/language/try_finally_regress_25333_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698