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 "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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |