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 void 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 }
141
142
129 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { 143 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) {
130 ASSERT(node_sequence_ == NULL); 144 ASSERT(node_sequence_ == NULL);
131 ASSERT(node_sequence != NULL); 145 ASSERT(node_sequence != NULL);
132 node_sequence_ = node_sequence; 146 node_sequence_ = node_sequence;
133 } 147 }
134 148
135 149
136 void ParsedFunction::AddDeferredPrefix(const LibraryPrefix& prefix) { 150 void ParsedFunction::AddDeferredPrefix(const LibraryPrefix& prefix) {
137 ASSERT(prefix.is_deferred_load()); 151 ASSERT(prefix.is_deferred_load());
138 ASSERT(!prefix.is_loaded()); 152 ASSERT(!prefix.is_loaded());
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 // Add implicit return node. 850 // Add implicit return node.
837 node_sequence->Add(new ReturnNode(func.end_token_pos())); 851 node_sequence->Add(new ReturnNode(func.end_token_pos()));
838 } 852 }
839 if (parsed_function->has_expression_temp_var()) { 853 if (parsed_function->has_expression_temp_var()) {
840 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); 854 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var());
841 } 855 }
842 if (parsed_function->has_saved_current_context_var()) { 856 if (parsed_function->has_saved_current_context_var()) {
843 node_sequence->scope()->AddVariable( 857 node_sequence->scope()->AddVariable(
844 parsed_function->saved_current_context_var()); 858 parsed_function->saved_current_context_var());
845 } 859 }
860 if (parsed_function->has_finally_return_temp_var()) {
861 node_sequence->scope()->AddVariable(
862 parsed_function->finally_return_temp_var());
863 }
846 parsed_function->SetNodeSequence(node_sequence); 864 parsed_function->SetNodeSequence(node_sequence);
847 865
848 // The instantiator may be required at run time for generic type checks or 866 // The instantiator may be required at run time for generic type checks or
849 // allocation of generic types. 867 // allocation of generic types.
850 if (parser.IsInstantiatorRequired()) { 868 if (parser.IsInstantiatorRequired()) {
851 // In the case of a local function, only set the instantiator if the 869 // In the case of a local function, only set the instantiator if the
852 // receiver (or type arguments parameter of a factory) was captured. 870 // receiver (or type arguments parameter of a factory) was captured.
853 LocalVariable* instantiator = NULL; 871 LocalVariable* instantiator = NULL;
854 const bool kTestOnly = true; 872 const bool kTestOnly = true;
855 if (parser.current_function().IsInFactoryScope()) { 873 if (parser.current_function().IsInFactoryScope()) {
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1107 // Move forward to the start of the initializer expression. 1125 // Move forward to the start of the initializer expression.
1108 intptr_t ident_pos = TokenPos(); 1126 intptr_t ident_pos = TokenPos();
1109 ExpectIdentifier("identifier expected"); 1127 ExpectIdentifier("identifier expected");
1110 ExpectToken(Token::kASSIGN); 1128 ExpectToken(Token::kASSIGN);
1111 intptr_t token_pos = TokenPos(); 1129 intptr_t token_pos = TokenPos();
1112 1130
1113 // Synthesize a try-catch block to wrap the initializer expression. 1131 // Synthesize a try-catch block to wrap the initializer expression.
1114 LocalVariable* context_var = 1132 LocalVariable* context_var =
1115 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); 1133 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar());
1116 if (context_var == NULL) { 1134 if (context_var == NULL) {
1117 context_var = new LocalVariable(token_pos, 1135 context_var = new(I) LocalVariable(
1118 Symbols::SavedTryContextVar(), 1136 token_pos,
1119 Type::ZoneHandle(I, Type::DynamicType())); 1137 Symbols::SavedTryContextVar(),
1138 Type::ZoneHandle(I, Type::DynamicType()));
1120 current_block_->scope->AddVariable(context_var); 1139 current_block_->scope->AddVariable(context_var);
1121 } 1140 }
1122 LocalVariable* catch_excp_var = 1141 LocalVariable* catch_excp_var =
1123 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); 1142 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar());
1124 if (catch_excp_var == NULL) { 1143 if (catch_excp_var == NULL) {
1125 catch_excp_var = new LocalVariable( 1144 catch_excp_var = new (I) LocalVariable(
1126 token_pos, 1145 token_pos,
1127 Symbols::ExceptionVar(), 1146 Symbols::ExceptionVar(),
1128 Type::ZoneHandle(I, Type::DynamicType())); 1147 Type::ZoneHandle(I, Type::DynamicType()));
1129 current_block_->scope->AddVariable(catch_excp_var); 1148 current_block_->scope->AddVariable(catch_excp_var);
1130 } 1149 }
1131 LocalVariable* catch_trace_var = 1150 LocalVariable* catch_trace_var =
1132 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar()); 1151 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar());
1133 if (catch_trace_var == NULL) { 1152 if (catch_trace_var == NULL) {
1134 catch_trace_var = new LocalVariable( 1153 catch_trace_var = new (I) LocalVariable(
1135 token_pos, 1154 token_pos,
1136 Symbols::StackTraceVar(), 1155 Symbols::StackTraceVar(),
1137 Type::ZoneHandle(I, Type::DynamicType())); 1156 Type::ZoneHandle(I, Type::DynamicType()));
1138 current_block_->scope->AddVariable(catch_trace_var); 1157 current_block_->scope->AddVariable(catch_trace_var);
1139 } 1158 }
1140 1159
1141 OpenBlock(); // Start try block. 1160 OpenBlock(); // Start try block.
1142 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); 1161 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
1143 const Field& field = Field::ZoneHandle(I, func.saved_static_field()); 1162 const Field& field = Field::ZoneHandle(I, func.saved_static_field());
1144 ASSERT(!field.is_const()); 1163 ASSERT(!field.is_const());
(...skipping 4924 matching lines...) Expand 10 before | Expand all | Expand 10 after
6069 // We temporarily use the class of the Function interface. 6088 // We temporarily use the class of the Function interface.
6070 const Class& unknown_signature_class = Class::Handle(I, 6089 const Class& unknown_signature_class = Class::Handle(I,
6071 Type::Handle(I, Type::Function()).type_class()); 6090 Type::Handle(I, Type::Function()).type_class());
6072 function_type = Type::New(unknown_signature_class, 6091 function_type = Type::New(unknown_signature_class,
6073 TypeArguments::Handle(I), function_pos); 6092 TypeArguments::Handle(I), function_pos);
6074 function_type.SetIsFinalized(); // No finalization needed. 6093 function_type.SetIsFinalized(); // No finalization needed.
6075 6094
6076 // Add the function variable to the scope before parsing the function in 6095 // Add the function variable to the scope before parsing the function in
6077 // order to allow self reference from inside the function. 6096 // order to allow self reference from inside the function.
6078 function_variable = new(I) LocalVariable(function_pos, 6097 function_variable = new(I) LocalVariable(function_pos,
6079 *variable_name, 6098 *variable_name,
6080 function_type); 6099 function_type);
6081 function_variable->set_is_final(); 6100 function_variable->set_is_final();
6082 ASSERT(current_block_ != NULL); 6101 ASSERT(current_block_ != NULL);
6083 ASSERT(current_block_->scope != NULL); 6102 ASSERT(current_block_->scope != NULL);
6084 if (!current_block_->scope->AddVariable(function_variable)) { 6103 if (!current_block_->scope->AddVariable(function_variable)) {
6085 LocalVariable* existing_var = 6104 LocalVariable* existing_var =
6086 current_block_->scope->LookupVariable(function_variable->name(), 6105 current_block_->scope->LookupVariable(function_variable->name(),
6087 true); 6106 true);
6088 ASSERT(existing_var != NULL); 6107 ASSERT(existing_var != NULL);
6089 if (existing_var->owner() == current_block_->scope) { 6108 if (existing_var->owner() == current_block_->scope) {
6090 ReportError(function_pos, "identifier '%s' already defined", 6109 ReportError(function_pos, "identifier '%s' already defined",
(...skipping 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after
7240 iterator = iterator->outer_try_block(); 7259 iterator = iterator->outer_try_block();
7241 } 7260 }
7242 } 7261 }
7243 7262
7244 7263
7245 // Add the inlined finally block to the specified node. 7264 // Add the inlined finally block to the specified node.
7246 void Parser::AddFinallyBlockToNode(AstNode* node, 7265 void Parser::AddFinallyBlockToNode(AstNode* node,
7247 InlinedFinallyNode* finally_node) { 7266 InlinedFinallyNode* finally_node) {
7248 ReturnNode* return_node = node->AsReturnNode(); 7267 ReturnNode* return_node = node->AsReturnNode();
7249 if (return_node != NULL) { 7268 if (return_node != NULL) {
7269 parsed_function()->EnsureFinallyReturnTemp();
7250 return_node->AddInlinedFinallyNode(finally_node); 7270 return_node->AddInlinedFinallyNode(finally_node);
7251 if (return_node->saved_return_value_var() == NULL) {
7252 LocalVariable* temp =
7253 CreateTempConstVariable(node->token_pos(), "finally_ret_val");
7254 return_node->set_saved_return_value_var(temp);
7255 }
7256 return; 7271 return;
7257 } 7272 }
7258 JumpNode* jump_node = node->AsJumpNode(); 7273 JumpNode* jump_node = node->AsJumpNode();
7259 ASSERT(jump_node != NULL); 7274 ASSERT(jump_node != NULL);
7260 jump_node->AddInlinedFinallyNode(finally_node); 7275 jump_node->AddInlinedFinallyNode(finally_node);
7261 } 7276 }
7262 7277
7263 7278
7264 SequenceNode* Parser::ParseCatchClauses( 7279 SequenceNode* Parser::ParseCatchClauses(
7265 intptr_t handler_pos, 7280 intptr_t handler_pos,
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
7526 if (CurrentToken() == Token::kFINALLY) { 7541 if (CurrentToken() == Token::kFINALLY) {
7527 ConsumeToken(); // Consume the 'finally'. 7542 ConsumeToken(); // Consume the 'finally'.
7528 const intptr_t finally_pos = TokenPos(); 7543 const intptr_t finally_pos = TokenPos();
7529 // Add the finally block to the exit points recorded so far. 7544 // Add the finally block to the exit points recorded so far.
7530 intptr_t node_index = 0; 7545 intptr_t node_index = 0;
7531 AstNode* node_to_inline = 7546 AstNode* node_to_inline =
7532 inner_try_block->GetNodeToInlineFinally(node_index); 7547 inner_try_block->GetNodeToInlineFinally(node_index);
7533 while (node_to_inline != NULL) { 7548 while (node_to_inline != NULL) {
7534 finally_block = ParseFinallyBlock(); 7549 finally_block = ParseFinallyBlock();
7535 InlinedFinallyNode* node = new(I) InlinedFinallyNode(finally_pos, 7550 InlinedFinallyNode* node = new(I) InlinedFinallyNode(finally_pos,
7536 finally_block, 7551 finally_block,
7537 context_var, 7552 context_var,
7538 outer_try_index); 7553 outer_try_index);
7539 AddFinallyBlockToNode(node_to_inline, node); 7554 AddFinallyBlockToNode(node_to_inline, node);
7540 node_index += 1; 7555 node_index += 1;
7541 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); 7556 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index);
7542 tokens_iterator_.SetCurrentPosition(finally_pos); 7557 tokens_iterator_.SetCurrentPosition(finally_pos);
7543 } 7558 }
7544 finally_block = ParseFinallyBlock(); 7559 finally_block = ParseFinallyBlock();
7545 } 7560 }
7546 7561
7547 CatchClauseNode* catch_clause = new(I) CatchClauseNode( 7562 CatchClauseNode* catch_clause = new(I) CatchClauseNode(
7548 handler_pos, 7563 handler_pos,
(...skipping 3744 matching lines...) Expand 10 before | Expand all | Expand 10 after
11293 void Parser::SkipQualIdent() { 11308 void Parser::SkipQualIdent() {
11294 ASSERT(IsIdentifier()); 11309 ASSERT(IsIdentifier());
11295 ConsumeToken(); 11310 ConsumeToken();
11296 if (CurrentToken() == Token::kPERIOD) { 11311 if (CurrentToken() == Token::kPERIOD) {
11297 ConsumeToken(); // Consume the kPERIOD token. 11312 ConsumeToken(); // Consume the kPERIOD token.
11298 ExpectIdentifier("identifier expected after '.'"); 11313 ExpectIdentifier("identifier expected after '.'");
11299 } 11314 }
11300 } 11315 }
11301 11316
11302 } // namespace dart 11317 } // 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