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

Side by Side Diff: runtime/vm/parser.cc

Issue 59523002: Flatten the AST for try/catch. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698