| 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/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/code_descriptors.h" | 9 #include "vm/code_descriptors.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 const Class& instantiator_class = Class::Handle( | 971 const Class& instantiator_class = Class::Handle( |
| 972 owner()->parsed_function().function().Owner()); | 972 owner()->parsed_function().function().Owner()); |
| 973 // Since called only when type tested against is not instantiated. | 973 // Since called only when type tested against is not instantiated. |
| 974 ASSERT(instantiator_class.NumTypeParameters() > 0); | 974 ASSERT(instantiator_class.NumTypeParameters() > 0); |
| 975 Value* instantiator_type_arguments = NULL; | 975 Value* instantiator_type_arguments = NULL; |
| 976 Value* instantiator = BuildInstantiator(); | 976 Value* instantiator = BuildInstantiator(); |
| 977 if (instantiator == NULL) { | 977 if (instantiator == NULL) { |
| 978 // No instantiator when inside factory. | 978 // No instantiator when inside factory. |
| 979 *push_instantiator_result = PushArgument(BuildNullValue()); | 979 *push_instantiator_result = PushArgument(BuildNullValue()); |
| 980 instantiator_type_arguments = | 980 instantiator_type_arguments = |
| 981 BuildInstantiatorTypeArguments(token_pos, NULL); | 981 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 982 } else { | 982 } else { |
| 983 instantiator = Bind(BuildStoreExprTemp(instantiator)); | 983 instantiator = Bind(BuildStoreExprTemp(instantiator)); |
| 984 *push_instantiator_result = PushArgument(instantiator); | 984 *push_instantiator_result = PushArgument(instantiator); |
| 985 Value* loaded = Bind(BuildLoadExprTemp()); | 985 Value* loaded = Bind(BuildLoadExprTemp()); |
| 986 instantiator_type_arguments = | 986 instantiator_type_arguments = |
| 987 BuildInstantiatorTypeArguments(token_pos, loaded); | 987 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); |
| 988 } | 988 } |
| 989 *push_instantiator_type_arguments_result = | 989 *push_instantiator_type_arguments_result = |
| 990 PushArgument(instantiator_type_arguments); | 990 PushArgument(instantiator_type_arguments); |
| 991 } | 991 } |
| 992 | 992 |
| 993 | 993 |
| 994 | 994 |
| 995 void EffectGraphVisitor::BuildTypecheckArguments( | 995 void EffectGraphVisitor::BuildTypecheckArguments( |
| 996 intptr_t token_pos, | 996 intptr_t token_pos, |
| 997 Value** instantiator_result, | 997 Value** instantiator_result, |
| 998 Value** instantiator_type_arguments_result) { | 998 Value** instantiator_type_arguments_result) { |
| 999 Value* instantiator = NULL; | 999 Value* instantiator = NULL; |
| 1000 Value* instantiator_type_arguments = NULL; | 1000 Value* instantiator_type_arguments = NULL; |
| 1001 const Class& instantiator_class = Class::Handle( | 1001 const Class& instantiator_class = Class::Handle( |
| 1002 owner()->parsed_function().function().Owner()); | 1002 owner()->parsed_function().function().Owner()); |
| 1003 // Since called only when type tested against is not instantiated. | 1003 // Since called only when type tested against is not instantiated. |
| 1004 ASSERT(instantiator_class.NumTypeParameters() > 0); | 1004 ASSERT(instantiator_class.NumTypeParameters() > 0); |
| 1005 instantiator = BuildInstantiator(); | 1005 instantiator = BuildInstantiator(); |
| 1006 if (instantiator == NULL) { | 1006 if (instantiator == NULL) { |
| 1007 // No instantiator when inside factory. | 1007 // No instantiator when inside factory. |
| 1008 instantiator = BuildNullValue(); | 1008 instantiator = BuildNullValue(); |
| 1009 instantiator_type_arguments = | 1009 instantiator_type_arguments = |
| 1010 BuildInstantiatorTypeArguments(token_pos, NULL); | 1010 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 1011 } else { | 1011 } else { |
| 1012 // Preserve instantiator. | 1012 // Preserve instantiator. |
| 1013 instantiator = Bind(BuildStoreExprTemp(instantiator)); | 1013 instantiator = Bind(BuildStoreExprTemp(instantiator)); |
| 1014 Value* loaded = Bind(BuildLoadExprTemp()); | 1014 Value* loaded = Bind(BuildLoadExprTemp()); |
| 1015 instantiator_type_arguments = | 1015 instantiator_type_arguments = |
| 1016 BuildInstantiatorTypeArguments(token_pos, loaded); | 1016 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); |
| 1017 } | 1017 } |
| 1018 *instantiator_result = instantiator; | 1018 *instantiator_result = instantiator; |
| 1019 *instantiator_type_arguments_result = instantiator_type_arguments; | 1019 *instantiator_type_arguments_result = instantiator_type_arguments; |
| 1020 } | 1020 } |
| 1021 | 1021 |
| 1022 | 1022 |
| 1023 Value* EffectGraphVisitor::BuildNullValue() { | 1023 Value* EffectGraphVisitor::BuildNullValue() { |
| 1024 return Bind(new ConstantInstr(Object::ZoneHandle())); | 1024 return Bind(new ConstantInstr(Object::ZoneHandle())); |
| 1025 } | 1025 } |
| 1026 | 1026 |
| (...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1836 ASSERT(function.context_scope() != ContextScope::null()); | 1836 ASSERT(function.context_scope() != ContextScope::null()); |
| 1837 | 1837 |
| 1838 // The function type of a closure may have type arguments. In that case, pass | 1838 // The function type of a closure may have type arguments. In that case, pass |
| 1839 // the type arguments of the instantiator. Otherwise, pass null object. | 1839 // the type arguments of the instantiator. Otherwise, pass null object. |
| 1840 const Class& cls = Class::Handle(function.signature_class()); | 1840 const Class& cls = Class::Handle(function.signature_class()); |
| 1841 ASSERT(!cls.IsNull()); | 1841 ASSERT(!cls.IsNull()); |
| 1842 const bool requires_type_arguments = cls.HasTypeArguments(); | 1842 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 1843 Value* type_arguments = NULL; | 1843 Value* type_arguments = NULL; |
| 1844 if (requires_type_arguments) { | 1844 if (requires_type_arguments) { |
| 1845 ASSERT(!function.IsImplicitStaticClosureFunction()); | 1845 ASSERT(!function.IsImplicitStaticClosureFunction()); |
| 1846 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), NULL); | 1846 const Class& instantiator_class = Class::Handle( |
| 1847 owner()->parsed_function().function().Owner()); |
| 1848 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), |
| 1849 instantiator_class, |
| 1850 NULL); |
| 1847 } else { | 1851 } else { |
| 1848 type_arguments = BuildNullValue(); | 1852 type_arguments = BuildNullValue(); |
| 1849 } | 1853 } |
| 1850 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); | 1854 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); |
| 1851 arguments->Add(push_type_arguments); | 1855 arguments->Add(push_type_arguments); |
| 1852 ReturnDefinition( | 1856 ReturnDefinition( |
| 1853 new CreateClosureInstr(node->function(), arguments, node->token_pos())); | 1857 new CreateClosureInstr(node->function(), arguments, node->token_pos())); |
| 1854 } | 1858 } |
| 1855 | 1859 |
| 1856 | 1860 |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2154 ValueGraphVisitor for_instantiator(owner(), temp_index()); | 2158 ValueGraphVisitor for_instantiator(owner(), temp_index()); |
| 2155 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | 2159 owner()->parsed_function().instantiator()->Visit(&for_instantiator); |
| 2156 Append(for_instantiator); | 2160 Append(for_instantiator); |
| 2157 return for_instantiator.value(); | 2161 return for_instantiator.value(); |
| 2158 } | 2162 } |
| 2159 | 2163 |
| 2160 | 2164 |
| 2161 // 'expression_temp_var' may not be used inside this method if 'instantiator' | 2165 // 'expression_temp_var' may not be used inside this method if 'instantiator' |
| 2162 // is not NULL. | 2166 // is not NULL. |
| 2163 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 2167 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 2164 intptr_t token_pos, Value* instantiator) { | 2168 intptr_t token_pos, |
| 2165 const Class& instantiator_class = Class::Handle( | 2169 const Class& instantiator_class, |
| 2166 owner()->parsed_function().function().Owner()); | 2170 Value* instantiator) { |
| 2167 if (instantiator_class.NumTypeParameters() == 0) { | 2171 if (instantiator_class.NumTypeParameters() == 0) { |
| 2168 // The type arguments are compile time constants. | 2172 // The type arguments are compile time constants. |
| 2169 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); | 2173 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); |
| 2170 // Type is temporary. Only its type arguments are preserved. | 2174 // Type is temporary. Only its type arguments are preserved. |
| 2171 Type& type = Type::Handle( | 2175 Type& type = Type::Handle( |
| 2172 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); | 2176 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); |
| 2173 type ^= ClassFinalizer::FinalizeType( | 2177 type ^= ClassFinalizer::FinalizeType( |
| 2174 instantiator_class, type, ClassFinalizer::kFinalize); | 2178 instantiator_class, type, ClassFinalizer::kFinalize); |
| 2175 ASSERT(!type.IsMalformed()); | 2179 ASSERT(!type.IsMalformed()); |
| 2176 type_arguments = type.arguments(); | 2180 type_arguments = type.arguments(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2209 } | 2213 } |
| 2210 | 2214 |
| 2211 | 2215 |
| 2212 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( | 2216 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
| 2213 intptr_t token_pos, | 2217 intptr_t token_pos, |
| 2214 const AbstractTypeArguments& type_arguments) { | 2218 const AbstractTypeArguments& type_arguments) { |
| 2215 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 2219 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
| 2216 return Bind(new ConstantInstr(type_arguments)); | 2220 return Bind(new ConstantInstr(type_arguments)); |
| 2217 } | 2221 } |
| 2218 // The type arguments are uninstantiated. | 2222 // The type arguments are uninstantiated. |
| 2223 const Class& instantiator_class = Class::ZoneHandle( |
| 2224 owner()->parsed_function().function().Owner()); |
| 2219 Value* instantiator_value = | 2225 Value* instantiator_value = |
| 2220 BuildInstantiatorTypeArguments(token_pos, NULL); | 2226 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 2221 return Bind(new InstantiateTypeArgumentsInstr(token_pos, | 2227 return Bind(new InstantiateTypeArgumentsInstr(token_pos, |
| 2222 type_arguments, | 2228 type_arguments, |
| 2229 instantiator_class, |
| 2223 instantiator_value)); | 2230 instantiator_value)); |
| 2224 } | 2231 } |
| 2225 | 2232 |
| 2226 | 2233 |
| 2227 void EffectGraphVisitor::BuildConstructorTypeArguments( | 2234 void EffectGraphVisitor::BuildConstructorTypeArguments( |
| 2228 ConstructorCallNode* node, | 2235 ConstructorCallNode* node, |
| 2229 Value** type_arguments, | 2236 Value** type_arguments, |
| 2230 Value** instantiator, | 2237 Value** instantiator, |
| 2231 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { | 2238 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { |
| 2232 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 2239 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2258 // t1 = InstantiatorTypeArguments(); | 2265 // t1 = InstantiatorTypeArguments(); |
| 2259 // t2 = ExtractConstructorTypeArguments(t1); | 2266 // t2 = ExtractConstructorTypeArguments(t1); |
| 2260 // t1 = ExtractConstructorInstantiator(t1); | 2267 // t1 = ExtractConstructorInstantiator(t1); |
| 2261 // t_n <- t2 | 2268 // t_n <- t2 |
| 2262 // t_n+1 <- t1 | 2269 // t_n+1 <- t1 |
| 2263 // Use expression_temp_var and node->allocated_object_var() locals to keep | 2270 // Use expression_temp_var and node->allocated_object_var() locals to keep |
| 2264 // intermediate results around (t1 and t2 above). | 2271 // intermediate results around (t1 and t2 above). |
| 2265 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); | 2272 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); |
| 2266 const LocalVariable& t1 = *owner()->parsed_function().expression_temp_var(); | 2273 const LocalVariable& t1 = *owner()->parsed_function().expression_temp_var(); |
| 2267 const LocalVariable& t2 = node->allocated_object_var(); | 2274 const LocalVariable& t2 = node->allocated_object_var(); |
| 2275 const Class& instantiator_class = Class::Handle( |
| 2276 owner()->parsed_function().function().Owner()); |
| 2268 Value* instantiator_type_arguments = BuildInstantiatorTypeArguments( | 2277 Value* instantiator_type_arguments = BuildInstantiatorTypeArguments( |
| 2269 node->token_pos(), NULL); | 2278 node->token_pos(), instantiator_class, NULL); |
| 2270 Value* stored_instantiator = | 2279 Value* stored_instantiator = |
| 2271 Bind(BuildStoreTemp(t1, instantiator_type_arguments)); | 2280 Bind(BuildStoreTemp(t1, instantiator_type_arguments)); |
| 2272 // t1: instantiator type arguments. | 2281 // t1: instantiator type arguments. |
| 2273 | 2282 |
| 2274 Value* extract_type_arguments = Bind( | 2283 Value* extract_type_arguments = Bind( |
| 2275 new ExtractConstructorTypeArgumentsInstr( | 2284 new ExtractConstructorTypeArgumentsInstr( |
| 2276 node->token_pos(), | 2285 node->token_pos(), |
| 2277 node->type_arguments(), | 2286 node->type_arguments(), |
| 2287 instantiator_class, |
| 2278 stored_instantiator)); | 2288 stored_instantiator)); |
| 2279 | 2289 |
| 2280 Do(BuildStoreTemp(t2, extract_type_arguments)); | 2290 Do(BuildStoreTemp(t2, extract_type_arguments)); |
| 2281 // t2: extracted constructor type arguments. | 2291 // t2: extracted constructor type arguments. |
| 2282 Value* load_instantiator = Bind(BuildLoadLocal(t1)); | 2292 Value* load_instantiator = Bind(BuildLoadLocal(t1)); |
| 2283 | 2293 |
| 2284 Value* extract_instantiator = | 2294 Value* extract_instantiator = |
| 2285 Bind(new ExtractConstructorInstantiatorInstr(node, load_instantiator)); | 2295 Bind(new ExtractConstructorInstantiatorInstr(node, |
| 2296 instantiator_class, |
| 2297 load_instantiator)); |
| 2286 Do(BuildStoreTemp(t1, extract_instantiator)); | 2298 Do(BuildStoreTemp(t1, extract_instantiator)); |
| 2287 // t2: extracted constructor type arguments. | 2299 // t2: extracted constructor type arguments. |
| 2288 // t1: extracted constructor instantiator. | 2300 // t1: extracted constructor instantiator. |
| 2289 Value* type_arguments_val = Bind(BuildLoadLocal(t2)); | 2301 Value* type_arguments_val = Bind(BuildLoadLocal(t2)); |
| 2290 if (call_arguments != NULL) { | 2302 if (call_arguments != NULL) { |
| 2291 ASSERT(type_arguments == NULL); | 2303 ASSERT(type_arguments == NULL); |
| 2292 call_arguments->Add(PushArgument(type_arguments_val)); | 2304 call_arguments->Add(PushArgument(type_arguments_val)); |
| 2293 } else { | 2305 } else { |
| 2294 ASSERT(type_arguments != NULL); | 2306 ASSERT(type_arguments != NULL); |
| 2295 *type_arguments = type_arguments_val; | 2307 *type_arguments = type_arguments_val; |
| (...skipping 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3360 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3372 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 3361 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3373 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 3362 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3374 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 3363 const Error& error = Error::Handle( | 3375 const Error& error = Error::Handle( |
| 3364 LanguageError::New(String::Handle(String::New(chars)))); | 3376 LanguageError::New(String::Handle(String::New(chars)))); |
| 3365 Isolate::Current()->long_jump_base()->Jump(1, error); | 3377 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 3366 } | 3378 } |
| 3367 | 3379 |
| 3368 | 3380 |
| 3369 } // namespace dart | 3381 } // namespace dart |
| OLD | NEW |