| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 bool ClassFinalizer::AllClassesFinalized() { | 42 bool ClassFinalizer::AllClassesFinalized() { |
| 43 ObjectStore* object_store = Isolate::Current()->object_store(); | 43 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 44 const Array& classes = Array::Handle(object_store->pending_classes()); | 44 const Array& classes = Array::Handle(object_store->pending_classes()); |
| 45 return classes.Length() == 0; | 45 return classes.Length() == 0; |
| 46 } | 46 } |
| 47 | 47 |
| 48 | 48 |
| 49 // Class finalization occurs: | 49 // Class finalization occurs: |
| 50 // a) when bootstrap process completes (VerifyBootstrapClasses). | 50 // a) when bootstrap process completes (VerifyBootstrapClasses). |
| 51 // b) after the user classes are loaded (dart_api). | 51 // b) after the user classes are loaded (dart_api). |
| 52 bool ClassFinalizer::FinalizePendingClasses() { | 52 bool ClassFinalizer::FinalizePendingClasses(bool generating_snapshot) { |
| 53 bool retval = true; | 53 bool retval = true; |
| 54 Isolate* isolate = Isolate::Current(); | 54 Isolate* isolate = Isolate::Current(); |
| 55 ASSERT(isolate != NULL); | 55 ASSERT(isolate != NULL); |
| 56 ObjectStore* object_store = isolate->object_store(); | 56 ObjectStore* object_store = isolate->object_store(); |
| 57 const String& error = String::Handle(object_store->sticky_error()); | 57 const String& error = String::Handle(object_store->sticky_error()); |
| 58 if (!error.IsNull()) { | 58 if (!error.IsNull()) { |
| 59 return false; | 59 return false; |
| 60 } | 60 } |
| 61 LongJump* base = isolate->long_jump_base(); | 61 LongJump* base = isolate->long_jump_base(); |
| 62 LongJump jump; | 62 LongJump jump; |
| 63 isolate->set_long_jump_base(&jump); | 63 isolate->set_long_jump_base(&jump); |
| 64 if (setjmp(*jump.Set()) == 0) { | 64 if (setjmp(*jump.Set()) == 0) { |
| 65 const Array& class_array = Array::Handle(object_store->pending_classes()); | 65 const Array& class_array = Array::Handle(object_store->pending_classes()); |
| 66 ASSERT(!class_array.IsNull()); | 66 ASSERT(!class_array.IsNull()); |
| 67 Class& cls = Class::Handle(); | 67 Class& cls = Class::Handle(); |
| 68 // First resolve all superclasses. | 68 // First resolve all superclasses. |
| 69 for (intptr_t i = 0; i < class_array.Length(); i++) { | 69 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 70 cls ^= class_array.At(i); | 70 cls ^= class_array.At(i); |
| 71 if (FLAG_trace_class_finalization) { | 71 if (FLAG_trace_class_finalization) { |
| 72 OS::Print("Resolving super and default: %s\n", cls.ToCString()); | 72 OS::Print("Resolving super and default: %s\n", cls.ToCString()); |
| 73 } | 73 } |
| 74 ResolveSuperType(cls); | 74 ResolveSuperType(cls); |
| 75 if (cls.is_interface()) { | 75 if (cls.is_interface()) { |
| 76 ResolveFactoryClass(cls); | 76 ResolveFactoryClass(cls); |
| 77 } | 77 } |
| 78 } | 78 } |
| 79 // Finalize all classes. | 79 // Finalize all classes. |
| 80 for (intptr_t i = 0; i < class_array.Length(); i++) { | 80 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 81 cls ^= class_array.At(i); | 81 cls ^= class_array.At(i); |
| 82 FinalizeClass(cls); | 82 FinalizeClass(cls, generating_snapshot); |
| 83 } | 83 } |
| 84 if (FLAG_print_classes) { | 84 if (FLAG_print_classes) { |
| 85 for (intptr_t i = 0; i < class_array.Length(); i++) { | 85 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 86 cls ^= class_array.At(i); | 86 cls ^= class_array.At(i); |
| 87 PrintClassInformation(cls); | 87 PrintClassInformation(cls); |
| 88 } | 88 } |
| 89 } | 89 } |
| 90 if (FLAG_verify_implements) { | 90 if (FLAG_verify_implements) { |
| 91 for (intptr_t i = 0; i < class_array.Length(); i++) { | 91 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 92 cls ^= class_array.At(i); | 92 cls ^= class_array.At(i); |
| (...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 function_name.ToCString(), | 977 function_name.ToCString(), |
| 978 class_name.ToCString(), | 978 class_name.ToCString(), |
| 979 function_name.ToCString(), | 979 function_name.ToCString(), |
| 980 super_class_name.ToCString()); | 980 super_class_name.ToCString()); |
| 981 } | 981 } |
| 982 } | 982 } |
| 983 } | 983 } |
| 984 } | 984 } |
| 985 | 985 |
| 986 | 986 |
| 987 void ClassFinalizer::FinalizeClass(const Class& cls) { | 987 void ClassFinalizer::FinalizeClass(const Class& cls, bool generating_snapshot) { |
| 988 if (cls.is_finalized()) { | 988 if (cls.is_finalized()) { |
| 989 return; | 989 return; |
| 990 } | 990 } |
| 991 if (FLAG_trace_class_finalization) { | 991 if (FLAG_trace_class_finalization) { |
| 992 OS::Print("Finalize %s\n", cls.ToCString()); | 992 OS::Print("Finalize %s\n", cls.ToCString()); |
| 993 } | 993 } |
| 994 // Signature classes are finalized upon creation. | 994 // Signature classes are finalized upon creation. |
| 995 ASSERT(!cls.IsSignatureClass()); | 995 ASSERT(!cls.IsSignatureClass()); |
| 996 if (!IsSuperCycleFree(cls)) { | 996 if (!IsSuperCycleFree(cls)) { |
| 997 const String& name = String::Handle(cls.Name()); | 997 const String& name = String::Handle(cls.Name()); |
| 998 const Script& script = Script::Handle(cls.script()); | 998 const Script& script = Script::Handle(cls.script()); |
| 999 ReportError(script, -1, | 999 ReportError(script, -1, |
| 1000 "class '%s' has a cycle in its superclass relationship.\n", | 1000 "class '%s' has a cycle in its superclass relationship.\n", |
| 1001 name.ToCString()); | 1001 name.ToCString()); |
| 1002 } | 1002 } |
| 1003 GrowableArray<const Class*> visited; | 1003 GrowableArray<const Class*> visited; |
| 1004 ResolveInterfaces(cls, &visited); | 1004 ResolveInterfaces(cls, &visited); |
| 1005 Type& super_type = Type::Handle(cls.super_type()); | 1005 Type& super_type = Type::Handle(cls.super_type()); |
| 1006 if (!super_type.IsNull()) { | 1006 if (!super_type.IsNull()) { |
| 1007 const Class& super_class = Class::Handle(super_type.type_class()); | 1007 const Class& super_class = Class::Handle(super_type.type_class()); |
| 1008 // Finalize super class and super type. | 1008 // Finalize super class and super type. |
| 1009 FinalizeClass(super_class); | 1009 FinalizeClass(super_class, generating_snapshot); |
| 1010 super_type = FinalizeType(super_type); | 1010 super_type = FinalizeType(super_type); |
| 1011 cls.set_super_type(super_type); | 1011 cls.set_super_type(super_type); |
| 1012 } | 1012 } |
| 1013 if (cls.is_interface()) { | 1013 if (cls.is_interface()) { |
| 1014 if (cls.HasFactoryClass()) { | 1014 if (cls.HasFactoryClass()) { |
| 1015 const Class& factory_class = Class::Handle(cls.FactoryClass()); | 1015 const Class& factory_class = Class::Handle(cls.FactoryClass()); |
| 1016 // Finalize factory class. | 1016 // Finalize factory class. |
| 1017 if (!factory_class.is_finalized()) { | 1017 if (!factory_class.is_finalized()) { |
| 1018 FinalizeClass(factory_class); | 1018 FinalizeClass(factory_class, generating_snapshot); |
| 1019 // Finalizing the factory class may indirectly finalize this interface. | 1019 // Finalizing the factory class may indirectly finalize this interface. |
| 1020 if (cls.is_finalized()) { | 1020 if (cls.is_finalized()) { |
| 1021 return; | 1021 return; |
| 1022 } | 1022 } |
| 1023 } | 1023 } |
| 1024 } | 1024 } |
| 1025 } | 1025 } |
| 1026 // Finalize interface types (but not necessarily interface classes). | 1026 // Finalize interface types (but not necessarily interface classes). |
| 1027 Array& interface_types = Array::Handle(cls.interfaces()); | 1027 Array& interface_types = Array::Handle(cls.interfaces()); |
| 1028 Type& interface_type = Type::Handle(); | 1028 Type& interface_type = Type::Handle(); |
| 1029 for (intptr_t i = 0; i < interface_types.Length(); i++) { | 1029 for (intptr_t i = 0; i < interface_types.Length(); i++) { |
| 1030 interface_type ^= interface_types.At(i); | 1030 interface_type ^= interface_types.At(i); |
| 1031 interface_type = FinalizeType(interface_type); | 1031 interface_type = FinalizeType(interface_type); |
| 1032 interface_types.SetAt(i, interface_type); | 1032 interface_types.SetAt(i, interface_type); |
| 1033 } | 1033 } |
| 1034 // Mark as finalized before resolving type parameter upper bounds and member | 1034 // Mark as finalized before resolving type parameter upper bounds and member |
| 1035 // types in order to break cycles. | 1035 // types in order to break cycles. |
| 1036 cls.Finalize(); | 1036 cls.Finalize(); |
| 1037 ResolveAndFinalizeUpperBounds(cls); | 1037 ResolveAndFinalizeUpperBounds(cls); |
| 1038 ResolveAndFinalizeMemberTypes(cls); | 1038 ResolveAndFinalizeMemberTypes(cls); |
| 1039 // Run additional checks after all types are finalized. | 1039 // Run additional checks after all types are finalized. |
| 1040 if (cls.is_const()) { | 1040 if (cls.is_const()) { |
| 1041 CheckForLegalConstClass(cls); | 1041 CheckForLegalConstClass(cls); |
| 1042 } | 1042 } |
| 1043 // Check to ensure we don't have classes with native fields in libraries | 1043 // Check to ensure we don't have classes with native fields in libraries |
| 1044 // which do not have a native resolver. | 1044 // which do not have a native resolver. |
| 1045 if (cls.num_native_fields() != 0) { | 1045 if (!generating_snapshot && cls.num_native_fields() != 0) { |
| 1046 const Library& lib = Library::Handle(cls.library()); | 1046 const Library& lib = Library::Handle(cls.library()); |
| 1047 if (lib.native_entry_resolver() == NULL) { | 1047 if (lib.native_entry_resolver() == NULL) { |
| 1048 const String& cls_name = String::Handle(cls.Name()); | 1048 const String& cls_name = String::Handle(cls.Name()); |
| 1049 const String& lib_name = String::Handle(lib.url()); | 1049 const String& lib_name = String::Handle(lib.url()); |
| 1050 const Script& script = Script::Handle(cls.script()); | 1050 const Script& script = Script::Handle(cls.script()); |
| 1051 ReportError(script, -1, | 1051 ReportError(script, -1, |
| 1052 "class '%s' is trying to extend a native fields class, " | 1052 "class '%s' is trying to extend a native fields class, " |
| 1053 "but library '%s' has no native resolvers", | 1053 "but library '%s' has no native resolvers", |
| 1054 cls_name.ToCString(), lib_name.ToCString()); | 1054 cls_name.ToCString(), lib_name.ToCString()); |
| 1055 } | 1055 } |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 va_end(args); | 1306 va_end(args); |
| 1307 if (FLAG_warning_as_error) { | 1307 if (FLAG_warning_as_error) { |
| 1308 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); | 1308 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); |
| 1309 UNREACHABLE(); | 1309 UNREACHABLE(); |
| 1310 } else { | 1310 } else { |
| 1311 OS::Print(message_buffer); | 1311 OS::Print(message_buffer); |
| 1312 } | 1312 } |
| 1313 } | 1313 } |
| 1314 | 1314 |
| 1315 } // namespace dart | 1315 } // namespace dart |
| OLD | NEW |