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

Side by Side Diff: runtime/vm/class_finalizer.cc

Issue 10871005: Make ClassFinalizer indifferent on whether we are generating a snapshot or not. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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
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 #include "vm/symbols.h" 13 #include "vm/symbols.h"
14 14
15 namespace dart { 15 namespace dart {
16 16
17 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); 17 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes.");
18 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); 18 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization.");
19 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); 19 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization.");
20 DEFINE_FLAG(bool, verify_implements, false,
21 "Verify that all classes implement their interface.");
22 DECLARE_FLAG(bool, enable_type_checks); 20 DECLARE_FLAG(bool, enable_type_checks);
23 21
24 22
25 bool ClassFinalizer::AllClassesFinalized() { 23 bool ClassFinalizer::AllClassesFinalized() {
26 ObjectStore* object_store = Isolate::Current()->object_store(); 24 ObjectStore* object_store = Isolate::Current()->object_store();
27 const GrowableObjectArray& classes = 25 const GrowableObjectArray& classes =
28 GrowableObjectArray::Handle(object_store->pending_classes()); 26 GrowableObjectArray::Handle(object_store->pending_classes());
29 return classes.Length() == 0; 27 return classes.Length() == 0;
30 } 28 }
31 29
32 30
31 bool ClassFinalizer::FinalizeAllClasses() {
32 ClassFinalizer class_finalizer(kNotGeneratingSnapshot);
33 return class_finalizer.FinalizePendingClasses();
34 }
35
36
33 // Class finalization occurs: 37 // Class finalization occurs:
34 // a) when bootstrap process completes (VerifyBootstrapClasses). 38 // a) when bootstrap process completes (VerifyBootstrapClasses).
35 // b) after the user classes are loaded (dart_api). 39 // b) after the user classes are loaded (dart_api).
36 bool ClassFinalizer::FinalizePendingClasses(bool generating_snapshot) { 40 bool ClassFinalizer::FinalizePendingClasses() const {
37 bool retval = true; 41 bool retval = true;
38 Isolate* isolate = Isolate::Current(); 42 Isolate* isolate = Isolate::Current();
39 ASSERT(isolate != NULL); 43 ASSERT(isolate != NULL);
40 ObjectStore* object_store = isolate->object_store(); 44 ObjectStore* object_store = isolate->object_store();
41 const Error& error = Error::Handle(object_store->sticky_error()); 45 const Error& error = Error::Handle(object_store->sticky_error());
42 if (!error.IsNull()) { 46 if (!error.IsNull()) {
43 return false; 47 return false;
44 } 48 }
45 LongJump* base = isolate->long_jump_base(); 49 LongJump* base = isolate->long_jump_base();
46 LongJump jump; 50 LongJump jump;
(...skipping 10 matching lines...) Expand all
57 OS::Print("Resolving super and default: %s\n", cls.ToCString()); 61 OS::Print("Resolving super and default: %s\n", cls.ToCString());
58 } 62 }
59 ResolveSuperType(cls); 63 ResolveSuperType(cls);
60 if (cls.is_interface()) { 64 if (cls.is_interface()) {
61 ResolveFactoryClass(cls); 65 ResolveFactoryClass(cls);
62 } 66 }
63 } 67 }
64 // Finalize all classes. 68 // Finalize all classes.
65 for (intptr_t i = 0; i < class_array.Length(); i++) { 69 for (intptr_t i = 0; i < class_array.Length(); i++) {
66 cls ^= class_array.At(i); 70 cls ^= class_array.At(i);
67 FinalizeClass(cls, generating_snapshot); 71 FinalizeClass(cls);
68 } 72 }
69 if (FLAG_print_classes) { 73 if (FLAG_print_classes) {
70 for (intptr_t i = 0; i < class_array.Length(); i++) { 74 for (intptr_t i = 0; i < class_array.Length(); i++) {
71 cls ^= class_array.At(i); 75 cls ^= class_array.At(i);
72 PrintClassInformation(cls); 76 PrintClassInformation(cls);
73 } 77 }
74 } 78 }
75 if (FLAG_verify_implements) {
76 for (intptr_t i = 0; i < class_array.Length(); i++) {
77 cls ^= class_array.At(i);
78 if (!cls.is_interface()) {
79 VerifyClassImplements(cls);
80 }
81 }
82 }
83 // Clear pending classes array. 79 // Clear pending classes array.
84 class_array = GrowableObjectArray::New(); 80 class_array = GrowableObjectArray::New();
85 object_store->set_pending_classes(class_array); 81 object_store->set_pending_classes(class_array);
86 } else { 82 } else {
87 retval = false; 83 retval = false;
88 } 84 }
89 isolate->set_long_jump_base(base); 85 isolate->set_long_jump_base(base);
90 return retval; 86 return retval;
91 } 87 }
92 88
93 89
94 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. 90 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur.
95 // No cycles are allowed. 91 // No cycles are allowed.
96 void ClassFinalizer::CollectInterfaces(const Class& cls, 92 void ClassFinalizer::CollectInterfaces(const Class& cls,
97 const GrowableObjectArray& collected) { 93 const GrowableObjectArray& collected) {
98 const Array& interface_array = Array::ZoneHandle(cls.interfaces()); 94 const Array& interface_array = Array::ZoneHandle(cls.interfaces());
99 AbstractType& interface = AbstractType::Handle(); 95 AbstractType& interface = AbstractType::Handle();
100 Class& interface_class = Class::Handle(); 96 Class& interface_class = Class::Handle();
101 for (intptr_t i = 0; i < interface_array.Length(); i++) { 97 for (intptr_t i = 0; i < interface_array.Length(); i++) {
102 interface ^= interface_array.At(i); 98 interface ^= interface_array.At(i);
103 interface_class = interface.type_class(); 99 interface_class = interface.type_class();
104 collected.Add(interface_class); 100 collected.Add(interface_class);
105 CollectInterfaces(interface_class, collected); 101 CollectInterfaces(interface_class, collected);
106 } 102 }
107 } 103 }
108 104
109 105
110 #if defined (DEBUG)
111 // Collect all interfaces of the class 'cls' and check that every function
112 // defined in each interface can be found in the class.
113 // No need to check instance fields since they have been turned into
114 // getters/setters.
115 void ClassFinalizer::VerifyClassImplements(const Class& cls) {
116 ASSERT(!cls.is_interface());
117 const GrowableObjectArray& interfaces =
118 GrowableObjectArray::Handle(GrowableObjectArray::New());
119 CollectInterfaces(cls, interfaces);
120 const String& class_name = String::Handle(cls.Name());
121 Class& interface_class = Class::Handle();
122 String& interface_name = String::Handle();
123 Array& interface_functions = Array::Handle();
124 for (int i = 0; i < interfaces.Length(); i++) {
125 interface_class ^= interfaces.At(i);
126 interface_name = interface_class.Name();
127 interface_functions = interface_class.functions();
128 for (intptr_t f = 0; f < interface_functions.Length(); f++) {
129 Function& interface_function = Function::Handle();
130 interface_function ^= interface_functions.At(f);
131 const String& function_name = String::Handle(interface_function.name());
132 // Check for constructor/factory.
133 if (function_name.StartsWith(interface_name)) {
134 // TODO(srdjan): convert 'InterfaceName.' to 'ClassName.' and check.
135 continue;
136 }
137 if (interface_function.kind() == RawFunction::kConstImplicitGetter) {
138 // This interface constants are not overridable.
139 continue;
140 }
141 // Lookup function in 'cls' and all its super classes.
142 Class& test_class = Class::Handle(cls.raw());
143 Function& class_function =
144 Function::Handle(test_class.LookupDynamicFunction(function_name));
145 while (class_function.IsNull()) {
146 test_class = test_class.SuperClass();
147 if (test_class.IsNull()) break;
148 class_function = test_class.LookupDynamicFunction(function_name);
149 }
150 if (class_function.IsNull()) {
151 OS::PrintErr("%s implements '%s' missing: '%s'\n",
152 class_name.ToCString(),
153 interface_name.ToCString(),
154 function_name.ToCString());
155 } else {
156 Error& malformed_error = Error::Handle();
157 if (!class_function.IsSubtypeOf(TypeArguments::Handle(),
158 interface_function,
159 TypeArguments::Handle(),
160 &malformed_error)) {
161 if (!malformed_error.IsNull()) {
162 OS::PrintErr("%s\n", malformed_error.ToErrorCString());
163 }
164 OS::PrintErr("The type of instance method '%s' in class '%s' is not "
165 "a subtype of the type of '%s' in interface '%s'\n",
166 function_name.ToCString(),
167 class_name.ToCString(),
168 function_name.ToCString(),
169 interface_name.ToCString());
170 }
171 }
172 }
173 }
174 }
175 #else
176
177 void ClassFinalizer::VerifyClassImplements(const Class& cls) {}
178
179 #endif
180
181
182 void ClassFinalizer::VerifyBootstrapClasses() { 106 void ClassFinalizer::VerifyBootstrapClasses() {
183 if (FLAG_trace_class_finalization) { 107 if (FLAG_trace_class_finalization) {
184 OS::Print("VerifyBootstrapClasses START.\n"); 108 OS::Print("VerifyBootstrapClasses START.\n");
185 } 109 }
186 ObjectStore* object_store = Isolate::Current()->object_store(); 110 ObjectStore* object_store = Isolate::Current()->object_store();
187 111
188 Class& cls = Class::Handle(); 112 Class& cls = Class::Handle();
189 #if defined(DEBUG) 113 #if defined(DEBUG)
190 // Basic checking. 114 // Basic checking.
191 cls = object_store->object_class(); 115 cls = object_store->object_class();
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 for (intptr_t i = 0; i < class_array.Length(); i++) { 190 for (intptr_t i = 0; i < class_array.Length(); i++) {
267 // TODO(iposva): Add real checks. 191 // TODO(iposva): Add real checks.
268 cls ^= class_array.At(i); 192 cls ^= class_array.At(i);
269 if (cls.is_finalized() || cls.is_prefinalized()) { 193 if (cls.is_finalized() || cls.is_prefinalized()) {
270 // Pre-finalized bootstrap classes must not define any fields. 194 // Pre-finalized bootstrap classes must not define any fields.
271 ASSERT(!cls.HasInstanceFields()); 195 ASSERT(!cls.HasInstanceFields());
272 } 196 }
273 } 197 }
274 198
275 // Finalize classes that aren't pre-finalized by Object::Init(). 199 // Finalize classes that aren't pre-finalized by Object::Init().
276 if (!FinalizePendingClasses()) { 200 ClassFinalizer class_finalizer(kGeneratingSnapshot);
201 if (!class_finalizer.FinalizePendingClasses()) {
277 // TODO(srdjan): Exit like a real VM instead. 202 // TODO(srdjan): Exit like a real VM instead.
278 const Error& err = Error::Handle(object_store->sticky_error()); 203 const Error& err = Error::Handle(object_store->sticky_error());
279 OS::PrintErr("Could not verify bootstrap classes : %s\n", 204 OS::PrintErr("Could not verify bootstrap classes : %s\n",
280 err.ToErrorCString()); 205 err.ToErrorCString());
281 OS::Exit(255); 206 OS::Exit(255);
282 } 207 }
283 if (FLAG_trace_class_finalization) { 208 if (FLAG_trace_class_finalization) {
284 OS::Print("VerifyBootstrapClasses END.\n"); 209 OS::Print("VerifyBootstrapClasses END.\n");
285 } 210 }
286 Isolate::Current()->heap()->Verify(); 211 Isolate::Current()->heap()->Verify();
(...skipping 14 matching lines...) Expand all
301 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); 226 LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
302 lib_prefix = unresolved_class.library_prefix(); 227 lib_prefix = unresolved_class.library_prefix();
303 ASSERT(!lib_prefix.IsNull()); 228 ASSERT(!lib_prefix.IsNull());
304 resolved_class = lib_prefix.LookupLocalClass(class_name); 229 resolved_class = lib_prefix.LookupLocalClass(class_name);
305 } 230 }
306 return resolved_class.raw(); 231 return resolved_class.raw();
307 } 232 }
308 233
309 234
310 // Resolve unresolved supertype (String -> Class). 235 // Resolve unresolved supertype (String -> Class).
311 void ClassFinalizer::ResolveSuperType(const Class& cls) { 236 void ClassFinalizer::ResolveSuperType(const Class& cls) const {
312 if (cls.is_finalized()) { 237 if (cls.is_finalized()) {
313 return; 238 return;
314 } 239 }
315 Type& super_type = Type::Handle(cls.super_type()); 240 Type& super_type = Type::Handle(cls.super_type());
316 if (super_type.IsNull()) { 241 if (super_type.IsNull()) {
317 return; 242 return;
318 } 243 }
319 // Resolve failures lead to a longjmp. 244 // Resolve failures lead to a longjmp.
320 ResolveType(cls, super_type, kCanonicalizeWellFormed); 245 ResolveType(cls, super_type, kCanonicalizeWellFormed);
321 const Class& super_class = Class::Handle(super_type.type_class()); 246 const Class& super_class = Class::Handle(super_type.type_class());
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 "mismatch in number or names of type parameters between " 385 "mismatch in number or names of type parameters between "
461 "interface '%s' and default factory class '%s'", 386 "interface '%s' and default factory class '%s'",
462 interface_name.ToCString(), 387 interface_name.ToCString(),
463 factory_name.ToCString()); 388 factory_name.ToCString());
464 } 389 }
465 } 390 }
466 391
467 392
468 void ClassFinalizer::ResolveType(const Class& cls, 393 void ClassFinalizer::ResolveType(const Class& cls,
469 const AbstractType& type, 394 const AbstractType& type,
470 FinalizationKind finalization) { 395 FinalizationKind finalization) const {
471 if (type.IsResolved() || type.IsFinalized()) { 396 if (type.IsResolved() || type.IsFinalized()) {
472 return; 397 return;
473 } 398 }
474 if (FLAG_trace_type_finalization) { 399 if (FLAG_trace_type_finalization) {
475 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); 400 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString());
476 } 401 }
477 402
478 // Resolve the type class. 403 // Resolve the type class.
479 if (!type.HasResolvedTypeClass()) { 404 if (!type.HasResolvedTypeClass()) {
480 // Type parameters are always resolved in the parser in the correct 405 // Type parameters are always resolved in the parser in the correct
(...skipping 30 matching lines...) Expand all
511 intptr_t num_arguments = arguments.Length(); 436 intptr_t num_arguments = arguments.Length();
512 AbstractType& type_argument = AbstractType::Handle(); 437 AbstractType& type_argument = AbstractType::Handle();
513 for (intptr_t i = 0; i < num_arguments; i++) { 438 for (intptr_t i = 0; i < num_arguments; i++) {
514 type_argument = arguments.TypeAt(i); 439 type_argument = arguments.TypeAt(i);
515 ResolveType(cls, type_argument, finalization); 440 ResolveType(cls, type_argument, finalization);
516 } 441 }
517 } 442 }
518 } 443 }
519 444
520 445
521 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) { 446 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) const {
522 const TypeArguments& type_parameters = 447 const TypeArguments& type_parameters =
523 TypeArguments::Handle(cls.type_parameters()); 448 TypeArguments::Handle(cls.type_parameters());
524 if (!type_parameters.IsNull()) { 449 if (!type_parameters.IsNull()) {
525 TypeParameter& type_parameter = TypeParameter::Handle(); 450 TypeParameter& type_parameter = TypeParameter::Handle();
526 const intptr_t num_types = type_parameters.Length(); 451 const intptr_t num_types = type_parameters.Length();
527 for (intptr_t i = 0; i < num_types; i++) { 452 for (intptr_t i = 0; i < num_types; i++) {
528 type_parameter ^= type_parameters.TypeAt(i); 453 type_parameter ^= type_parameters.TypeAt(i);
529 type_parameter ^= FinalizeType(cls, 454 type_parameter ^= FinalizeType(cls,
530 type_parameter, 455 type_parameter,
531 kCanonicalizeWellFormed); 456 kCanonicalizeWellFormed);
(...skipping 13 matching lines...) Expand all
545 // Example: 470 // Example:
546 // Declared: class C<K, V> extends B<V> { ... } 471 // Declared: class C<K, V> extends B<V> { ... }
547 // class B<T> extends A<int> { ... } 472 // class B<T> extends A<int> { ... }
548 // Input: C<String, double> expressed as 473 // Input: C<String, double> expressed as
549 // cls = C, arguments = [null, null, String, double], 474 // cls = C, arguments = [null, null, String, double],
550 // i.e. cls_args = [String, double], offset = 2, length = 2. 475 // i.e. cls_args = [String, double], offset = 2, length = 2.
551 // Output: arguments = [int, double, String, double] 476 // Output: arguments = [int, double, String, double]
552 void ClassFinalizer::FinalizeTypeArguments( 477 void ClassFinalizer::FinalizeTypeArguments(
553 const Class& cls, 478 const Class& cls,
554 const AbstractTypeArguments& arguments, 479 const AbstractTypeArguments& arguments,
555 FinalizationKind finalization) { 480 FinalizationKind finalization) const {
556 ASSERT(arguments.Length() >= cls.NumTypeArguments()); 481 ASSERT(arguments.Length() >= cls.NumTypeArguments());
557 if (!cls.is_finalized()) { 482 if (!cls.is_finalized()) {
558 GrowableArray<intptr_t> visited_interfaces; 483 GrowableArray<intptr_t> visited_interfaces;
559 ResolveInterfaces(cls, &visited_interfaces); 484 ResolveInterfaces(cls, &visited_interfaces);
560 FinalizeTypeParameters(cls); 485 FinalizeTypeParameters(cls);
561 } 486 }
562 Type& super_type = Type::Handle(cls.super_type()); 487 Type& super_type = Type::Handle(cls.super_type());
563 if (!super_type.IsNull()) { 488 if (!super_type.IsNull()) {
564 const Class& super_class = Class::Handle(super_type.type_class()); 489 const Class& super_class = Class::Handle(super_type.type_class());
565 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle(); 490 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 super_type_arg = super_type_arg.Canonicalize(); 524 super_type_arg = super_type_arg.Canonicalize();
600 } 525 }
601 } 526 }
602 arguments.SetTypeAt(super_offset + i, super_type_arg); 527 arguments.SetTypeAt(super_offset + i, super_type_arg);
603 } 528 }
604 FinalizeTypeArguments(super_class, arguments, finalization); 529 FinalizeTypeArguments(super_class, arguments, finalization);
605 } 530 }
606 } 531 }
607 532
608 533
609 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, 534 RawAbstractType* ClassFinalizer::FinalizeType(
610 const AbstractType& type, 535 const Class& cls,
611 FinalizationKind finalization) { 536 const AbstractType& type,
537 FinalizationKind finalization) const {
612 if (type.IsFinalized()) { 538 if (type.IsFinalized()) {
613 return type.raw(); 539 return type.raw();
614 } 540 }
615 ASSERT(type.IsResolved()); 541 ASSERT(type.IsResolved());
616 ASSERT(finalization >= kFinalize); 542 ASSERT(finalization >= kFinalize);
617 543
618 if (FLAG_trace_type_finalization) { 544 if (FLAG_trace_type_finalization) {
619 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); 545 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString());
620 } 546 }
621 547
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 AbstractTypeArguments::Handle(parameterized_type.arguments()); 597 AbstractTypeArguments::Handle(parameterized_type.arguments());
672 if (!arguments.IsNull()) { 598 if (!arguments.IsNull()) {
673 intptr_t num_arguments = arguments.Length(); 599 intptr_t num_arguments = arguments.Length();
674 AbstractType& type_argument = AbstractType::Handle(); 600 AbstractType& type_argument = AbstractType::Handle();
675 for (intptr_t i = 0; i < num_arguments; i++) { 601 for (intptr_t i = 0; i < num_arguments; i++) {
676 type_argument = arguments.TypeAt(i); 602 type_argument = arguments.TypeAt(i);
677 type_argument = FinalizeType(cls, type_argument, finalization); 603 type_argument = FinalizeType(cls, type_argument, finalization);
678 if (type_argument.IsMalformed()) { 604 if (type_argument.IsMalformed()) {
679 // In production mode, malformed type arguments are mapped to Dynamic. 605 // In production mode, malformed type arguments are mapped to Dynamic.
680 // In checked mode, a type with malformed type arguments is malformed. 606 // In checked mode, a type with malformed type arguments is malformed.
681 if (FLAG_enable_type_checks) { 607 if (FLAG_enable_type_checks || generating_snapshot_) {
682 const Error& error = Error::Handle(type_argument.malformed_error()); 608 const Error& error = Error::Handle(type_argument.malformed_error());
683 const String& type_name = 609 const String& type_name =
684 String::Handle(parameterized_type.UserVisibleName()); 610 String::Handle(parameterized_type.UserVisibleName());
685 FinalizeMalformedType(error, cls, parameterized_type, finalization, 611 FinalizeMalformedType(error, cls, parameterized_type, finalization,
686 "type '%s' has malformed type argument", 612 "type '%s' has malformed type argument",
687 type_name.ToCString()); 613 type_name.ToCString());
688 return parameterized_type.raw(); 614 return parameterized_type.raw();
689 } else { 615 } else {
690 type_argument = Type::DynamicType(); 616 type_argument = Type::DynamicType();
691 } 617 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 if (type_class.IsCanonicalSignatureClass()) { 732 if (type_class.IsCanonicalSignatureClass()) {
807 ASSERT(type_class.is_finalized()); 733 ASSERT(type_class.is_finalized());
808 // Resolve and finalize the result and parameter types of the signature 734 // Resolve and finalize the result and parameter types of the signature
809 // function of this signature class. 735 // function of this signature class.
810 ASSERT(type_class.SignatureType() == type.raw()); 736 ASSERT(type_class.SignatureType() == type.raw());
811 ResolveAndFinalizeSignature( 737 ResolveAndFinalizeSignature(
812 type_class, Function::Handle(type_class.signature_function())); 738 type_class, Function::Handle(type_class.signature_function()));
813 } else { 739 } else {
814 // This type is a function type alias. Its class may need to be finalized 740 // This type is a function type alias. Its class may need to be finalized
815 // and checked for illegal self reference. 741 // and checked for illegal self reference.
816 FinalizeClass(type_class, false); 742 FinalizeClass(type_class);
817 // Finalizing the signature function here (as in the canonical case above) 743 // Finalizing the signature function here (as in the canonical case above)
818 // would not mark the canonical signature type as finalized. 744 // would not mark the canonical signature type as finalized.
819 const Type& signature_type = Type::Handle(type_class.SignatureType()); 745 const Type& signature_type = Type::Handle(type_class.SignatureType());
820 FinalizeType(cls, signature_type, finalization); 746 FinalizeType(cls, signature_type, finalization);
821 } 747 }
822 } 748 }
823 749
824 if (finalization >= kCanonicalize) { 750 if (finalization >= kCanonicalize) {
825 return parameterized_type.Canonicalize(); 751 return parameterized_type.Canonicalize();
826 } else { 752 } else {
827 return parameterized_type.raw(); 753 return parameterized_type.raw();
828 } 754 }
829 } 755 }
830 756
831 757
832 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, 758 void ClassFinalizer::ResolveAndFinalizeSignature(
833 const Function& function) { 759 const Class& cls,
760 const Function& function) const {
834 // Resolve result type. 761 // Resolve result type.
835 AbstractType& type = AbstractType::Handle(function.result_type()); 762 AbstractType& type = AbstractType::Handle(function.result_type());
836 // In case of a factory, the parser sets the factory result type to a type 763 // In case of a factory, the parser sets the factory result type to a type
837 // with an unresolved class whose name matches the factory name. 764 // with an unresolved class whose name matches the factory name.
838 // It is not a compile time error if this name does not resolve to a class or 765 // It is not a compile time error if this name does not resolve to a class or
839 // interface. 766 // interface.
840 ResolveType(cls, type, kCanonicalize); 767 ResolveType(cls, type, kCanonicalize);
841 type = FinalizeType(cls, type, kCanonicalize); 768 type = FinalizeType(cls, type, kCanonicalize);
842 // In production mode, a malformed result type is mapped to Dynamic. 769 // In production mode, a malformed result type is mapped to Dynamic.
843 if (!FLAG_enable_type_checks && type.IsMalformed()) { 770 if (!FLAG_enable_type_checks && type.IsMalformed()) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 if (!function.IsNull()) { 819 if (!function.IsNull()) {
893 return super_class.raw(); 820 return super_class.raw();
894 } 821 }
895 super_class = super_class.SuperClass(); 822 super_class = super_class.SuperClass();
896 } 823 }
897 return Class::null(); 824 return Class::null();
898 } 825 }
899 826
900 827
901 // Resolve and finalize the upper bounds of the type parameters of class cls. 828 // Resolve and finalize the upper bounds of the type parameters of class cls.
902 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) { 829 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) const {
903 const intptr_t num_type_params = cls.NumTypeParameters(); 830 const intptr_t num_type_params = cls.NumTypeParameters();
904 TypeParameter& type_param = TypeParameter::Handle(); 831 TypeParameter& type_param = TypeParameter::Handle();
905 AbstractType& bound = AbstractType::Handle(); 832 AbstractType& bound = AbstractType::Handle();
906 const AbstractTypeArguments& type_params = 833 const AbstractTypeArguments& type_params =
907 AbstractTypeArguments::Handle(cls.type_parameters()); 834 AbstractTypeArguments::Handle(cls.type_parameters());
908 ASSERT((type_params.IsNull() && (num_type_params == 0)) || 835 ASSERT((type_params.IsNull() && (num_type_params == 0)) ||
909 (type_params.Length() == num_type_params)); 836 (type_params.Length() == num_type_params));
910 for (intptr_t i = 0; i < num_type_params; i++) { 837 for (intptr_t i = 0; i < num_type_params; i++) {
911 type_param ^= type_params.TypeAt(i); 838 type_param ^= type_params.TypeAt(i);
912 bound = type_param.bound(); 839 bound = type_param.bound();
913 if (bound.IsFinalized()) { 840 if (bound.IsFinalized()) {
914 continue; 841 continue;
915 } 842 }
916 ResolveType(cls, bound, kCanonicalize); 843 ResolveType(cls, bound, kCanonicalize);
917 bound = FinalizeType(cls, bound, kCanonicalize); 844 bound = FinalizeType(cls, bound, kCanonicalize);
918 type_param.set_bound(bound); 845 type_param.set_bound(bound);
919 } 846 }
920 } 847 }
921 848
922 849
923 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { 850 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) const {
924 // Note that getters and setters are explicitly listed as such in the list of 851 // Note that getters and setters are explicitly listed as such in the list of
925 // functions of a class, so we do not need to consider fields as implicitly 852 // functions of a class, so we do not need to consider fields as implicitly
926 // generating getters and setters. 853 // generating getters and setters.
927 // The only compile errors we report are therefore: 854 // The only compile errors we report are therefore:
928 // - a getter having the same name as a method (but not a getter) in a super 855 // - a getter having the same name as a method (but not a getter) in a super
929 // class or in a subclass. 856 // class or in a subclass.
930 // - a setter having the same name as a method (but not a setter) in a super 857 // - a setter having the same name as a method (but not a setter) in a super
931 // class or in a subclass. 858 // class or in a subclass.
932 // - a static field, instance field, or static method (but not an instance 859 // - a static field, instance field, or static method (but not an instance
933 // method) having the same name as an instance member in a super class. 860 // method) having the same name as an instance member in a super class.
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 function_name.ToCString(), 999 function_name.ToCString(),
1073 class_name.ToCString(), 1000 class_name.ToCString(),
1074 function_name.ToCString(), 1001 function_name.ToCString(),
1075 super_class_name.ToCString()); 1002 super_class_name.ToCString());
1076 } 1003 }
1077 } 1004 }
1078 } 1005 }
1079 } 1006 }
1080 1007
1081 1008
1082 void ClassFinalizer::FinalizeClass(const Class& cls, bool generating_snapshot) { 1009 void ClassFinalizer::FinalizeClass(const Class& cls) const {
1083 if (cls.is_finalized()) { 1010 if (cls.is_finalized()) {
1084 return; 1011 return;
1085 } 1012 }
1086 if (FLAG_trace_class_finalization) { 1013 if (FLAG_trace_class_finalization) {
1087 OS::Print("Finalize %s\n", cls.ToCString()); 1014 OS::Print("Finalize %s\n", cls.ToCString());
1088 } 1015 }
1089 if (!IsSuperCycleFree(cls)) { 1016 if (!IsSuperCycleFree(cls)) {
1090 const String& name = String::Handle(cls.Name()); 1017 const String& name = String::Handle(cls.Name());
1091 const Script& script = Script::Handle(cls.script()); 1018 const Script& script = Script::Handle(cls.script());
1092 ReportError(script, cls.token_pos(), 1019 ReportError(script, cls.token_pos(),
1093 "class '%s' has a cycle in its superclass relationship", 1020 "class '%s' has a cycle in its superclass relationship",
1094 name.ToCString()); 1021 name.ToCString());
1095 } 1022 }
1096 GrowableArray<intptr_t> visited_interfaces; 1023 GrowableArray<intptr_t> visited_interfaces;
1097 ResolveInterfaces(cls, &visited_interfaces); 1024 ResolveInterfaces(cls, &visited_interfaces);
1098 // Finalize super class. 1025 // Finalize super class.
1099 const Class& super_class = Class::Handle(cls.SuperClass()); 1026 const Class& super_class = Class::Handle(cls.SuperClass());
1100 if (!super_class.IsNull()) { 1027 if (!super_class.IsNull()) {
1101 FinalizeClass(super_class, generating_snapshot); 1028 FinalizeClass(super_class);
1102 } 1029 }
1103 // Finalize type parameters before finalizing the super type. 1030 // Finalize type parameters before finalizing the super type.
1104 FinalizeTypeParameters(cls); 1031 FinalizeTypeParameters(cls);
1105 // Finalize super type. 1032 // Finalize super type.
1106 Type& super_type = Type::Handle(cls.super_type()); 1033 Type& super_type = Type::Handle(cls.super_type());
1107 if (!super_type.IsNull()) { 1034 if (!super_type.IsNull()) {
1108 super_type ^= FinalizeType(cls, super_type, kCanonicalizeWellFormed); 1035 super_type ^= FinalizeType(cls, super_type, kCanonicalizeWellFormed);
1109 cls.set_super_type(super_type); 1036 cls.set_super_type(super_type);
1110 } 1037 }
1111 // Signature classes are finalized upon creation, except function type 1038 // Signature classes are finalized upon creation, except function type
(...skipping 13 matching lines...) Expand all
1125 // Signature classes extend Object. No need to add this class to the direct 1052 // Signature classes extend Object. No need to add this class to the direct
1126 // subclasses of Object. 1053 // subclasses of Object.
1127 ASSERT(super_type.IsNull() || super_type.IsObjectType()); 1054 ASSERT(super_type.IsNull() || super_type.IsObjectType());
1128 return; 1055 return;
1129 } 1056 }
1130 // Finalize factory class, if any. 1057 // Finalize factory class, if any.
1131 if (cls.is_interface()) { 1058 if (cls.is_interface()) {
1132 if (cls.HasFactoryClass()) { 1059 if (cls.HasFactoryClass()) {
1133 const Class& factory_class = Class::Handle(cls.FactoryClass()); 1060 const Class& factory_class = Class::Handle(cls.FactoryClass());
1134 if (!factory_class.is_finalized()) { 1061 if (!factory_class.is_finalized()) {
1135 FinalizeClass(factory_class, generating_snapshot); 1062 FinalizeClass(factory_class);
1136 // Finalizing the factory class may indirectly finalize this interface. 1063 // Finalizing the factory class may indirectly finalize this interface.
1137 if (cls.is_finalized()) { 1064 if (cls.is_finalized()) {
1138 return; 1065 return;
1139 } 1066 }
1140 } 1067 }
1141 } 1068 }
1142 } 1069 }
1143 // Finalize interface types (but not necessarily interface classes). 1070 // Finalize interface types (but not necessarily interface classes).
1144 Array& interface_types = Array::Handle(cls.interfaces()); 1071 Array& interface_types = Array::Handle(cls.interfaces());
1145 AbstractType& interface_type = AbstractType::Handle(); 1072 AbstractType& interface_type = AbstractType::Handle();
1146 for (intptr_t i = 0; i < interface_types.Length(); i++) { 1073 for (intptr_t i = 0; i < interface_types.Length(); i++) {
1147 interface_type ^= interface_types.At(i); 1074 interface_type ^= interface_types.At(i);
1148 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); 1075 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed);
1149 interface_types.SetAt(i, interface_type); 1076 interface_types.SetAt(i, interface_type);
1150 } 1077 }
1151 // Mark as finalized before resolving type parameter upper bounds and member 1078 // Mark as finalized before resolving type parameter upper bounds and member
1152 // types in order to break cycles. 1079 // types in order to break cycles.
1153 cls.Finalize(); 1080 cls.Finalize();
1154 ResolveAndFinalizeUpperBounds(cls); 1081 ResolveAndFinalizeUpperBounds(cls);
1155 ResolveAndFinalizeMemberTypes(cls); 1082 ResolveAndFinalizeMemberTypes(cls);
1156 // Run additional checks after all types are finalized. 1083 // Run additional checks after all types are finalized.
1157 if (cls.is_const()) { 1084 if (cls.is_const()) {
1158 CheckForLegalConstClass(cls); 1085 CheckForLegalConstClass(cls);
1159 } 1086 }
1160 // Check to ensure we don't have classes with native fields in libraries 1087 // Check to ensure we don't have classes with native fields in libraries
1161 // which do not have a native resolver. 1088 // which do not have a native resolver.
1162 if (!generating_snapshot && cls.num_native_fields() != 0) { 1089 if (!generating_snapshot_ && cls.num_native_fields() != 0) {
1163 const Library& lib = Library::Handle(cls.library()); 1090 const Library& lib = Library::Handle(cls.library());
1164 if (lib.native_entry_resolver() == NULL) { 1091 if (lib.native_entry_resolver() == NULL) {
1165 const String& cls_name = String::Handle(cls.Name()); 1092 const String& cls_name = String::Handle(cls.Name());
1166 const String& lib_name = String::Handle(lib.url()); 1093 const String& lib_name = String::Handle(lib.url());
1167 const Script& script = Script::Handle(cls.script()); 1094 const Script& script = Script::Handle(cls.script());
1168 ReportError(script, cls.token_pos(), 1095 ReportError(script, cls.token_pos(),
1169 "class '%s' is trying to extend a native fields class, " 1096 "class '%s' is trying to extend a native fields class, "
1170 "but library '%s' has no native resolvers", 1097 "but library '%s' has no native resolvers",
1171 cls_name.ToCString(), lib_name.ToCString()); 1098 cls_name.ToCString(), lib_name.ToCString());
1172 } 1099 }
(...skipping 24 matching lines...) Expand all
1197 test2 = test2.SuperClass(); 1124 test2 = test2.SuperClass();
1198 } 1125 }
1199 } 1126 }
1200 // No cycles. 1127 // No cycles.
1201 return true; 1128 return true;
1202 } 1129 }
1203 1130
1204 1131
1205 // Returns false if the function type alias illegally refers to itself. 1132 // Returns false if the function type alias illegally refers to itself.
1206 bool ClassFinalizer::IsAliasCycleFree(const Class& cls, 1133 bool ClassFinalizer::IsAliasCycleFree(const Class& cls,
1207 GrowableArray<intptr_t>* visited) { 1134 GrowableArray<intptr_t>* visited) const {
1208 ASSERT(cls.IsSignatureClass()); 1135 ASSERT(cls.IsSignatureClass());
1209 ASSERT(!cls.IsCanonicalSignatureClass()); 1136 ASSERT(!cls.IsCanonicalSignatureClass());
1210 ASSERT(!cls.is_finalized()); 1137 ASSERT(!cls.is_finalized());
1211 ASSERT(visited != NULL); 1138 ASSERT(visited != NULL);
1212 const intptr_t cls_index = cls.id(); 1139 const intptr_t cls_index = cls.id();
1213 for (int i = 0; i < visited->length(); i++) { 1140 for (int i = 0; i < visited->length(); i++) {
1214 if ((*visited)[i] == cls_index) { 1141 if ((*visited)[i] == cls_index) {
1215 // We have already visited alias 'cls'. We found a cycle. 1142 // We have already visited alias 'cls'. We found a cycle.
1216 return false; 1143 return false;
1217 } 1144 }
(...skipping 29 matching lines...) Expand all
1247 return false; 1174 return false;
1248 } 1175 }
1249 } 1176 }
1250 } 1177 }
1251 } 1178 }
1252 visited->RemoveLast(); 1179 visited->RemoveLast();
1253 return true; 1180 return true;
1254 } 1181 }
1255 1182
1256 1183
1257 bool ClassFinalizer::AddInterfaceIfUnique(
1258 const GrowableObjectArray& interface_list,
1259 const AbstractType& interface,
1260 AbstractType* conflicting) {
1261 String& interface_class_name = String::Handle(interface.ClassName());
1262 String& existing_interface_class_name = String::Handle();
1263 String& interface_name = String::Handle();
1264 String& existing_interface_name = String::Handle();
1265 AbstractType& other_interface = AbstractType::Handle();
1266 for (intptr_t i = 0; i < interface_list.Length(); i++) {
1267 other_interface ^= interface_list.At(i);
1268 existing_interface_class_name = other_interface.ClassName();
1269 if (interface_class_name.Equals(existing_interface_class_name)) {
1270 // Same interface class name, now check names of type arguments.
1271 interface_name = interface.Name();
1272 existing_interface_name = other_interface.Name();
1273 // TODO(regis): Revisit depending on the outcome of issue 4905685.
1274 if (!interface_name.Equals(existing_interface_name)) {
1275 *conflicting = other_interface.raw();
1276 return false;
1277 } else {
1278 return true;
1279 }
1280 }
1281 }
1282 interface_list.Add(interface);
1283 return true;
1284 }
1285
1286
1287 // Walks the graph of explicitly declared interfaces of classes and 1184 // Walks the graph of explicitly declared interfaces of classes and
1288 // interfaces recursively. Resolves unresolved interfaces. 1185 // interfaces recursively. Resolves unresolved interfaces.
1289 // Returns false if there is an interface reference that cannot be 1186 // Returns false if there is an interface reference that cannot be
1290 // resolved, or if there is a cycle in the graph. We detect cycles by 1187 // resolved, or if there is a cycle in the graph. We detect cycles by
1291 // remembering interfaces we've visited in each path through the 1188 // remembering interfaces we've visited in each path through the
1292 // graph. If we visit an interface a second time on a given path, 1189 // graph. If we visit an interface a second time on a given path,
1293 // we found a loop. 1190 // we found a loop.
1294 void ClassFinalizer::ResolveInterfaces(const Class& cls, 1191 void ClassFinalizer::ResolveInterfaces(const Class& cls,
1295 GrowableArray<intptr_t>* visited) { 1192 GrowableArray<intptr_t>* visited) const {
1296 ASSERT(visited != NULL); 1193 ASSERT(visited != NULL);
1297 const intptr_t cls_index = cls.id(); 1194 const intptr_t cls_index = cls.id();
1298 for (int i = 0; i < visited->length(); i++) { 1195 for (int i = 0; i < visited->length(); i++) {
1299 if ((*visited)[i] == cls_index) { 1196 if ((*visited)[i] == cls_index) {
1300 // We have already visited interface class 'cls'. We found a cycle. 1197 // We have already visited interface class 'cls'. We found a cycle.
1301 const String& interface_name = String::Handle(cls.Name()); 1198 const String& interface_name = String::Handle(cls.Name());
1302 const Script& script = Script::Handle(cls.script()); 1199 const Script& script = Script::Handle(cls.script());
1303 ReportError(script, cls.token_pos(), 1200 ReportError(script, cls.token_pos(),
1304 "cyclic reference found for interface '%s'", 1201 "cyclic reference found for interface '%s'",
1305 interface_name.ToCString()); 1202 interface_name.ToCString());
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1441 field ^= fields_array.At(i); 1338 field ^= fields_array.At(i);
1442 OS::Print(" %s\n", field.ToCString()); 1339 OS::Print(" %s\n", field.ToCString());
1443 } 1340 }
1444 } 1341 }
1445 1342
1446 1343
1447 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, 1344 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error,
1448 const Class& cls, 1345 const Class& cls,
1449 const Type& type, 1346 const Type& type,
1450 FinalizationKind finalization, 1347 FinalizationKind finalization,
1451 const char* format, ...) { 1348 const char* format, ...) const {
1452 va_list args; 1349 va_list args;
1453 va_start(args, format); 1350 va_start(args, format);
1454 LanguageError& error = LanguageError::Handle(); 1351 LanguageError& error = LanguageError::Handle();
1455 if (FLAG_enable_type_checks || 1352 if (FLAG_enable_type_checks ||
1456 !type.HasResolvedTypeClass() || 1353 !type.HasResolvedTypeClass() ||
1457 (finalization == kCanonicalizeWellFormed)) { 1354 (finalization == kCanonicalizeWellFormed) ||
1355 generating_snapshot_) {
1458 const Script& script = Script::Handle(cls.script()); 1356 const Script& script = Script::Handle(cls.script());
1459 if (prev_error.IsNull()) { 1357 if (prev_error.IsNull()) {
1460 error ^= Parser::FormatError( 1358 error ^= Parser::FormatError(
1461 script, type.token_pos(), "Error", format, args); 1359 script, type.token_pos(), "Error", format, args);
1462 } else { 1360 } else {
1463 error ^= Parser::FormatErrorWithAppend( 1361 error ^= Parser::FormatErrorWithAppend(
1464 prev_error, script, type.token_pos(), "Error", format, args); 1362 prev_error, script, type.token_pos(), "Error", format, args);
1465 } 1363 }
1466 if (finalization == kCanonicalizeWellFormed) { 1364 if ((finalization == kCanonicalizeWellFormed) || generating_snapshot_) {
1467 ReportError(error); 1365 ReportError(error);
1468 } 1366 }
1469 } 1367 }
1470 if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) { 1368 if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) {
1471 // In check mode, always mark the type as malformed. 1369 // In check mode, always mark the type as malformed.
1472 // In production mode, mark the type as malformed only if its type class is 1370 // In production mode, mark the type as malformed only if its type class is
1473 // not resolved. 1371 // not resolved.
1474 type.set_malformed_error(error); 1372 type.set_malformed_error(error);
1475 } else { 1373 } else {
1476 // In production mode, do not mark the type with a resolved type class as 1374 // In production mode, do not mark the type with a resolved type class as
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1509 void ClassFinalizer::ReportError(const char* format, ...) { 1407 void ClassFinalizer::ReportError(const char* format, ...) {
1510 va_list args; 1408 va_list args;
1511 va_start(args, format); 1409 va_start(args, format);
1512 const Error& error = Error::Handle( 1410 const Error& error = Error::Handle(
1513 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); 1411 Parser::FormatError(Script::Handle(), -1, "Error", format, args));
1514 va_end(args); 1412 va_end(args);
1515 ReportError(error); 1413 ReportError(error);
1516 } 1414 }
1517 1415
1518 } // namespace dart 1416 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698