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