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

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 regression test 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
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 tokens_iterator_.SetCurrentPosition(finally_pos);
9804 rethrow_clause = EnsureFinallyClause(
hausner 2016/01/06 17:11:59 Does this call to EnsureFinallyClause() return a d
Florian Schneider 2016/01/06 17:37:26 The AST will be the same (like for inlined-finally
9805 parse,
9806 is_async,
9807 exception_var,
9808 stack_trace_var,
9809 is_async ? saved_exception_var : exception_var,
9810 is_async ? saved_stack_trace_var : stack_trace_var);
9811 }
9798 } 9812 }
9799 9813
9800 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( 9814 CatchClauseNode* catch_clause = new(Z) CatchClauseNode(
9801 handler_pos, 9815 handler_pos,
9802 catch_handler_list, 9816 catch_handler_list,
9803 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), 9817 Array::ZoneHandle(Z, Array::MakeArray(handler_types)),
9804 context_var, 9818 context_var,
9805 exception_var, 9819 exception_var,
9806 stack_trace_var, 9820 stack_trace_var,
9807 is_async ? saved_exception_var : exception_var, 9821 is_async ? saved_exception_var : exception_var,
9808 is_async ? saved_stack_trace_var : stack_trace_var, 9822 is_async ? saved_stack_trace_var : stack_trace_var,
9809 (finally_clause != NULL) ? 9823 (finally_clause != NULL) ?
9810 AllocateTryIndex() : CatchClauseNode::kInvalidTryIndex, 9824 AllocateTryIndex() : CatchClauseNode::kInvalidTryIndex,
9811 needs_stack_trace); 9825 needs_stack_trace);
9812 9826
9813 // Now create the try/catch ast node and return it. If there is a label 9827 // 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 9828 // on the try/catch, close the block that's embedding the try statement
9815 // and attach the label to it. 9829 // and attach the label to it.
9816 AstNode* try_catch_node = new(Z) TryCatchNode( 9830 AstNode* try_catch_node = new(Z) TryCatchNode(
9817 try_pos, try_block, context_var, catch_clause, finally_clause, try_index); 9831 try_pos, try_block, context_var, catch_clause, finally_clause, try_index,
9832 rethrow_clause);
9818 9833
9819 if (try_label != NULL) { 9834 if (try_label != NULL) {
9820 current_block_->statements->Add(try_catch_node); 9835 current_block_->statements->Add(try_catch_node);
9821 SequenceNode* sequence = CloseBlock(); 9836 SequenceNode* sequence = CloseBlock();
9822 sequence->set_label(try_label); 9837 sequence->set_label(try_label);
9823 try_catch_node = sequence; 9838 try_catch_node = sequence;
9824 } 9839 }
9825 9840
9826 return try_catch_node; 9841 return try_catch_node;
9827 } 9842 }
(...skipping 4680 matching lines...) Expand 10 before | Expand all | Expand 10 after
14508 const ArgumentListNode& function_args, 14523 const ArgumentListNode& function_args,
14509 const LocalVariable* temp_for_last_arg, 14524 const LocalVariable* temp_for_last_arg,
14510 bool is_super_invocation) { 14525 bool is_super_invocation) {
14511 UNREACHABLE(); 14526 UNREACHABLE();
14512 return NULL; 14527 return NULL;
14513 } 14528 }
14514 14529
14515 } // namespace dart 14530 } // namespace dart
14516 14531
14517 #endif // DART_PRECOMPILED 14532 #endif // DART_PRECOMPILED
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698