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 #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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |