Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: vm/class_finalizer.cc

Issue 9594028: Add a first class GrowableObjectArray type in the VM and use it internally in the VM at all spots w… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « vm/class_finalizer.h ('k') | vm/class_finalizer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/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"
11 #include "vm/object_store.h" 11 #include "vm/object_store.h"
12 #include "vm/parser.h" 12 #include "vm/parser.h"
13 13
14 namespace dart { 14 namespace dart {
15 15
16 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); 16 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes.");
17 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); 17 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization.");
18 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); 18 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization.");
19 DEFINE_FLAG(bool, verify_implements, false, 19 DEFINE_FLAG(bool, verify_implements, false,
20 "Verify that all classes implement their interface."); 20 "Verify that all classes implement their interface.");
21 DECLARE_FLAG(bool, enable_type_checks); 21 DECLARE_FLAG(bool, enable_type_checks);
22 22
23 void ClassFinalizer::AddPendingClasses(
24 const GrowableArray<const Class*>& classes) {
25 if (!classes.is_empty()) {
26 ObjectStore* object_store = Isolate::Current()->object_store();
27 const Array& old_array = Array::Handle(object_store->pending_classes());
28 const intptr_t old_length = old_array.Length();
29 const int new_length = old_length + classes.length();
30 const Array& new_array = Array::Handle(Array::Grow(old_array, new_length));
31 // Add new classes.
32 for (int i = 0; i < classes.length(); i++) {
33 new_array.SetAt(i + old_length, *classes[i]);
34 }
35 object_store->set_pending_classes(new_array);
36 }
37 }
38
39 23
40 bool ClassFinalizer::AllClassesFinalized() { 24 bool ClassFinalizer::AllClassesFinalized() {
41 ObjectStore* object_store = Isolate::Current()->object_store(); 25 ObjectStore* object_store = Isolate::Current()->object_store();
42 const Array& classes = Array::Handle(object_store->pending_classes()); 26 const GrowableObjectArray& classes =
27 GrowableObjectArray::Handle(object_store->pending_classes());
43 return classes.Length() == 0; 28 return classes.Length() == 0;
44 } 29 }
45 30
46 31
47 // Class finalization occurs: 32 // Class finalization occurs:
48 // a) when bootstrap process completes (VerifyBootstrapClasses). 33 // a) when bootstrap process completes (VerifyBootstrapClasses).
49 // b) after the user classes are loaded (dart_api). 34 // b) after the user classes are loaded (dart_api).
50 bool ClassFinalizer::FinalizePendingClasses(bool generating_snapshot) { 35 bool ClassFinalizer::FinalizePendingClasses(bool generating_snapshot) {
51 bool retval = true; 36 bool retval = true;
52 Isolate* isolate = Isolate::Current(); 37 Isolate* isolate = Isolate::Current();
53 ASSERT(isolate != NULL); 38 ASSERT(isolate != NULL);
54 ObjectStore* object_store = isolate->object_store(); 39 ObjectStore* object_store = isolate->object_store();
55 const Error& error = Error::Handle(object_store->sticky_error()); 40 const Error& error = Error::Handle(object_store->sticky_error());
56 if (!error.IsNull()) { 41 if (!error.IsNull()) {
57 return false; 42 return false;
58 } 43 }
59 LongJump* base = isolate->long_jump_base(); 44 LongJump* base = isolate->long_jump_base();
60 LongJump jump; 45 LongJump jump;
61 isolate->set_long_jump_base(&jump); 46 isolate->set_long_jump_base(&jump);
62 if (setjmp(*jump.Set()) == 0) { 47 if (setjmp(*jump.Set()) == 0) {
63 const Array& class_array = Array::Handle(object_store->pending_classes()); 48 GrowableObjectArray& class_array = GrowableObjectArray::Handle();
49 class_array = object_store->pending_classes();
64 ASSERT(!class_array.IsNull()); 50 ASSERT(!class_array.IsNull());
65 Class& cls = Class::Handle(); 51 Class& cls = Class::Handle();
66 // First resolve all superclasses. 52 // First resolve all superclasses.
67 for (intptr_t i = 0; i < class_array.Length(); i++) { 53 for (intptr_t i = 0; i < class_array.Length(); i++) {
68 cls ^= class_array.At(i); 54 cls ^= class_array.At(i);
69 if (FLAG_trace_class_finalization) { 55 if (FLAG_trace_class_finalization) {
70 OS::Print("Resolving super and default: %s\n", cls.ToCString()); 56 OS::Print("Resolving super and default: %s\n", cls.ToCString());
71 } 57 }
72 ResolveSuperType(cls); 58 ResolveSuperType(cls);
73 if (cls.is_interface()) { 59 if (cls.is_interface()) {
(...skipping 13 matching lines...) Expand all
87 } 73 }
88 if (FLAG_verify_implements) { 74 if (FLAG_verify_implements) {
89 for (intptr_t i = 0; i < class_array.Length(); i++) { 75 for (intptr_t i = 0; i < class_array.Length(); i++) {
90 cls ^= class_array.At(i); 76 cls ^= class_array.At(i);
91 if (!cls.is_interface()) { 77 if (!cls.is_interface()) {
92 VerifyClassImplements(cls); 78 VerifyClassImplements(cls);
93 } 79 }
94 } 80 }
95 } 81 }
96 // Clear pending classes array. 82 // Clear pending classes array.
97 object_store->set_pending_classes(Array::Handle(Array::Empty())); 83 class_array = GrowableObjectArray::New();
84 object_store->set_pending_classes(class_array);
98 85
99 // Check to ensure there are no duplicate definitions in the library 86 // Check to ensure there are no duplicate definitions in the library
100 // hierarchy. 87 // hierarchy.
101 const String& str = String::Handle(Library::CheckForDuplicateDefinition()); 88 const String& str = String::Handle(Library::CheckForDuplicateDefinition());
102 if (!str.IsNull()) { 89 if (!str.IsNull()) {
103 ReportError("Duplicate definition : %s\n", str.ToCString()); 90 ReportError("Duplicate definition : %s\n", str.ToCString());
104 } 91 }
105 } else { 92 } else {
106 retval = false; 93 retval = false;
107 } 94 }
108 isolate->set_long_jump_base(base); 95 isolate->set_long_jump_base(base);
109 return retval; 96 return retval;
110 } 97 }
111 98
112 99
113 #if defined (DEBUG) 100 #if defined (DEBUG)
114 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. 101 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur.
115 // No cycles are allowed. 102 // No cycles are allowed.
116 void ClassFinalizer::CollectInterfaces(const Class& cls, 103 void ClassFinalizer::CollectInterfaces(const Class& cls,
117 GrowableArray<const Class*>* collected) { 104 const GrowableObjectArray& collected) {
118 const Array& interface_array = Array::ZoneHandle(cls.interfaces()); 105 const Array& interface_array = Array::ZoneHandle(cls.interfaces());
106 AbstractType& interface = AbstractType::Handle();
107 Class& interface_class = Class::Handle();
119 for (intptr_t i = 0; i < interface_array.Length(); i++) { 108 for (intptr_t i = 0; i < interface_array.Length(); i++) {
120 AbstractType& interface = AbstractType::Handle();
121 interface ^= interface_array.At(i); 109 interface ^= interface_array.At(i);
122 const Class& interface_class = Class::ZoneHandle(interface.type_class()); 110 interface_class = interface.type_class();
123 collected->Add(&interface_class); 111 collected.Add(interface_class);
124 CollectInterfaces(interface_class, collected); 112 CollectInterfaces(interface_class, collected);
125 } 113 }
126 } 114 }
127 115
128 116
129 // Collect all interfaces of the class 'cls' and check that every function 117 // Collect all interfaces of the class 'cls' and check that every function
130 // defined in each interface can be found in the class. 118 // defined in each interface can be found in the class.
131 // No need to check instance fields since they have been turned into 119 // No need to check instance fields since they have been turned into
132 // getters/setters. 120 // getters/setters.
133 void ClassFinalizer::VerifyClassImplements(const Class& cls) { 121 void ClassFinalizer::VerifyClassImplements(const Class& cls) {
134 ASSERT(!cls.is_interface()); 122 ASSERT(!cls.is_interface());
135 GrowableArray<const Class*> interfaces; 123 const GrowableObjectArray& interfaces =
136 CollectInterfaces(cls, &interfaces); 124 GrowableObjectArray::Handle(GrowableObjectArray::New());
125 CollectInterfaces(cls, interfaces);
137 const String& class_name = String::Handle(cls.Name()); 126 const String& class_name = String::Handle(cls.Name());
138 for (int i = 0; i < interfaces.length(); i++) { 127 Class& interface_class = Class::Handle();
139 const String& interface_name = String::Handle(interfaces[i]->Name()); 128 String& interface_name = String::Handle();
140 const Array& interface_functions = 129 Array& interface_functions = Array::Handle();
141 Array::Handle(interfaces[i]->functions()); 130 for (int i = 0; i < interfaces.Length(); i++) {
131 interface_class ^= interfaces.At(i);
132 interface_name = interface_class.Name();
133 interface_functions = interface_class.functions();
142 for (intptr_t f = 0; f < interface_functions.Length(); f++) { 134 for (intptr_t f = 0; f < interface_functions.Length(); f++) {
143 Function& interface_function = Function::Handle(); 135 Function& interface_function = Function::Handle();
144 interface_function ^= interface_functions.At(f); 136 interface_function ^= interface_functions.At(f);
145 const String& function_name = String::Handle(interface_function.name()); 137 const String& function_name = String::Handle(interface_function.name());
146 // Check for constructor/factory. 138 // Check for constructor/factory.
147 if (function_name.StartsWith(interface_name)) { 139 if (function_name.StartsWith(interface_name)) {
148 // TODO(srdjan): convert 'InterfaceName.' to 'ClassName.' and check. 140 // TODO(srdjan): convert 'InterfaceName.' to 'ClassName.' and check.
149 continue; 141 continue;
150 } 142 }
151 if (interface_function.kind() == RawFunction::kConstImplicitGetter) { 143 if (interface_function.kind() == RawFunction::kConstImplicitGetter) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 ASSERT(Array::InstanceSize() == cls.instance_size()); 215 ASSERT(Array::InstanceSize() == cls.instance_size());
224 cls = object_store->immutable_array_class(); 216 cls = object_store->immutable_array_class();
225 ASSERT(ImmutableArray::InstanceSize() == cls.instance_size()); 217 ASSERT(ImmutableArray::InstanceSize() == cls.instance_size());
226 cls = object_store->internal_byte_array_class(); 218 cls = object_store->internal_byte_array_class();
227 ASSERT(InternalByteArray::InstanceSize() == cls.instance_size()); 219 ASSERT(InternalByteArray::InstanceSize() == cls.instance_size());
228 cls = object_store->external_byte_array_class(); 220 cls = object_store->external_byte_array_class();
229 ASSERT(ExternalByteArray::InstanceSize() == cls.instance_size()); 221 ASSERT(ExternalByteArray::InstanceSize() == cls.instance_size());
230 #endif // defined(DEBUG) 222 #endif // defined(DEBUG)
231 223
232 // Remember the currently pending classes. 224 // Remember the currently pending classes.
233 const Array& class_array = Array::Handle(object_store->pending_classes()); 225 const GrowableObjectArray& class_array =
226 GrowableObjectArray::Handle(object_store->pending_classes());
234 for (intptr_t i = 0; i < class_array.Length(); i++) { 227 for (intptr_t i = 0; i < class_array.Length(); i++) {
235 // TODO(iposva): Add real checks. 228 // TODO(iposva): Add real checks.
236 cls ^= class_array.At(i); 229 cls ^= class_array.At(i);
237 if (cls.is_finalized() || cls.is_prefinalized()) { 230 if (cls.is_finalized() || cls.is_prefinalized()) {
238 // Pre-finalized bootstrap classes must not define any fields. 231 // Pre-finalized bootstrap classes must not define any fields.
239 ASSERT(Array::Handle(cls.fields()).Length() == 0); 232 ASSERT(Array::Handle(cls.fields()).Length() == 0);
240 } 233 }
241 } 234 }
242 235
243 // Finalize classes that aren't pre-finalized by Object::Init(). 236 // Finalize classes that aren't pre-finalized by Object::Init().
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 } 896 }
904 // Signature classes are finalized upon creation. 897 // Signature classes are finalized upon creation.
905 ASSERT(!cls.IsSignatureClass()); 898 ASSERT(!cls.IsSignatureClass());
906 if (!IsSuperCycleFree(cls)) { 899 if (!IsSuperCycleFree(cls)) {
907 const String& name = String::Handle(cls.Name()); 900 const String& name = String::Handle(cls.Name());
908 const Script& script = Script::Handle(cls.script()); 901 const Script& script = Script::Handle(cls.script());
909 ReportError(script, cls.token_index(), 902 ReportError(script, cls.token_index(),
910 "class '%s' has a cycle in its superclass relationship", 903 "class '%s' has a cycle in its superclass relationship",
911 name.ToCString()); 904 name.ToCString());
912 } 905 }
913 GrowableArray<const Class*> visited; 906 const GrowableObjectArray& visited =
914 ResolveInterfaces(cls, &visited); 907 GrowableObjectArray::Handle(GrowableObjectArray::New());
908 ResolveInterfaces(cls, visited);
915 Type& super_type = Type::Handle(cls.super_type()); 909 Type& super_type = Type::Handle(cls.super_type());
916 if (!super_type.IsNull()) { 910 if (!super_type.IsNull()) {
917 const Class& super_class = Class::Handle(super_type.type_class()); 911 const Class& super_class = Class::Handle(super_type.type_class());
918 // Finalize super class and super type. 912 // Finalize super class and super type.
919 FinalizeClass(super_class, generating_snapshot); 913 FinalizeClass(super_class, generating_snapshot);
920 super_type ^= FinalizeType(cls, super_type, kFinalizeWellFormed); 914 super_type ^= FinalizeType(cls, super_type, kFinalizeWellFormed);
921 cls.set_super_type(super_type); 915 cls.set_super_type(super_type);
922 } 916 }
923 if (cls.is_interface()) { 917 if (cls.is_interface()) {
924 if (cls.HasFactoryClass()) { 918 if (cls.HasFactoryClass()) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
983 if (!test2.IsNull()) { 977 if (!test2.IsNull()) {
984 test2 = test2.SuperClass(); 978 test2 = test2.SuperClass();
985 } 979 }
986 } 980 }
987 // No cycles. 981 // No cycles.
988 return true; 982 return true;
989 } 983 }
990 984
991 985
992 bool ClassFinalizer::AddInterfaceIfUnique( 986 bool ClassFinalizer::AddInterfaceIfUnique(
993 GrowableArray<AbstractType*>* interface_list, 987 const GrowableObjectArray& interface_list,
994 AbstractType* interface, 988 const AbstractType& interface,
995 AbstractType* conflicting) { 989 AbstractType* conflicting) {
996 String& interface_class_name = String::Handle(interface->ClassName()); 990 String& interface_class_name = String::Handle(interface.ClassName());
997 String& existing_interface_class_name = String::Handle(); 991 String& existing_interface_class_name = String::Handle();
998 for (intptr_t i = 0; i < interface_list->length(); i++) { 992 String& interface_name = String::Handle();
999 existing_interface_class_name = (*interface_list)[i]->ClassName(); 993 String& existing_interface_name = String::Handle();
994 AbstractType& other_interface = AbstractType::Handle();
995 for (intptr_t i = 0; i < interface_list.Length(); i++) {
996 other_interface ^= interface_list.At(i);
997 existing_interface_class_name = other_interface.ClassName();
1000 if (interface_class_name.Equals(existing_interface_class_name)) { 998 if (interface_class_name.Equals(existing_interface_class_name)) {
1001 // Same interface class name, now check names of type arguments. 999 // Same interface class name, now check names of type arguments.
1002 const String& interface_name = String::Handle(interface->Name()); 1000 interface_name = interface.Name();
1003 const String& existing_interface_name = 1001 existing_interface_name = other_interface.Name();
1004 String::Handle((*interface_list)[i]->Name());
1005 // TODO(regis): Revisit depending on the outcome of issue 4905685. 1002 // TODO(regis): Revisit depending on the outcome of issue 4905685.
1006 if (!interface_name.Equals(existing_interface_name)) { 1003 if (!interface_name.Equals(existing_interface_name)) {
1007 *conflicting = (*interface_list)[i]->raw(); 1004 *conflicting = other_interface.raw();
1008 return false; 1005 return false;
1009 } else { 1006 } else {
1010 return true; 1007 return true;
1011 } 1008 }
1012 } 1009 }
1013 } 1010 }
1014 interface_list->Add(interface); 1011 interface_list.Add(interface);
1015 return true; 1012 return true;
1016 } 1013 }
1017 1014
1018 1015
1019 template<typename T>
1020 static RawArray* NewArray(const GrowableArray<T*>& objs) {
1021 Array& a = Array::Handle(Array::New(objs.length()));
1022 for (int i = 0; i < objs.length(); i++) {
1023 a.SetAt(i, *objs[i]);
1024 }
1025 return a.raw();
1026 }
1027
1028
1029 // Walks the graph of explicitly declared interfaces of classes and 1016 // Walks the graph of explicitly declared interfaces of classes and
1030 // interfaces recursively. Resolves unresolved interfaces. 1017 // interfaces recursively. Resolves unresolved interfaces.
1031 // Returns false if there is an interface reference that cannot be 1018 // Returns false if there is an interface reference that cannot be
1032 // resolved, or if there is a cycle in the graph. We detect cycles by 1019 // resolved, or if there is a cycle in the graph. We detect cycles by
1033 // remembering interfaces we've visited in each path through the 1020 // remembering interfaces we've visited in each path through the
1034 // graph. If we visit an interface a second time on a given path, 1021 // graph. If we visit an interface a second time on a given path,
1035 // we found a loop. 1022 // we found a loop.
1036 void ClassFinalizer::ResolveInterfaces(const Class& cls, 1023 void ClassFinalizer::ResolveInterfaces(const Class& cls,
1037 GrowableArray<const Class*>* visited) { 1024 const GrowableObjectArray& visited) {
1038 ASSERT(visited != NULL); 1025 ASSERT(!visited.IsNull());
1039 for (int i = 0; i < visited->length(); i++) { 1026 Class& visited_cls = Class::Handle();
1040 if ((*visited)[i]->raw() == cls.raw()) { 1027 for (int i = 0; i < visited.Length(); i++) {
1028 visited_cls ^= visited.At(i);
1029 if (visited_cls.raw() == cls.raw()) {
1041 // We have already visited interface class 'cls'. We found a cycle. 1030 // We have already visited interface class 'cls'. We found a cycle.
1042 const String& interface_name = String::Handle(cls.Name()); 1031 const String& interface_name = String::Handle(cls.Name());
1043 const Script& script = Script::Handle(cls.script()); 1032 const Script& script = Script::Handle(cls.script());
1044 ReportError(script, cls.token_index(), 1033 ReportError(script, cls.token_index(),
1045 "cyclic reference found for interface '%s'", 1034 "cyclic reference found for interface '%s'",
1046 interface_name.ToCString()); 1035 interface_name.ToCString());
1047 } 1036 }
1048 } 1037 }
1049 1038
1050 // If the class/interface has no explicit interfaces, we are done. 1039 // If the class/interface has no explicit interfaces, we are done.
1051 Array& super_interfaces = Array::Handle(cls.interfaces()); 1040 Array& super_interfaces = Array::Handle(cls.interfaces());
1052 if (super_interfaces.Length() == 0) { 1041 if (super_interfaces.Length() == 0) {
1053 return; 1042 return;
1054 } 1043 }
1055 1044
1056 // If cls belongs to core lib or to core lib's implementation, restrictions 1045 // If cls belongs to core lib or to core lib's implementation, restrictions
1057 // about allowed interfaces are lifted. 1046 // about allowed interfaces are lifted.
1058 const bool cls_belongs_to_core_lib = 1047 const bool cls_belongs_to_core_lib =
1059 (cls.library() == Library::CoreLibrary()) || 1048 (cls.library() == Library::CoreLibrary()) ||
1060 (cls.library() == Library::CoreImplLibrary()); 1049 (cls.library() == Library::CoreImplLibrary());
1061 1050
1062 // Resolve and check the interfaces of cls. 1051 // Resolve and check the interfaces of cls.
1063 visited->Add(&cls); 1052 visited.Add(cls);
1064 AbstractType& interface = AbstractType::Handle(); 1053 AbstractType& interface = AbstractType::Handle();
1054 Class& interface_class = Class::Handle();
1065 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { 1055 for (intptr_t i = 0; i < super_interfaces.Length(); i++) {
1066 interface ^= super_interfaces.At(i); 1056 interface ^= super_interfaces.At(i);
1067 ResolveType(cls, interface, kFinalizeWellFormed); 1057 ResolveType(cls, interface, kFinalizeWellFormed);
1068 if (interface.IsTypeParameter()) { 1058 if (interface.IsTypeParameter()) {
1069 const Script& script = Script::Handle(cls.script()); 1059 const Script& script = Script::Handle(cls.script());
1070 ReportError(script, cls.token_index(), 1060 ReportError(script, cls.token_index(),
1071 "type parameter '%s' cannot be used as interface", 1061 "type parameter '%s' cannot be used as interface",
1072 String::Handle(interface.Name()).ToCString()); 1062 String::Handle(interface.Name()).ToCString());
1073 } 1063 }
1074 const Class& interface_class = Class::Handle(interface.type_class()); 1064 interface_class = interface.type_class();
1075 if (!interface_class.is_interface()) { 1065 if (!interface_class.is_interface()) {
1076 const Script& script = Script::Handle(cls.script()); 1066 const Script& script = Script::Handle(cls.script());
1077 ReportError(script, cls.token_index(), 1067 ReportError(script, cls.token_index(),
1078 "class '%s' is used where an interface is expected", 1068 "class '%s' is used where an interface is expected",
1079 String::Handle(interface_class.Name()).ToCString()); 1069 String::Handle(interface_class.Name()).ToCString());
1080 } 1070 }
1081 // Verify that unless cls belongs to core lib, it cannot extend or implement 1071 // Verify that unless cls belongs to core lib, it cannot extend or implement
1082 // any of bool, num, int, double, String, Function, Dynamic. 1072 // any of bool, num, int, double, String, Function, Dynamic.
1083 // The exception is signature classes, which are compiler generated and 1073 // The exception is signature classes, which are compiler generated and
1084 // represent a function type, therefore implementing the Function interface. 1074 // represent a function type, therefore implementing the Function interface.
1085 if (!cls_belongs_to_core_lib) { 1075 if (!cls_belongs_to_core_lib) {
1086 if (interface.IsBoolInterface() || 1076 if (interface.IsBoolInterface() ||
1087 interface.IsNumberInterface() || 1077 interface.IsNumberInterface() ||
1088 interface.IsIntInterface() || 1078 interface.IsIntInterface() ||
1089 interface.IsDoubleInterface() || 1079 interface.IsDoubleInterface() ||
1090 interface.IsStringInterface() || 1080 interface.IsStringInterface() ||
1091 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || 1081 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) ||
1092 interface.IsDynamicType()) { 1082 interface.IsDynamicType()) {
1093 const Script& script = Script::Handle(cls.script()); 1083 const Script& script = Script::Handle(cls.script());
1094 ReportError(script, cls.token_index(), 1084 ReportError(script, cls.token_index(),
1095 "'%s' is not allowed to extend or implement '%s'", 1085 "'%s' is not allowed to extend or implement '%s'",
1096 String::Handle(cls.Name()).ToCString(), 1086 String::Handle(cls.Name()).ToCString(),
1097 String::Handle(interface_class.Name()).ToCString()); 1087 String::Handle(interface_class.Name()).ToCString());
1098 } 1088 }
1099 } 1089 }
1100 // Now resolve the super interfaces. 1090 // Now resolve the super interfaces.
1101 ResolveInterfaces(interface_class, visited); 1091 ResolveInterfaces(interface_class, visited);
1102 } 1092 }
1103 visited->RemoveLast(); 1093 visited.RemoveLast();
1104 } 1094 }
1105 1095
1106 1096
1107 // A class is marked as constant if it has one constant constructor. 1097 // A class is marked as constant if it has one constant constructor.
1108 // A constant class: 1098 // A constant class:
1109 // - may extend only const classes. 1099 // - may extend only const classes.
1110 // - has only const instance fields. 1100 // - has only const instance fields.
1111 // Note: we must check for cycles before checking for const properties. 1101 // Note: we must check for cycles before checking for const properties.
1112 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) { 1102 void ClassFinalizer::CheckForLegalConstClass(const Class& cls) {
1113 ASSERT(cls.is_const()); 1103 ASSERT(cls.is_const());
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1220 void ClassFinalizer::ReportError(const char* format, ...) { 1210 void ClassFinalizer::ReportError(const char* format, ...) {
1221 va_list args; 1211 va_list args;
1222 va_start(args, format); 1212 va_start(args, format);
1223 const Error& error = Error::Handle( 1213 const Error& error = Error::Handle(
1224 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); 1214 Parser::FormatError(Script::Handle(), -1, "Error", format, args));
1225 va_end(args); 1215 va_end(args);
1226 ReportError(error); 1216 ReportError(error);
1227 } 1217 }
1228 1218
1229 } // namespace dart 1219 } // namespace dart
OLDNEW
« no previous file with comments | « vm/class_finalizer.h ('k') | vm/class_finalizer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698