Chromium Code Reviews| 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 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 5951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5962 | 5962 |
| 5963 // Now parse the 'catch' blocks if any and merge all of them into | 5963 // Now parse the 'catch' blocks if any and merge all of them into |
| 5964 // an if-then sequence of the different types specified using the 'is' | 5964 // an if-then sequence of the different types specified using the 'is' |
| 5965 // operator. | 5965 // operator. |
| 5966 bool catch_seen = false; | 5966 bool catch_seen = false; |
| 5967 bool generic_catch_seen = false; | 5967 bool generic_catch_seen = false; |
| 5968 SequenceNode* catch_handler_list = NULL; | 5968 SequenceNode* catch_handler_list = NULL; |
| 5969 const intptr_t handler_pos = TokenPos(); | 5969 const intptr_t handler_pos = TokenPos(); |
| 5970 OpenBlock(); // Start the catch block sequence. | 5970 OpenBlock(); // Start the catch block sequence. |
| 5971 current_block_->scope->AddLabel(end_catch_label); | 5971 current_block_->scope->AddLabel(end_catch_label); |
| 5972 const GrowableObjectArray& handler_types = | |
| 5973 GrowableObjectArray::Handle(GrowableObjectArray::New()); | |
| 5972 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { | 5974 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { |
| 5973 const intptr_t catch_pos = TokenPos(); | 5975 const intptr_t catch_pos = TokenPos(); |
| 5974 CatchParamDesc exception_param; | 5976 CatchParamDesc exception_param; |
| 5975 CatchParamDesc stack_trace_param; | 5977 CatchParamDesc stack_trace_param; |
| 5976 catch_seen = true; | 5978 catch_seen = true; |
| 5977 if (IsLiteral("on")) { | 5979 if (IsLiteral("on")) { |
| 5978 ConsumeToken(); | 5980 ConsumeToken(); |
| 5979 // TODO(regis): The spec may change in the way a malformed 'on' type is | 5981 // TODO(regis): The spec may change in the way a malformed 'on' type is |
| 5980 // treated. For now, we require the type to be wellformed. | 5982 // treated. For now, we require the type to be wellformed. |
| 5981 exception_param.type = &AbstractType::ZoneHandle( | 5983 exception_param.type = &AbstractType::ZoneHandle( |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6054 } | 6056 } |
| 6055 TypeNode* exception_type = new TypeNode(catch_pos, *exception_param.type); | 6057 TypeNode* exception_type = new TypeNode(catch_pos, *exception_param.type); |
| 6056 AstNode* exception_var = new LoadLocalNode(catch_pos, catch_excp_var); | 6058 AstNode* exception_var = new LoadLocalNode(catch_pos, catch_excp_var); |
| 6057 if (!exception_type->type().IsInstantiated()) { | 6059 if (!exception_type->type().IsInstantiated()) { |
| 6058 EnsureExpressionTemp(); | 6060 EnsureExpressionTemp(); |
| 6059 } | 6061 } |
| 6060 AstNode* type_cond_expr = new ComparisonNode( | 6062 AstNode* type_cond_expr = new ComparisonNode( |
| 6061 catch_pos, Token::kIS, exception_var, exception_type); | 6063 catch_pos, Token::kIS, exception_var, exception_type); |
| 6062 current_block_->statements->Add( | 6064 current_block_->statements->Add( |
| 6063 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL)); | 6065 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL)); |
| 6066 ASSERT(exception_type->type().IsInstantiated()); | |
| 6067 handler_types.Add(*exception_param.type); | |
| 6064 } else { | 6068 } else { |
| 6065 // No exception type exists in the catch specifier so execute the | 6069 // No exception type exists in the catch specifier so execute the |
| 6066 // catch handler code unconditionally. | 6070 // catch handler code unconditionally. |
| 6067 current_block_->statements->Add(catch_handler); | 6071 current_block_->statements->Add(catch_handler); |
| 6068 generic_catch_seen = true; | 6072 generic_catch_seen = true; |
| 6073 // This catch clause will handle all exceptions. We can safely forget | |
| 6074 // all previous catch clause types. | |
| 6075 handler_types.SetLength(0); | |
| 6076 handler_types.Add(*exception_param.type); | |
|
siva
2013/01/15 22:04:12
We should also be ok to not collect any more catch
hausner
2013/01/15 22:44:52
The compiler prints an error message if there are
| |
| 6069 } | 6077 } |
| 6070 SequenceNode* catch_clause = CloseBlock(); | 6078 SequenceNode* catch_clause = CloseBlock(); |
| 6071 | 6079 |
| 6072 // Add this individual catch handler to the catch handlers list. | 6080 // Add this individual catch handler to the catch handlers list. |
| 6073 current_block_->statements->Add(catch_clause); | 6081 current_block_->statements->Add(catch_clause); |
| 6074 } | 6082 } |
| 6075 catch_handler_list = CloseBlock(); | 6083 catch_handler_list = CloseBlock(); |
| 6076 TryBlocks* inner_try_block = PopTryBlock(); | 6084 TryBlocks* inner_try_block = PopTryBlock(); |
| 6077 | 6085 |
| 6078 // Finally parse the 'finally' block. | 6086 // Finally parse the 'finally' block. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6111 } | 6119 } |
| 6112 | 6120 |
| 6113 if (!generic_catch_seen) { | 6121 if (!generic_catch_seen) { |
| 6114 // No generic catch handler exists so rethrow the exception so that | 6122 // No generic catch handler exists so rethrow the exception so that |
| 6115 // the next catch handler can deal with it. | 6123 // the next catch handler can deal with it. |
| 6116 catch_handler_list->Add( | 6124 catch_handler_list->Add( |
| 6117 new ThrowNode(handler_pos, | 6125 new ThrowNode(handler_pos, |
| 6118 new LoadLocalNode(handler_pos, catch_excp_var), | 6126 new LoadLocalNode(handler_pos, catch_excp_var), |
| 6119 new LoadLocalNode(handler_pos, catch_trace_var))); | 6127 new LoadLocalNode(handler_pos, catch_trace_var))); |
| 6120 } | 6128 } |
| 6121 CatchClauseNode* catch_block = new CatchClauseNode(handler_pos, | 6129 CatchClauseNode* catch_block = |
| 6122 catch_handler_list, | 6130 new CatchClauseNode(handler_pos, |
| 6123 context_var, | 6131 catch_handler_list, |
| 6124 catch_excp_var, | 6132 Array::ZoneHandle(Array::MakeArray(handler_types)), |
| 6125 catch_trace_var); | 6133 context_var, |
| 6134 catch_excp_var, | |
| 6135 catch_trace_var); | |
| 6126 | 6136 |
| 6127 // Now create the try/catch ast node and return it. If there is a label | 6137 // Now create the try/catch ast node and return it. If there is a label |
| 6128 // on the try/catch, close the block that's embedding the try statement | 6138 // on the try/catch, close the block that's embedding the try statement |
| 6129 // and attach the label to it. | 6139 // and attach the label to it. |
| 6130 AstNode* try_catch_node = | 6140 AstNode* try_catch_node = |
| 6131 new TryCatchNode(try_pos, try_block, end_catch_label, | 6141 new TryCatchNode(try_pos, try_block, end_catch_label, |
| 6132 context_var, catch_block, finally_block); | 6142 context_var, catch_block, finally_block); |
| 6133 | 6143 |
| 6134 if (try_label != NULL) { | 6144 if (try_label != NULL) { |
| 6135 current_block_->statements->Add(try_catch_node); | 6145 current_block_->statements->Add(try_catch_node); |
| (...skipping 3570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9706 void Parser::SkipQualIdent() { | 9716 void Parser::SkipQualIdent() { |
| 9707 ASSERT(IsIdentifier()); | 9717 ASSERT(IsIdentifier()); |
| 9708 ConsumeToken(); | 9718 ConsumeToken(); |
| 9709 if (CurrentToken() == Token::kPERIOD) { | 9719 if (CurrentToken() == Token::kPERIOD) { |
| 9710 ConsumeToken(); // Consume the kPERIOD token. | 9720 ConsumeToken(); // Consume the kPERIOD token. |
| 9711 ExpectIdentifier("identifier expected after '.'"); | 9721 ExpectIdentifier("identifier expected after '.'"); |
| 9712 } | 9722 } |
| 9713 } | 9723 } |
| 9714 | 9724 |
| 9715 } // namespace dart | 9725 } // namespace dart |
| OLD | NEW |