| 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 |