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/code_generator.h" | 5 #include "vm/code_generator.h" |
6 | 6 |
7 #include "vm/assembler_macros.h" | 7 #include "vm/assembler_macros.h" |
8 #include "vm/ast.h" | 8 #include "vm/ast.h" |
9 #include "vm/code_patcher.h" | 9 #include "vm/code_patcher.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 if (!type_class.HasTypeArguments()) { | 370 if (!type_class.HasTypeArguments()) { |
371 return true; | 371 return true; |
372 } | 372 } |
373 AbstractTypeArguments& type_arguments = | 373 AbstractTypeArguments& type_arguments = |
374 AbstractTypeArguments::Handle(instance.GetTypeArguments()); | 374 AbstractTypeArguments::Handle(instance.GetTypeArguments()); |
375 if (type_arguments.IsNull()) { | 375 if (type_arguments.IsNull()) { |
376 return true; | 376 return true; |
377 } | 377 } |
378 if (type_arguments.IsInstantiatedTypeArguments()) { | 378 if (type_arguments.IsInstantiatedTypeArguments()) { |
379 do { | 379 do { |
380 InstantiatedTypeArguments& instantiated_type_arguments = | 380 const InstantiatedTypeArguments& instantiated_type_arguments = |
381 InstantiatedTypeArguments::Handle(); | 381 InstantiatedTypeArguments::Cast(type_arguments); |
382 instantiated_type_arguments ^= type_arguments.raw(); | |
383 const AbstractTypeArguments& uninstantiated = | 382 const AbstractTypeArguments& uninstantiated = |
384 AbstractTypeArguments::Handle( | 383 AbstractTypeArguments::Handle( |
385 instantiated_type_arguments.uninstantiated_type_arguments()); | 384 instantiated_type_arguments.uninstantiated_type_arguments()); |
386 const AbstractTypeArguments& instantiator = | 385 const AbstractTypeArguments& instantiator = |
387 AbstractTypeArguments::Handle( | 386 AbstractTypeArguments::Handle( |
388 instantiated_type_arguments.instantiator_type_arguments()); | 387 instantiated_type_arguments.instantiator_type_arguments()); |
389 type_arguments = uninstantiated.InstantiateFrom(instantiator); | 388 type_arguments = uninstantiated.InstantiateFrom(instantiator); |
390 } while (type_arguments.IsInstantiatedTypeArguments()); | 389 } while (type_arguments.IsInstantiatedTypeArguments()); |
391 TypeArguments& new_type_arguments = TypeArguments::Handle(); | 390 AbstractTypeArguments& new_type_arguments = AbstractTypeArguments::Handle(); |
392 new_type_arguments ^= type_arguments.raw(); | 391 new_type_arguments = type_arguments.Canonicalize(); |
393 new_type_arguments ^= new_type_arguments.Canonicalize(); | |
394 instance.SetTypeArguments(new_type_arguments); | 392 instance.SetTypeArguments(new_type_arguments); |
395 *type_arguments_replaced = true; | 393 *type_arguments_replaced = true; |
396 } else if (!type_arguments.IsCanonical()) { | 394 } else if (!type_arguments.IsCanonical()) { |
397 AbstractTypeArguments& new_type_arguments = | 395 AbstractTypeArguments& new_type_arguments = AbstractTypeArguments::Handle(); |
398 AbstractTypeArguments::Handle(); | 396 new_type_arguments = type_arguments.Canonicalize(); |
399 new_type_arguments ^= type_arguments.Canonicalize(); | |
400 instance.SetTypeArguments(new_type_arguments); | 397 instance.SetTypeArguments(new_type_arguments); |
401 *type_arguments_replaced = true; | 398 *type_arguments_replaced = true; |
402 } | 399 } |
403 ASSERT(AbstractTypeArguments::Handle( | 400 ASSERT(AbstractTypeArguments::Handle( |
404 instance.GetTypeArguments()).IsTypeArguments()); | 401 instance.GetTypeArguments()).IsTypeArguments()); |
405 return true; | 402 return true; |
406 } | 403 } |
407 | 404 |
408 | 405 |
409 // This updates the type test cache, an array containing 4-value elements | 406 // This updates the type test cache, an array containing 4-value elements |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 if (FLAG_trace_type_checks) { | 448 if (FLAG_trace_type_checks) { |
452 PrintTypeCheck("WARNING: Cannot canonicalize instantiator " | 449 PrintTypeCheck("WARNING: Cannot canonicalize instantiator " |
453 "type arguments", | 450 "type arguments", |
454 instance, type, instantiator_type_arguments, result); | 451 instance, type, instantiator_type_arguments, result); |
455 } | 452 } |
456 return; | 453 return; |
457 } | 454 } |
458 if (replaced) { | 455 if (replaced) { |
459 type_arguments_replaced = true; | 456 type_arguments_replaced = true; |
460 } | 457 } |
461 instantiator_type_arguments ^= instantiator.GetTypeArguments(); | 458 instantiator_type_arguments = instantiator.GetTypeArguments(); |
462 } | 459 } |
463 | 460 |
464 Class& last_instance_class = Class::Handle(); | 461 Class& last_instance_class = Class::Handle(); |
465 AbstractTypeArguments& last_instance_type_arguments = | 462 AbstractTypeArguments& last_instance_type_arguments = |
466 AbstractTypeArguments::Handle(); | 463 AbstractTypeArguments::Handle(); |
467 AbstractTypeArguments& last_instantiator_type_arguments = | 464 AbstractTypeArguments& last_instantiator_type_arguments = |
468 AbstractTypeArguments::Handle(); | 465 AbstractTypeArguments::Handle(); |
469 Bool& last_result = Bool::Handle(); | 466 Bool& last_result = Bool::Handle(); |
470 intptr_t len = new_cache.NumberOfChecks(); | 467 intptr_t len = new_cache.NumberOfChecks(); |
471 for (intptr_t i = 0; i < len; ++i) { | 468 for (intptr_t i = 0; i < len; ++i) { |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 num_named_arguments); | 779 num_named_arguments); |
783 return function.CurrentCode(); | 780 return function.CurrentCode(); |
784 } | 781 } |
785 } | 782 } |
786 | 783 |
787 | 784 |
788 // Result of an invoke may be an unhandled exception, in which case we | 785 // Result of an invoke may be an unhandled exception, in which case we |
789 // rethrow it. | 786 // rethrow it. |
790 static void CheckResultError(const Object& result) { | 787 static void CheckResultError(const Object& result) { |
791 if (result.IsError()) { | 788 if (result.IsError()) { |
792 Exceptions::PropagateError(result); | 789 Exceptions::PropagateError(Error::Cast(result)); |
793 } | 790 } |
794 } | 791 } |
795 | 792 |
796 | 793 |
797 // Resolves an instance function and compiles it if necessary. | 794 // Resolves an instance function and compiles it if necessary. |
798 // Arg0: receiver object. | 795 // Arg0: receiver object. |
799 // Returns: RawCode object or NULL (method not found or not compileable). | 796 // Returns: RawCode object or NULL (method not found or not compileable). |
800 // This is called by the megamorphic stub when instance call does not need to be | 797 // This is called by the megamorphic stub when instance call does not need to be |
801 // patched. | 798 // patched. |
802 // Used by megamorphic lookup/no-such-method-handling. | 799 // Used by megamorphic lookup/no-such-method-handling. |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 const ICData& ic_data = ICData::CheckedHandle(arguments.At(1)); | 995 const ICData& ic_data = ICData::CheckedHandle(arguments.At(1)); |
999 const String& original_function_name = String::Handle(ic_data.target_name()); | 996 const String& original_function_name = String::Handle(ic_data.target_name()); |
1000 const String& getter_prefix = String::Handle(String::New("get:")); | 997 const String& getter_prefix = String::Handle(String::New("get:")); |
1001 Closure& closure = Closure::Handle(); | 998 Closure& closure = Closure::Handle(); |
1002 if (!original_function_name.StartsWith(getter_prefix)) { | 999 if (!original_function_name.StartsWith(getter_prefix)) { |
1003 // This is not a getter so can't be the case where we are trying to | 1000 // This is not a getter so can't be the case where we are trying to |
1004 // create an implicit closure of an instance function. | 1001 // create an implicit closure of an instance function. |
1005 arguments.SetReturn(closure); | 1002 arguments.SetReturn(closure); |
1006 return; | 1003 return; |
1007 } | 1004 } |
1008 Class& receiver_class = Class::Handle(); | 1005 const Class& receiver_class = Class::Handle(receiver.clazz()); |
1009 receiver_class ^= receiver.clazz(); | |
1010 ASSERT(!receiver_class.IsNull()); | 1006 ASSERT(!receiver_class.IsNull()); |
1011 String& func_name = String::Handle(); | 1007 String& func_name = String::Handle(); |
1012 func_name = String::SubString(original_function_name, getter_prefix.Length()); | 1008 func_name = String::SubString(original_function_name, getter_prefix.Length()); |
1013 func_name = String::NewSymbol(func_name); | 1009 func_name = String::NewSymbol(func_name); |
1014 const Function& function = Function::Handle( | 1010 const Function& function = Function::Handle( |
1015 LookupDynamicFunction(isolate, receiver_class, func_name)); | 1011 LookupDynamicFunction(isolate, receiver_class, func_name)); |
1016 if (function.IsNull()) { | 1012 if (function.IsNull()) { |
1017 // There is no function of the same name so can't be the case where | 1013 // There is no function of the same name so can't be the case where |
1018 // we are trying to create an implicit closure of an instance function. | 1014 // we are trying to create an implicit closure of an instance function. |
1019 arguments.SetReturn(closure); | 1015 arguments.SetReturn(closure); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 Object::Handle(DartEntry::InvokeDynamic(receiver, | 1063 Object::Handle(DartEntry::InvokeDynamic(receiver, |
1068 function, | 1064 function, |
1069 invoke_arguments, | 1065 invoke_arguments, |
1070 kNoArgumentNames)); | 1066 kNoArgumentNames)); |
1071 if (result.IsError()) { | 1067 if (result.IsError()) { |
1072 if (result.IsUnhandledException()) { | 1068 if (result.IsUnhandledException()) { |
1073 // If the getter throws an exception, treat as no such method. | 1069 // If the getter throws an exception, treat as no such method. |
1074 arguments.SetReturn(code); | 1070 arguments.SetReturn(code); |
1075 return; | 1071 return; |
1076 } else { | 1072 } else { |
1077 Exceptions::PropagateError(result); | 1073 Exceptions::PropagateError(Error::Cast(result)); |
1078 } | 1074 } |
1079 } | 1075 } |
1080 if (!result.IsSmi()) { | 1076 if (!result.IsSmi()) { |
1081 const Class& cls = Class::Handle(result.clazz()); | 1077 const Class& cls = Class::Handle(result.clazz()); |
1082 ASSERT(!cls.IsNull()); | 1078 ASSERT(!cls.IsNull()); |
1083 function = cls.signature_function(); | 1079 function = cls.signature_function(); |
1084 if (!function.IsNull()) { | 1080 if (!function.IsNull()) { |
1085 arguments.SetReturn(result); | 1081 arguments.SetReturn(result); |
1086 return; // Return closure object. | 1082 return; // Return closure object. |
1087 } | 1083 } |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1534 | 1530 |
1535 | 1531 |
1536 // Adds a pointer to the store buffer. | 1532 // Adds a pointer to the store buffer. |
1537 // ptr: the address of a field being stored into. | 1533 // ptr: the address of a field being stored into. |
1538 DEFINE_LEAF_RUNTIME_ENTRY(void, StoreBuffer, uword ptr) { | 1534 DEFINE_LEAF_RUNTIME_ENTRY(void, StoreBuffer, uword ptr) { |
1539 Isolate::Current()->store_buffer()->AddPointer(ptr); | 1535 Isolate::Current()->store_buffer()->AddPointer(ptr); |
1540 } | 1536 } |
1541 END_LEAF_RUNTIME_ENTRY | 1537 END_LEAF_RUNTIME_ENTRY |
1542 | 1538 |
1543 } // namespace dart | 1539 } // namespace dart |
OLD | NEW |