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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 1079 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1090 field, | 1090 field, |
| 1091 expr); | 1091 expr); |
| 1092 current_block_->statements->Add(store); | 1092 current_block_->statements->Add(store); |
| 1093 SequenceNode* try_block = CloseBlock(); // End try block. | 1093 SequenceNode* try_block = CloseBlock(); // End try block. |
| 1094 | 1094 |
| 1095 OpenBlock(); // Start catch handler list. | 1095 OpenBlock(); // Start catch handler list. |
| 1096 SourceLabel* end_catch_label = | 1096 SourceLabel* end_catch_label = |
| 1097 SourceLabel::New(token_pos, NULL, SourceLabel::kCatch); | 1097 SourceLabel::New(token_pos, NULL, SourceLabel::kCatch); |
| 1098 current_block_->scope->AddLabel(end_catch_label); | 1098 current_block_->scope->AddLabel(end_catch_label); |
| 1099 | 1099 |
| 1100 OpenBlock(); // Start catch clause. | 1100 OpenBlock(); // Start catch clause. |
|
Florian Schneider
2013/11/05 10:05:30
The same should be done here for try-catch generat
| |
| 1101 AstNode* compare_transition_sentinel = new ComparisonNode( | 1101 AstNode* compare_transition_sentinel = new ComparisonNode( |
| 1102 token_pos, | 1102 token_pos, |
| 1103 Token::kEQ_STRICT, | 1103 Token::kEQ_STRICT, |
| 1104 new LoadStaticFieldNode(token_pos, field), | 1104 new LoadStaticFieldNode(token_pos, field), |
| 1105 new LiteralNode(field.token_pos(), Object::transition_sentinel())); | 1105 new LiteralNode(field.token_pos(), Object::transition_sentinel())); |
| 1106 | 1106 |
| 1107 SequenceNode* store_null = new SequenceNode(token_pos, NULL); | 1107 SequenceNode* store_null = new SequenceNode(token_pos, NULL); |
| 1108 store_null->Add(new StoreStaticFieldNode( | 1108 store_null->Add(new StoreStaticFieldNode( |
| 1109 field.token_pos(), | 1109 field.token_pos(), |
| 1110 field, | 1110 field, |
| (...skipping 5724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6835 | 6835 |
| 6836 // Now parse the 'try' block. | 6836 // Now parse the 'try' block. |
| 6837 OpenBlock(); | 6837 OpenBlock(); |
| 6838 Block* current_try_block = current_block_; | 6838 Block* current_try_block = current_block_; |
| 6839 PushTryBlock(current_try_block); | 6839 PushTryBlock(current_try_block); |
| 6840 ExpectToken(Token::kLBRACE); | 6840 ExpectToken(Token::kLBRACE); |
| 6841 ParseStatementSequence(); | 6841 ParseStatementSequence(); |
| 6842 ExpectToken(Token::kRBRACE); | 6842 ExpectToken(Token::kRBRACE); |
| 6843 SequenceNode* try_block = CloseBlock(); | 6843 SequenceNode* try_block = CloseBlock(); |
| 6844 | 6844 |
| 6845 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && | |
| 6846 (CurrentToken() != Token::kFINALLY)) { | |
| 6847 ErrorMsg("catch or finally clause expected"); | |
| 6848 } | |
| 6849 | |
| 6845 // Now create a label for the end of catch block processing so that we can | 6850 // Now create a label for the end of catch block processing so that we can |
| 6846 // jump over the catch block code after executing the try block. | 6851 // jump over the catch block code after executing the try block. |
| 6847 SourceLabel* end_catch_label = | 6852 SourceLabel* end_catch_label = |
| 6848 SourceLabel::New(TokenPos(), NULL, SourceLabel::kCatch); | 6853 SourceLabel::New(TokenPos(), NULL, SourceLabel::kCatch); |
| 6849 | 6854 |
| 6850 // Now parse the 'catch' blocks if any and merge all of them into | 6855 // Now parse the 'catch' blocks if any and merge all of them into |
| 6851 // an if-then sequence of the different types specified using the 'is' | 6856 // an if-then sequence of the different types specified using the 'is' |
| 6852 // operator. | 6857 // operator. |
| 6853 bool catch_seen = false; | |
| 6854 bool generic_catch_seen = false; | 6858 bool generic_catch_seen = false; |
| 6855 const intptr_t handler_pos = TokenPos(); | 6859 const intptr_t handler_pos = TokenPos(); |
| 6856 OpenBlock(); // Start the catch block sequence. | 6860 OpenBlock(); // Start the catch block sequence. |
| 6857 current_block_->scope->AddLabel(end_catch_label); | 6861 current_block_->scope->AddLabel(end_catch_label); |
| 6858 const GrowableObjectArray& handler_types = | 6862 const GrowableObjectArray& handler_types = |
| 6859 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 6863 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 6860 bool needs_stacktrace = false; | 6864 bool needs_stacktrace = false; |
| 6861 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { | 6865 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { |
| 6862 const intptr_t catch_pos = TokenPos(); | 6866 const intptr_t catch_pos = TokenPos(); |
| 6863 CatchParamDesc exception_param; | 6867 CatchParamDesc exception_param; |
| 6864 CatchParamDesc stack_trace_param; | 6868 CatchParamDesc stack_trace_param; |
| 6865 catch_seen = true; | |
| 6866 if (IsLiteral("on")) { | 6869 if (IsLiteral("on")) { |
| 6867 ConsumeToken(); | 6870 ConsumeToken(); |
| 6868 exception_param.type = &AbstractType::ZoneHandle( | 6871 exception_param.type = &AbstractType::ZoneHandle( |
| 6869 ParseType(ClassFinalizer::kCanonicalize)); | 6872 ParseType(ClassFinalizer::kCanonicalize)); |
| 6870 } else { | 6873 } else { |
| 6871 exception_param.type = | 6874 exception_param.type = |
| 6872 &AbstractType::ZoneHandle(Type::DynamicType()); | 6875 &AbstractType::ZoneHandle(Type::DynamicType()); |
| 6873 } | 6876 } |
| 6874 if (CurrentToken() == Token::kCATCH) { | 6877 if (CurrentToken() == Token::kCATCH) { |
| 6875 ConsumeToken(); // Consume the 'catch'. | 6878 ConsumeToken(); // Consume the 'catch'. |
| 6876 ExpectToken(Token::kLPAREN); | 6879 ExpectToken(Token::kLPAREN); |
| 6877 exception_param.token_pos = TokenPos(); | 6880 exception_param.token_pos = TokenPos(); |
| 6878 exception_param.var = ExpectIdentifier("identifier expected"); | 6881 exception_param.var = ExpectIdentifier("identifier expected"); |
| 6879 if (CurrentToken() == Token::kCOMMA) { | 6882 if (CurrentToken() == Token::kCOMMA) { |
| 6880 ConsumeToken(); | 6883 ConsumeToken(); |
| 6881 // TODO(hausner): Make implicit type be StackTrace, not dynamic. | 6884 // TODO(hausner): Make implicit type be StackTrace, not dynamic. |
| 6882 stack_trace_param.type = | 6885 stack_trace_param.type = |
| 6883 &AbstractType::ZoneHandle(Type::DynamicType()); | 6886 &AbstractType::ZoneHandle(Type::DynamicType()); |
| 6884 stack_trace_param.token_pos = TokenPos(); | 6887 stack_trace_param.token_pos = TokenPos(); |
| 6885 stack_trace_param.var = ExpectIdentifier("identifier expected"); | 6888 stack_trace_param.var = ExpectIdentifier("identifier expected"); |
| 6886 } | 6889 } |
| 6887 ExpectToken(Token::kRPAREN); | 6890 ExpectToken(Token::kRPAREN); |
| 6888 } | 6891 } |
| 6889 | 6892 |
| 6893 // Parse the individual catch handler code and add an unconditional | |
| 6894 // JUMP to the end of the try block. | |
| 6895 ExpectToken(Token::kLBRACE); | |
| 6890 OpenBlock(); | 6896 OpenBlock(); |
| 6891 AddCatchParamsToScope(exception_param, | 6897 AddCatchParamsToScope(exception_param, |
| 6892 stack_trace_param, | 6898 stack_trace_param, |
| 6893 current_block_->scope); | 6899 current_block_->scope); |
| 6894 | 6900 |
| 6895 // Parse the individual catch handler code and add an unconditional | |
| 6896 // JUMP to the end of the try block. | |
| 6897 ExpectToken(Token::kLBRACE); | |
| 6898 OpenBlock(); | |
| 6899 | |
| 6900 if (exception_param.var != NULL) { | 6901 if (exception_param.var != NULL) { |
| 6901 // Generate code to load the exception object (:exception_var) into | 6902 // Generate code to load the exception object (:exception_var) into |
| 6902 // the exception variable specified in this block. | 6903 // the exception variable specified in this block. |
| 6903 LocalVariable* var = LookupLocalScope(*exception_param.var); | 6904 LocalVariable* var = LookupLocalScope(*exception_param.var); |
| 6904 ASSERT(var != NULL); | 6905 ASSERT(var != NULL); |
| 6905 ASSERT(catch_excp_var != NULL); | 6906 ASSERT(catch_excp_var != NULL); |
| 6906 current_block_->statements->Add( | 6907 current_block_->statements->Add( |
| 6907 new StoreLocalNode(catch_pos, var, | 6908 new StoreLocalNode(catch_pos, var, |
| 6908 new LoadLocalNode(catch_pos, catch_excp_var))); | 6909 new LoadLocalNode(catch_pos, catch_excp_var))); |
| 6909 } | 6910 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6963 } else { | 6964 } else { |
| 6964 // No exception type exists in the catch specifier so execute the | 6965 // No exception type exists in the catch specifier so execute the |
| 6965 // catch handler code unconditionally. | 6966 // catch handler code unconditionally. |
| 6966 current_block_->statements->Add(catch_handler); | 6967 current_block_->statements->Add(catch_handler); |
| 6967 generic_catch_seen = true; | 6968 generic_catch_seen = true; |
| 6968 // This catch clause will handle all exceptions. We can safely forget | 6969 // This catch clause will handle all exceptions. We can safely forget |
| 6969 // all previous catch clause types. | 6970 // all previous catch clause types. |
| 6970 handler_types.SetLength(0); | 6971 handler_types.SetLength(0); |
| 6971 handler_types.Add(*exception_param.type); | 6972 handler_types.Add(*exception_param.type); |
| 6972 } | 6973 } |
| 6973 SequenceNode* catch_clause = CloseBlock(); | |
| 6974 | |
| 6975 // Add this individual catch handler to the catch handlers list. | |
| 6976 current_block_->statements->Add(catch_clause); | |
| 6977 } | 6974 } |
| 6978 SequenceNode* catch_handler_list = CloseBlock(); | 6975 SequenceNode* catch_handler_list = CloseBlock(); |
| 6979 TryBlocks* inner_try_block = PopTryBlock(); | 6976 TryBlocks* inner_try_block = PopTryBlock(); |
| 6980 const intptr_t try_index = inner_try_block->try_index(); | 6977 const intptr_t try_index = inner_try_block->try_index(); |
| 6981 TryBlocks* outer_try_block = try_blocks_list_; | 6978 TryBlocks* outer_try_block = try_blocks_list_; |
| 6982 const intptr_t outer_try_index = (outer_try_block != NULL) | 6979 const intptr_t outer_try_index = (outer_try_block != NULL) |
| 6983 ? outer_try_block->try_index() | 6980 ? outer_try_block->try_index() |
| 6984 : CatchClauseNode::kInvalidTryIndex; | 6981 : CatchClauseNode::kInvalidTryIndex; |
| 6985 | 6982 |
| 6986 // Finally parse the 'finally' block. | 6983 // Finally parse the 'finally' block. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 6998 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos, | 6995 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos, |
| 6999 finally_block, | 6996 finally_block, |
| 7000 context_var, | 6997 context_var, |
| 7001 outer_try_index); | 6998 outer_try_index); |
| 7002 AddFinallyBlockToNode(node_to_inline, node); | 6999 AddFinallyBlockToNode(node_to_inline, node); |
| 7003 node_index += 1; | 7000 node_index += 1; |
| 7004 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); | 7001 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); |
| 7005 tokens_iterator_.SetCurrentPosition(finally_pos); | 7002 tokens_iterator_.SetCurrentPosition(finally_pos); |
| 7006 } | 7003 } |
| 7007 finally_block = ParseFinallyBlock(); | 7004 finally_block = ParseFinallyBlock(); |
| 7008 } else { | |
| 7009 if (!catch_seen) { | |
| 7010 ErrorMsg("catch or finally clause expected"); | |
| 7011 } | |
| 7012 } | 7005 } |
| 7013 | 7006 |
| 7014 if (!generic_catch_seen) { | 7007 if (!generic_catch_seen) { |
| 7015 // No generic catch handler exists so rethrow the exception so that | 7008 // No generic catch handler exists so rethrow the exception so that |
| 7016 // the next catch handler can deal with it. | 7009 // the next catch handler can deal with it. |
| 7017 catch_handler_list->Add( | 7010 catch_handler_list->Add( |
| 7018 new ThrowNode(handler_pos, | 7011 new ThrowNode(handler_pos, |
| 7019 new LoadLocalNode(handler_pos, catch_excp_var), | 7012 new LoadLocalNode(handler_pos, catch_excp_var), |
| 7020 new LoadLocalNode(handler_pos, catch_trace_var))); | 7013 new LoadLocalNode(handler_pos, catch_trace_var))); |
| 7021 } | 7014 } |
| (...skipping 3757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10779 void Parser::SkipQualIdent() { | 10772 void Parser::SkipQualIdent() { |
| 10780 ASSERT(IsIdentifier()); | 10773 ASSERT(IsIdentifier()); |
| 10781 ConsumeToken(); | 10774 ConsumeToken(); |
| 10782 if (CurrentToken() == Token::kPERIOD) { | 10775 if (CurrentToken() == Token::kPERIOD) { |
| 10783 ConsumeToken(); // Consume the kPERIOD token. | 10776 ConsumeToken(); // Consume the kPERIOD token. |
| 10784 ExpectIdentifier("identifier expected after '.'"); | 10777 ExpectIdentifier("identifier expected after '.'"); |
| 10785 } | 10778 } |
| 10786 } | 10779 } |
| 10787 | 10780 |
| 10788 } // namespace dart | 10781 } // namespace dart |
| OLD | NEW |