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

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

Issue 467933002: Fix issue 20476: creating multiple LocalVariables with same name (finally_ret_val35), confuses the … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 months 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 | « runtime/vm/parser.h ('k') | tests/language/language.status » ('j') | 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 "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 } 108 }
109 // Cannot canonicalize TypeArgument yet as its types may not have been 109 // Cannot canonicalize TypeArgument yet as its types may not have been
110 // finalized yet. 110 // finalized yet.
111 return a.raw(); 111 return a.raw();
112 } 112 }
113 113
114 114
115 LocalVariable* ParsedFunction::EnsureExpressionTemp() { 115 LocalVariable* ParsedFunction::EnsureExpressionTemp() {
116 if (!has_expression_temp_var()) { 116 if (!has_expression_temp_var()) {
117 LocalVariable* temp = 117 LocalVariable* temp =
118 new LocalVariable(function_.token_pos(), 118 new (I) LocalVariable(function_.token_pos(),
119 Symbols::ExprTemp(), 119 Symbols::ExprTemp(),
120 Type::ZoneHandle(Type::DynamicType())); 120 Type::ZoneHandle(Type::DynamicType()));
121 ASSERT(temp != NULL); 121 ASSERT(temp != NULL);
122 set_expression_temp_var(temp); 122 set_expression_temp_var(temp);
123 } 123 }
124 ASSERT(has_expression_temp_var()); 124 ASSERT(has_expression_temp_var());
125 return expression_temp_var(); 125 return expression_temp_var();
126 } 126 }
127 127
128 128
129 LocalVariable* ParsedFunction::EnsureFinallyReturnTemp() {
130 if (!has_finally_return_temp_var()) {
131 LocalVariable* temp = new(I) LocalVariable(
132 function_.token_pos(),
133 String::ZoneHandle(I, Symbols::New(":finally_ret_val")),
134 Type::ZoneHandle(I, Type::DynamicType()));
135 ASSERT(temp != NULL);
136 temp->set_is_final();
137 set_finally_return_temp_var(temp);
138 }
139 ASSERT(has_finally_return_temp_var());
140 return finally_return_temp_var();
141 }
142
143
129 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { 144 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) {
130 ASSERT(node_sequence_ == NULL); 145 ASSERT(node_sequence_ == NULL);
131 ASSERT(node_sequence != NULL); 146 ASSERT(node_sequence != NULL);
132 node_sequence_ = node_sequence; 147 node_sequence_ = node_sequence;
133 } 148 }
134 149
135 150
136 void ParsedFunction::AddDeferredPrefix(const LibraryPrefix& prefix) { 151 void ParsedFunction::AddDeferredPrefix(const LibraryPrefix& prefix) {
137 ASSERT(prefix.is_deferred_load()); 152 ASSERT(prefix.is_deferred_load());
138 ASSERT(!prefix.is_loaded()); 153 ASSERT(!prefix.is_loaded());
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 // Add implicit return node. 851 // Add implicit return node.
837 node_sequence->Add(new ReturnNode(func.end_token_pos())); 852 node_sequence->Add(new ReturnNode(func.end_token_pos()));
838 } 853 }
839 if (parsed_function->has_expression_temp_var()) { 854 if (parsed_function->has_expression_temp_var()) {
840 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); 855 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var());
841 } 856 }
842 if (parsed_function->has_saved_current_context_var()) { 857 if (parsed_function->has_saved_current_context_var()) {
843 node_sequence->scope()->AddVariable( 858 node_sequence->scope()->AddVariable(
844 parsed_function->saved_current_context_var()); 859 parsed_function->saved_current_context_var());
845 } 860 }
861 if (parsed_function->has_finally_return_temp_var()) {
862 node_sequence->scope()->AddVariable(
863 parsed_function->finally_return_temp_var());
864 }
846 parsed_function->SetNodeSequence(node_sequence); 865 parsed_function->SetNodeSequence(node_sequence);
847 866
848 // The instantiator may be required at run time for generic type checks or 867 // The instantiator may be required at run time for generic type checks or
849 // allocation of generic types. 868 // allocation of generic types.
850 if (parser.IsInstantiatorRequired()) { 869 if (parser.IsInstantiatorRequired()) {
851 // In the case of a local function, only set the instantiator if the 870 // In the case of a local function, only set the instantiator if the
852 // receiver (or type arguments parameter of a factory) was captured. 871 // receiver (or type arguments parameter of a factory) was captured.
853 LocalVariable* instantiator = NULL; 872 LocalVariable* instantiator = NULL;
854 const bool kTestOnly = true; 873 const bool kTestOnly = true;
855 if (parser.current_function().IsInFactoryScope()) { 874 if (parser.current_function().IsInFactoryScope()) {
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 // Move forward to the start of the initializer expression. 1127 // Move forward to the start of the initializer expression.
1109 intptr_t ident_pos = TokenPos(); 1128 intptr_t ident_pos = TokenPos();
1110 ExpectIdentifier("identifier expected"); 1129 ExpectIdentifier("identifier expected");
1111 ExpectToken(Token::kASSIGN); 1130 ExpectToken(Token::kASSIGN);
1112 intptr_t token_pos = TokenPos(); 1131 intptr_t token_pos = TokenPos();
1113 1132
1114 // Synthesize a try-catch block to wrap the initializer expression. 1133 // Synthesize a try-catch block to wrap the initializer expression.
1115 LocalVariable* context_var = 1134 LocalVariable* context_var =
1116 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); 1135 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar());
1117 if (context_var == NULL) { 1136 if (context_var == NULL) {
1118 context_var = new LocalVariable(token_pos, 1137 context_var = new(I) LocalVariable(
1119 Symbols::SavedTryContextVar(), 1138 token_pos,
1120 Type::ZoneHandle(I, Type::DynamicType())); 1139 Symbols::SavedTryContextVar(),
1140 Type::ZoneHandle(I, Type::DynamicType()));
1121 current_block_->scope->AddVariable(context_var); 1141 current_block_->scope->AddVariable(context_var);
1122 } 1142 }
1123 LocalVariable* catch_excp_var = 1143 LocalVariable* catch_excp_var =
1124 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); 1144 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar());
1125 if (catch_excp_var == NULL) { 1145 if (catch_excp_var == NULL) {
1126 catch_excp_var = new LocalVariable( 1146 catch_excp_var = new (I) LocalVariable(
1127 token_pos, 1147 token_pos,
1128 Symbols::ExceptionVar(), 1148 Symbols::ExceptionVar(),
1129 Type::ZoneHandle(I, Type::DynamicType())); 1149 Type::ZoneHandle(I, Type::DynamicType()));
1130 current_block_->scope->AddVariable(catch_excp_var); 1150 current_block_->scope->AddVariable(catch_excp_var);
1131 } 1151 }
1132 LocalVariable* catch_trace_var = 1152 LocalVariable* catch_trace_var =
1133 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar()); 1153 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar());
1134 if (catch_trace_var == NULL) { 1154 if (catch_trace_var == NULL) {
1135 catch_trace_var = new LocalVariable( 1155 catch_trace_var = new (I) LocalVariable(
1136 token_pos, 1156 token_pos,
1137 Symbols::StackTraceVar(), 1157 Symbols::StackTraceVar(),
1138 Type::ZoneHandle(I, Type::DynamicType())); 1158 Type::ZoneHandle(I, Type::DynamicType()));
1139 current_block_->scope->AddVariable(catch_trace_var); 1159 current_block_->scope->AddVariable(catch_trace_var);
1140 } 1160 }
1141 1161
1142 OpenBlock(); // Start try block. 1162 OpenBlock(); // Start try block.
1143 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); 1163 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
1144 const Field& field = Field::ZoneHandle(I, func.saved_static_field()); 1164 const Field& field = Field::ZoneHandle(I, func.saved_static_field());
1145 ASSERT(!field.is_const()); 1165 ASSERT(!field.is_const());
(...skipping 4955 matching lines...) Expand 10 before | Expand all | Expand 10 after
6101 // We temporarily use the class of the Function interface. 6121 // We temporarily use the class of the Function interface.
6102 const Class& unknown_signature_class = Class::Handle(I, 6122 const Class& unknown_signature_class = Class::Handle(I,
6103 Type::Handle(I, Type::Function()).type_class()); 6123 Type::Handle(I, Type::Function()).type_class());
6104 function_type = Type::New(unknown_signature_class, 6124 function_type = Type::New(unknown_signature_class,
6105 TypeArguments::Handle(I), function_pos); 6125 TypeArguments::Handle(I), function_pos);
6106 function_type.SetIsFinalized(); // No finalization needed. 6126 function_type.SetIsFinalized(); // No finalization needed.
6107 6127
6108 // Add the function variable to the scope before parsing the function in 6128 // Add the function variable to the scope before parsing the function in
6109 // order to allow self reference from inside the function. 6129 // order to allow self reference from inside the function.
6110 function_variable = new(I) LocalVariable(function_pos, 6130 function_variable = new(I) LocalVariable(function_pos,
6111 *variable_name, 6131 *variable_name,
6112 function_type); 6132 function_type);
6113 function_variable->set_is_final(); 6133 function_variable->set_is_final();
6114 ASSERT(current_block_ != NULL); 6134 ASSERT(current_block_ != NULL);
6115 ASSERT(current_block_->scope != NULL); 6135 ASSERT(current_block_->scope != NULL);
6116 if (!current_block_->scope->AddVariable(function_variable)) { 6136 if (!current_block_->scope->AddVariable(function_variable)) {
6117 LocalVariable* existing_var = 6137 LocalVariable* existing_var =
6118 current_block_->scope->LookupVariable(function_variable->name(), 6138 current_block_->scope->LookupVariable(function_variable->name(),
6119 true); 6139 true);
6120 ASSERT(existing_var != NULL); 6140 ASSERT(existing_var != NULL);
6121 if (existing_var->owner() == current_block_->scope) { 6141 if (existing_var->owner() == current_block_->scope) {
6122 ReportError(function_pos, "identifier '%s' already defined", 6142 ReportError(function_pos, "identifier '%s' already defined",
(...skipping 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after
7274 } 7294 }
7275 7295
7276 7296
7277 // Add the inlined finally block to the specified node. 7297 // Add the inlined finally block to the specified node.
7278 void Parser::AddFinallyBlockToNode(AstNode* node, 7298 void Parser::AddFinallyBlockToNode(AstNode* node,
7279 InlinedFinallyNode* finally_node) { 7299 InlinedFinallyNode* finally_node) {
7280 ReturnNode* return_node = node->AsReturnNode(); 7300 ReturnNode* return_node = node->AsReturnNode();
7281 if (return_node != NULL) { 7301 if (return_node != NULL) {
7282 return_node->AddInlinedFinallyNode(finally_node); 7302 return_node->AddInlinedFinallyNode(finally_node);
7283 if (return_node->saved_return_value_var() == NULL) { 7303 if (return_node->saved_return_value_var() == NULL) {
7284 LocalVariable* temp = 7304 return_node->set_saved_return_value_var(
Florian Schneider 2014/08/13 10:35:22 No need to save the variable with the ReturnNode,
srdjan 2014/08/13 15:38:55 Done.
7285 CreateTempConstVariable(node->token_pos(), "finally_ret_val"); 7305 parsed_function()->EnsureFinallyReturnTemp());
7286 return_node->set_saved_return_value_var(temp);
7287 } 7306 }
7288 return; 7307 return;
7289 } 7308 }
7290 JumpNode* jump_node = node->AsJumpNode(); 7309 JumpNode* jump_node = node->AsJumpNode();
7291 ASSERT(jump_node != NULL); 7310 ASSERT(jump_node != NULL);
7292 jump_node->AddInlinedFinallyNode(finally_node); 7311 jump_node->AddInlinedFinallyNode(finally_node);
7293 } 7312 }
7294 7313
7295 7314
7296 SequenceNode* Parser::ParseCatchClauses( 7315 SequenceNode* Parser::ParseCatchClauses(
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
7558 if (CurrentToken() == Token::kFINALLY) { 7577 if (CurrentToken() == Token::kFINALLY) {
7559 ConsumeToken(); // Consume the 'finally'. 7578 ConsumeToken(); // Consume the 'finally'.
7560 const intptr_t finally_pos = TokenPos(); 7579 const intptr_t finally_pos = TokenPos();
7561 // Add the finally block to the exit points recorded so far. 7580 // Add the finally block to the exit points recorded so far.
7562 intptr_t node_index = 0; 7581 intptr_t node_index = 0;
7563 AstNode* node_to_inline = 7582 AstNode* node_to_inline =
7564 inner_try_block->GetNodeToInlineFinally(node_index); 7583 inner_try_block->GetNodeToInlineFinally(node_index);
7565 while (node_to_inline != NULL) { 7584 while (node_to_inline != NULL) {
7566 finally_block = ParseFinallyBlock(); 7585 finally_block = ParseFinallyBlock();
7567 InlinedFinallyNode* node = new(I) InlinedFinallyNode(finally_pos, 7586 InlinedFinallyNode* node = new(I) InlinedFinallyNode(finally_pos,
7568 finally_block, 7587 finally_block,
7569 context_var, 7588 context_var,
7570 outer_try_index); 7589 outer_try_index);
7571 AddFinallyBlockToNode(node_to_inline, node); 7590 AddFinallyBlockToNode(node_to_inline, node);
7572 node_index += 1; 7591 node_index += 1;
7573 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); 7592 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index);
7574 tokens_iterator_.SetCurrentPosition(finally_pos); 7593 tokens_iterator_.SetCurrentPosition(finally_pos);
7575 } 7594 }
7576 finally_block = ParseFinallyBlock(); 7595 finally_block = ParseFinallyBlock();
7577 } 7596 }
7578 7597
7579 CatchClauseNode* catch_clause = new(I) CatchClauseNode( 7598 CatchClauseNode* catch_clause = new(I) CatchClauseNode(
7580 handler_pos, 7599 handler_pos,
(...skipping 3744 matching lines...) Expand 10 before | Expand all | Expand 10 after
11325 void Parser::SkipQualIdent() { 11344 void Parser::SkipQualIdent() {
11326 ASSERT(IsIdentifier()); 11345 ASSERT(IsIdentifier());
11327 ConsumeToken(); 11346 ConsumeToken();
11328 if (CurrentToken() == Token::kPERIOD) { 11347 if (CurrentToken() == Token::kPERIOD) {
11329 ConsumeToken(); // Consume the kPERIOD token. 11348 ConsumeToken(); // Consume the kPERIOD token.
11330 ExpectIdentifier("identifier expected after '.'"); 11349 ExpectIdentifier("identifier expected after '.'");
11331 } 11350 }
11332 } 11351 }
11333 11352
11334 } // namespace dart 11353 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698