| 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 1999 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2010 } | 2010 } |
| 2011 | 2011 |
| 2012 | 2012 |
| 2013 Value* EffectGraphVisitor::BuildObjectAllocation( | 2013 Value* EffectGraphVisitor::BuildObjectAllocation( |
| 2014 ConstructorCallNode* node) { | 2014 ConstructorCallNode* node) { |
| 2015 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 2015 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 2016 const bool requires_type_arguments = cls.HasTypeArguments(); | 2016 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 2017 | 2017 |
| 2018 // In checked mode, if the type arguments are uninstantiated, they may need to | 2018 // In checked mode, if the type arguments are uninstantiated, they may need to |
| 2019 // be checked against declared bounds at run time. | 2019 // be checked against declared bounds at run time. |
| 2020 Definition* allocate_comp = NULL; | 2020 Definition* allocation = NULL; |
| 2021 if (FLAG_enable_type_checks && | 2021 if (FLAG_enable_type_checks && |
| 2022 requires_type_arguments && | 2022 requires_type_arguments && |
| 2023 !node->type_arguments().IsNull() && | 2023 !node->type_arguments().IsNull() && |
| 2024 !node->type_arguments().IsInstantiated() && | 2024 !node->type_arguments().IsInstantiated() && |
| 2025 node->type_arguments().IsBounded()) { | 2025 node->type_arguments().IsBounded()) { |
| 2026 Value* type_arguments = NULL; | 2026 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = |
| 2027 Value* instantiator = NULL; | 2027 new ZoneGrowableArray<PushArgumentInstr*>(4); |
| 2028 BuildConstructorTypeArguments(node, &type_arguments, &instantiator, NULL); | 2028 // Argument 1: Empty argument slot for return value. |
| 2029 Value* null_val = Bind(new ConstantInstr(Object::ZoneHandle())); |
| 2030 allocate_arguments->Add(PushArgument(null_val)); |
| 2031 // Argument 2: Class. |
| 2032 Value* cls_val = |
| 2033 Bind(new ConstantInstr(Class::ZoneHandle(node->constructor().Owner()))); |
| 2034 allocate_arguments->Add(PushArgument(cls_val)); |
| 2035 // Build arguments 3 and 4. |
| 2036 BuildConstructorTypeArguments(node, allocate_arguments); |
| 2029 | 2037 |
| 2030 // The uninstantiated type arguments cannot be verified to be within their | 2038 // The uninstantiated type arguments cannot be verified to be within their |
| 2031 // bounds at compile time, so verify them at runtime. | 2039 // bounds at compile time, so verify them at runtime. |
| 2032 allocate_comp = new AllocateObjectWithBoundsCheckInstr(node, | 2040 allocation = new AllocateObjectWithBoundsCheckInstr(node); |
| 2033 type_arguments, | |
| 2034 instantiator); | |
| 2035 } else { | 2041 } else { |
| 2036 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = | 2042 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = |
| 2037 new ZoneGrowableArray<PushArgumentInstr*>(); | 2043 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 2038 | |
| 2039 if (requires_type_arguments) { | 2044 if (requires_type_arguments) { |
| 2040 BuildConstructorTypeArguments(node, NULL, NULL, allocate_arguments); | 2045 BuildConstructorTypeArguments(node, allocate_arguments); |
| 2041 } | 2046 } |
| 2042 | 2047 |
| 2043 allocate_comp = new AllocateObjectInstr(node, allocate_arguments); | 2048 allocation = new AllocateObjectInstr(node, allocate_arguments); |
| 2044 } | 2049 } |
| 2045 return Bind(allocate_comp); | 2050 return Bind(allocation); |
| 2046 } | 2051 } |
| 2047 | 2052 |
| 2048 | 2053 |
| 2049 void EffectGraphVisitor::BuildConstructorCall( | 2054 void EffectGraphVisitor::BuildConstructorCall( |
| 2050 ConstructorCallNode* node, | 2055 ConstructorCallNode* node, |
| 2051 PushArgumentInstr* push_alloc_value) { | 2056 PushArgumentInstr* push_alloc_value) { |
| 2052 Value* ctor_arg = Bind( | 2057 Value* ctor_arg = Bind( |
| 2053 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); | 2058 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); |
| 2054 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); | 2059 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); |
| 2055 | 2060 |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2242 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 2247 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 2243 return Bind(new InstantiateTypeArgumentsInstr(token_pos, | 2248 return Bind(new InstantiateTypeArgumentsInstr(token_pos, |
| 2244 type_arguments, | 2249 type_arguments, |
| 2245 instantiator_class, | 2250 instantiator_class, |
| 2246 instantiator_value)); | 2251 instantiator_value)); |
| 2247 } | 2252 } |
| 2248 | 2253 |
| 2249 | 2254 |
| 2250 void EffectGraphVisitor::BuildConstructorTypeArguments( | 2255 void EffectGraphVisitor::BuildConstructorTypeArguments( |
| 2251 ConstructorCallNode* node, | 2256 ConstructorCallNode* node, |
| 2252 Value** type_arguments, | |
| 2253 Value** instantiator, | |
| 2254 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { | 2257 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { |
| 2255 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 2258 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 2256 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); | 2259 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); |
| 2257 if (node->type_arguments().IsNull() || | 2260 if (node->type_arguments().IsNull() || |
| 2258 node->type_arguments().IsInstantiated()) { | 2261 node->type_arguments().IsInstantiated()) { |
| 2259 Value* type_arguments_val = Bind(new ConstantInstr(node->type_arguments())); | 2262 Value* type_arguments_val = Bind(new ConstantInstr(node->type_arguments())); |
| 2260 if (call_arguments != NULL) { | 2263 call_arguments->Add(PushArgument(type_arguments_val)); |
| 2261 ASSERT(type_arguments == NULL); | |
| 2262 call_arguments->Add(PushArgument(type_arguments_val)); | |
| 2263 } else { | |
| 2264 ASSERT(type_arguments != NULL); | |
| 2265 *type_arguments = type_arguments_val; | |
| 2266 } | |
| 2267 | 2264 |
| 2268 // No instantiator required. | 2265 // No instantiator required. |
| 2269 Value* instantiator_val = Bind(new ConstantInstr( | 2266 Value* instantiator_val = Bind(new ConstantInstr( |
| 2270 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); | 2267 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); |
| 2271 if (call_arguments != NULL) { | 2268 call_arguments->Add(PushArgument(instantiator_val)); |
| 2272 ASSERT(instantiator == NULL); | |
| 2273 call_arguments->Add(PushArgument(instantiator_val)); | |
| 2274 } else { | |
| 2275 ASSERT(instantiator != NULL); | |
| 2276 *instantiator = instantiator_val; | |
| 2277 } | |
| 2278 return; | 2269 return; |
| 2279 } | 2270 } |
| 2271 |
| 2280 // The type arguments are uninstantiated. We use expression_temp_var to save | 2272 // The type arguments are uninstantiated. We use expression_temp_var to save |
| 2281 // the instantiator type arguments becuase they have two uses. | 2273 // the instantiator type arguments because they have two uses. |
| 2282 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); | 2274 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); |
| 2283 const LocalVariable& temp = *owner()->parsed_function().expression_temp_var(); | 2275 const LocalVariable& temp = *owner()->parsed_function().expression_temp_var(); |
| 2284 const Class& instantiator_class = Class::Handle( | 2276 const Class& instantiator_class = Class::Handle( |
| 2285 owner()->parsed_function().function().Owner()); | 2277 owner()->parsed_function().function().Owner()); |
| 2286 Value* type_arguments_val = BuildInstantiatorTypeArguments( | 2278 Value* type_arguments_val = BuildInstantiatorTypeArguments( |
| 2287 node->token_pos(), instantiator_class, NULL); | 2279 node->token_pos(), instantiator_class, NULL); |
| 2288 | 2280 |
| 2289 const bool use_instantiator_type_args = | 2281 const bool use_instantiator_type_args = |
| 2290 node->type_arguments().IsUninstantiatedIdentity() || | 2282 node->type_arguments().IsUninstantiatedIdentity() || |
| 2291 node->type_arguments().CanShareInstantiatorTypeArguments( | 2283 node->type_arguments().CanShareInstantiatorTypeArguments( |
| 2292 instantiator_class); | 2284 instantiator_class); |
| 2293 | 2285 |
| 2294 if (!use_instantiator_type_args) { | 2286 if (!use_instantiator_type_args) { |
| 2295 type_arguments_val = | 2287 const intptr_t len = node->type_arguments().Length(); |
| 2296 Bind(BuildStoreTemp(temp, type_arguments_val)); | 2288 if (node->type_arguments().IsRawInstantiatedRaw(len)) { |
| 2297 type_arguments_val = Bind( | 2289 type_arguments_val = |
| 2298 new ExtractConstructorTypeArgumentsInstr( | 2290 Bind(BuildStoreTemp(temp, type_arguments_val)); |
| 2299 node->token_pos(), | 2291 type_arguments_val = Bind( |
| 2300 node->type_arguments(), | 2292 new ExtractConstructorTypeArgumentsInstr( |
| 2301 instantiator_class, | 2293 node->token_pos(), |
| 2302 type_arguments_val)); | 2294 node->type_arguments(), |
| 2295 instantiator_class, |
| 2296 type_arguments_val)); |
| 2297 } else { |
| 2298 Do(BuildStoreTemp(temp, type_arguments_val)); |
| 2299 type_arguments_val = Bind(new ConstantInstr(node->type_arguments())); |
| 2300 } |
| 2303 } | 2301 } |
| 2304 | 2302 call_arguments->Add(PushArgument(type_arguments_val)); |
| 2305 if (call_arguments != NULL) { | |
| 2306 ASSERT(type_arguments == NULL); | |
| 2307 call_arguments->Add(PushArgument(type_arguments_val)); | |
| 2308 } else { | |
| 2309 ASSERT(type_arguments != NULL); | |
| 2310 *type_arguments = type_arguments_val; | |
| 2311 } | |
| 2312 | 2303 |
| 2313 Value* instantiator_val = NULL; | 2304 Value* instantiator_val = NULL; |
| 2314 if (!use_instantiator_type_args) { | 2305 if (!use_instantiator_type_args) { |
| 2315 instantiator_val = Bind(BuildLoadLocal(temp)); | 2306 instantiator_val = Bind(BuildLoadLocal(temp)); |
| 2316 instantiator_val = | 2307 const intptr_t len = node->type_arguments().Length(); |
| 2317 Bind(new ExtractConstructorInstantiatorInstr(node, | 2308 if (node->type_arguments().IsRawInstantiatedRaw(len)) { |
| 2318 instantiator_class, | 2309 instantiator_val = |
| 2319 instantiator_val)); | 2310 Bind(new ExtractConstructorInstantiatorInstr(node, |
| 2311 instantiator_class, |
| 2312 instantiator_val)); |
| 2313 } |
| 2320 } else { | 2314 } else { |
| 2321 // No instantiator required. | 2315 // No instantiator required. |
| 2322 instantiator_val = Bind(new ConstantInstr( | 2316 instantiator_val = Bind(new ConstantInstr( |
| 2323 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); | 2317 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); |
| 2324 } | 2318 } |
| 2325 | 2319 call_arguments->Add(PushArgument(instantiator_val)); |
| 2326 if (call_arguments != NULL) { | |
| 2327 ASSERT(instantiator == NULL); | |
| 2328 call_arguments->Add(PushArgument(instantiator_val)); | |
| 2329 } else { | |
| 2330 ASSERT(instantiator != NULL); | |
| 2331 *instantiator = instantiator_val; | |
| 2332 } | |
| 2333 } | 2320 } |
| 2334 | 2321 |
| 2335 | 2322 |
| 2336 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 2323 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 2337 if (node->constructor().IsFactory()) { | 2324 if (node->constructor().IsFactory()) { |
| 2338 EffectGraphVisitor::VisitConstructorCallNode(node); | 2325 EffectGraphVisitor::VisitConstructorCallNode(node); |
| 2339 return; | 2326 return; |
| 2340 } | 2327 } |
| 2341 | 2328 |
| 2342 // t_n contains the allocated and initialized object. | 2329 // t_n contains the allocated and initialized object. |
| (...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3389 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3376 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 3390 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3377 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 3391 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3378 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 3392 const Error& error = Error::Handle( | 3379 const Error& error = Error::Handle( |
| 3393 LanguageError::New(String::Handle(String::New(chars)))); | 3380 LanguageError::New(String::Handle(String::New(chars)))); |
| 3394 Isolate::Current()->long_jump_base()->Jump(1, error); | 3381 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 3395 } | 3382 } |
| 3396 | 3383 |
| 3397 | 3384 |
| 3398 } // namespace dart | 3385 } // namespace dart |
| OLD | NEW |