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

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

Issue 8506001: Finalize all classes (fix issue 364). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 9 years, 1 month 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) 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"
11 #include "vm/object_store.h" 11 #include "vm/object_store.h"
12 12
13 namespace dart { 13 namespace dart {
14 14
15 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); 15 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes.");
16 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); 16 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization.");
17 DEFINE_FLAG(bool, verify_implements, false, 17 DEFINE_FLAG(bool, verify_implements, false,
18 "Verify that all classes implement their interface."); 18 "Verify that all classes implement their interface.");
19 DECLARE_FLAG(bool, enable_type_checks); 19 DECLARE_FLAG(bool, enable_type_checks);
20 20
21 void ClassFinalizer::ExpectPendingClasses() {
srdjan 2011/11/09 21:22:43 Do you want to allow ExpectPendingClasses several
regis 2011/11/09 23:31:01 Good question! Currently, there may be several cal
22 if (AllClassesFinalized()) {
23 ObjectStore* object_store = Isolate::Current()->object_store();
24 object_store->set_pending_classes(Array::Handle(Array::Empty()));
25 ASSERT(!AllClassesFinalized());
26 }
27 }
28
29
21 void ClassFinalizer::AddPendingClasses( 30 void ClassFinalizer::AddPendingClasses(
22 const GrowableArray<const Class*>& classes) { 31 const GrowableArray<const Class*>& classes) {
32 // ExpectPendingClasses() must be called prior to calling AddPendingClasses().
33 if (AllClassesFinalized()) { // TODO(regis): DEBUG.
34 ASSERT(false);
35 }
srdjan 2011/11/09 21:22:43 Why the code above?
regis 2011/11/09 23:31:01 Left over debugging code. Removed.
36 ASSERT(!AllClassesFinalized());
23 if (!classes.is_empty()) { 37 if (!classes.is_empty()) {
24 ObjectStore* object_store = Isolate::Current()->object_store(); 38 ObjectStore* object_store = Isolate::Current()->object_store();
25 const Array& old_array = Array::Handle(object_store->pending_classes()); 39 const Array& old_array = Array::Handle(object_store->pending_classes());
26 const intptr_t old_length = old_array.Length(); 40 const intptr_t old_length = old_array.Length();
27 const int new_length = old_length + classes.length(); 41 const int new_length = old_length + classes.length();
28 const Array& new_array = Array::Handle(Array::Grow(old_array, new_length)); 42 const Array& new_array = Array::Handle(Array::Grow(old_array, new_length));
29 // Add new classes. 43 // Add new classes.
30 for (int i = 0; i < classes.length(); i++) { 44 for (int i = 0; i < classes.length(); i++) {
31 new_array.SetAt(i + old_length, *classes[i]); 45 new_array.SetAt(i + old_length, *classes[i]);
32 } 46 }
33 object_store->set_pending_classes(new_array); 47 object_store->set_pending_classes(new_array);
34 } 48 }
35 } 49 }
36 50
37 51
38 bool ClassFinalizer::AllClassesFinalized() { 52 bool ClassFinalizer::AllClassesFinalized() {
39 ObjectStore* object_store = Isolate::Current()->object_store(); 53 ObjectStore* object_store = Isolate::Current()->object_store();
40 const Array& classes = Array::Handle(object_store->pending_classes()); 54 const Array& classes = Array::Handle(object_store->pending_classes());
41 return classes.Length() == 0; 55 return classes.IsNull();
42 } 56 }
43 57
44 58
45 // Class finalization occurs: 59 // Class finalization occurs:
46 // a) when bootstrap process completes (VerifyBootstrapClasses). 60 // a) when bootstrap process completes (VerifyBootstrapClasses).
47 // b) after the user classes are loaded (dart_api). 61 // b) after the user classes are loaded (dart_api).
48 bool ClassFinalizer::FinalizePendingClasses() { 62 bool ClassFinalizer::FinalizePendingClasses() {
49 bool retval = true; 63 bool retval = true;
50 Isolate* isolate = Isolate::Current(); 64 Isolate* isolate = Isolate::Current();
51 ASSERT(isolate != NULL); 65 ASSERT(isolate != NULL);
52 ObjectStore* object_store = isolate->object_store(); 66 ObjectStore* object_store = isolate->object_store();
53 const String& error = String::Handle(object_store->sticky_error()); 67 const String& error = String::Handle(object_store->sticky_error());
54 if (!error.IsNull()) { 68 if (!error.IsNull()) {
55 return false; 69 return false;
56 } 70 }
57 LongJump* base = isolate->long_jump_base(); 71 LongJump* base = isolate->long_jump_base();
58 LongJump jump; 72 LongJump jump;
59 isolate->set_long_jump_base(&jump); 73 isolate->set_long_jump_base(&jump);
60 if (setjmp(*jump.Set()) == 0) { 74 if (setjmp(*jump.Set()) == 0) {
61 const Array& class_array = Array::Handle(object_store->pending_classes()); 75 const Array& class_array = Array::Handle(object_store->pending_classes());
62 ASSERT(!class_array.IsNull()); 76 const intptr_t num_pending_classes =
77 class_array.IsNull() ? 0 : class_array.Length();
63 Class& cls = Class::Handle(); 78 Class& cls = Class::Handle();
64 // First resolve all superclasses. 79 // First resolve all superclasses.
65 for (intptr_t i = 0; i < class_array.Length(); i++) { 80 for (intptr_t i = 0; i < num_pending_classes; i++) {
66 cls ^= class_array.At(i); 81 cls ^= class_array.At(i);
67 if (FLAG_trace_class_finalization) { 82 if (FLAG_trace_class_finalization) {
68 OS::Print("Resolving super and default: %s\n", cls.ToCString()); 83 OS::Print("Resolving super and default: %s\n", cls.ToCString());
69 } 84 }
70 ResolveSuperClass(cls); 85 ResolveSuperClass(cls);
71 if (cls.is_interface()) { 86 if (cls.is_interface()) {
72 ResolveDefaultClass(cls); 87 ResolveDefaultClass(cls);
73 } 88 }
74 } 89 }
75 // Finalize all classes. 90 // Finalize all classes.
76 for (intptr_t i = 0; i < class_array.Length(); i++) { 91 for (intptr_t i = 0; i < num_pending_classes; i++) {
77 cls ^= class_array.At(i); 92 cls ^= class_array.At(i);
78 FinalizeClass(cls); 93 FinalizeClass(cls);
79 } 94 }
80 if (FLAG_print_classes) { 95 if (FLAG_print_classes) {
81 for (intptr_t i = 0; i < class_array.Length(); i++) { 96 for (intptr_t i = 0; i < num_pending_classes; i++) {
82 cls ^= class_array.At(i); 97 cls ^= class_array.At(i);
83 PrintClassInformation(cls); 98 PrintClassInformation(cls);
84 } 99 }
85 } 100 }
86 if (FLAG_verify_implements) { 101 if (FLAG_verify_implements) {
87 for (intptr_t i = 0; i < class_array.Length(); i++) { 102 for (intptr_t i = 0; i < num_pending_classes; i++) {
88 cls ^= class_array.At(i); 103 cls ^= class_array.At(i);
89 if (!cls.is_interface()) { 104 if (!cls.is_interface()) {
90 VerifyClassImplements(cls); 105 VerifyClassImplements(cls);
91 } 106 }
92 } 107 }
93 } 108 }
94 // Clear pending classes array. 109 // Clear pending classes array.
95 object_store->set_pending_classes(Array::Handle(Array::Empty())); 110 object_store->set_pending_classes(Array::Handle());
111 ASSERT(AllClassesFinalized());
96 112
97 // Check to ensure there are no duplicate definitions in the library 113 // Check to ensure there are no duplicate definitions in the library
98 // hierarchy. 114 // hierarchy.
99 const String& str = String::Handle(Library::CheckForDuplicateDefinition()); 115 const String& str = String::Handle(Library::CheckForDuplicateDefinition());
100 if (!str.IsNull()) { 116 if (!str.IsNull()) {
101 ReportError("Duplicate definition : %s\n", str.ToCString()); 117 ReportError("Duplicate definition : %s\n", str.ToCString());
102 } 118 }
103 } else { 119 } else {
104 retval = false; 120 retval = false;
105 } 121 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 OS::PrintErr("Could not verify bootstrap classes : %s\n", err.ToCString()); 251 OS::PrintErr("Could not verify bootstrap classes : %s\n", err.ToCString());
236 OS::Exit(255); 252 OS::Exit(255);
237 } 253 }
238 if (FLAG_trace_class_finalization) { 254 if (FLAG_trace_class_finalization) {
239 OS::Print("VerifyBootstrapClasses END.\n"); 255 OS::Print("VerifyBootstrapClasses END.\n");
240 } 256 }
241 Isolate::Current()->heap()->Verify(); 257 Isolate::Current()->heap()->Verify();
242 } 258 }
243 259
244 260
261 // Resolve unresolved_class in the library of cls.
262 RawClass* ClassFinalizer::ResolveClass(
263 const Class& cls, const UnresolvedClass& unresolved_class) {
264 Library& lib = Library::Handle();
265 if (unresolved_class.qualifier() == String::null()) {
266 lib = cls.library();
267 } else {
268 const String& qualifier = String::Handle(unresolved_class.qualifier());
269 LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
270 lib_prefix = cls.LookupLibraryPrefix(qualifier);
271 if (lib_prefix.IsNull()) {
272 const Script& script = Script::Handle(cls.script());
273 ReportError(script, unresolved_class.token_index(),
274 "cannot resolve name '%s'\n",
srdjan 2011/11/09 21:22:43 Maybe be more specific -> cannot resolve library p
regis 2011/11/09 23:31:01 Done.
275 String::Handle(unresolved_class.Name()).ToCString());
276 }
277 lib = lib_prefix.library();
278 }
279 ASSERT(!lib.IsNull());
280 const String& class_name = String::Handle(unresolved_class.ident());
281 const Class& resolved_class = Class::Handle(lib.LookupClass(class_name));
282 if (resolved_class.IsNull()) {
283 const Script& script = Script::Handle(cls.script());
284 ReportError(script, unresolved_class.token_index(),
285 "cannot resolve class name '%s' from '%s'\n",
286 String::Handle(unresolved_class.Name()).ToCString(),
287 String::Handle(cls.Name()).ToCString());
288 }
289 return resolved_class.raw();
290 }
291
292
245 // Resolve unresolved superclasses (String -> Class). 293 // Resolve unresolved superclasses (String -> Class).
246 void ClassFinalizer::ResolveSuperClass(const Class& cls) { 294 void ClassFinalizer::ResolveSuperClass(const Class& cls) {
247 if (cls.is_finalized()) { 295 if (cls.is_finalized()) {
248 return; 296 return;
249 } 297 }
250 Type& super_type = Type::Handle(cls.super_type()); 298 Type& super_type = Type::Handle(cls.super_type());
251 if (super_type.IsNull()) { 299 if (super_type.IsNull()) {
252 return; 300 return;
253 } 301 }
254 // Resolve failures lead to a longjmp. 302 // Resolve failures lead to a longjmp.
255 super_type = ResolveType(cls, super_type); 303 super_type = ResolveType(cls, super_type);
304 if (super_type.IsTypeParameter()) {
305 String& class_name = String::Handle(cls.Name());
306 String& type_parameter_name = String::Handle(super_type.Name());
307 ReportError("'%s' cannot extend or implement type parameter '%s'.\n",
308 class_name.ToCString(),
309 type_parameter_name.ToCString());
310 }
256 cls.set_super_type(super_type); 311 cls.set_super_type(super_type);
257 const Class& super_class = Class::Handle(super_type.type_class()); 312 const Class& super_class = Class::Handle(super_type.type_class());
258 if (cls.is_interface() != super_class.is_interface()) { 313 if (cls.is_interface() != super_class.is_interface()) {
259 String& class_name = String::Handle(cls.Name()); 314 String& class_name = String::Handle(cls.Name());
260 String& super_class_name = String::Handle(super_class.Name()); 315 String& super_class_name = String::Handle(super_class.Name());
261 ReportError("class '%s' and superclass '%s' are not " 316 ReportError("class '%s' and superclass '%s' are not "
262 "both classes or both interfaces.\n", 317 "both classes or both interfaces.\n",
263 class_name.ToCString(), 318 class_name.ToCString(),
264 super_class_name.ToCString()); 319 super_class_name.ToCString());
265 } 320 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 // A type parameter cannot be parameterized, so report an error if type 402 // A type parameter cannot be parameterized, so report an error if type
348 // arguments have previously been parsed. 403 // arguments have previously been parsed.
349 if (type.arguments() != TypeArguments::null()) { 404 if (type.arguments() != TypeArguments::null()) {
350 ReportError("type parameter '%s' cannot be parameterized", 405 ReportError("type parameter '%s' cannot be parameterized",
351 type_class_name.ToCString()); 406 type_class_name.ToCString());
352 } 407 }
353 return type_parameter.raw(); 408 return type_parameter.raw();
354 } 409 }
355 410
356 // Lookup the type class. 411 // Lookup the type class.
357 Class& type_class = Class::Handle(); 412 const Class& type_class =
358 Library& lib = Library::Handle(); 413 Class::Handle(ResolveClass(cls, unresolved_class));
359 if (unresolved_class.qualifier() == String::null()) { 414
360 lib = cls.library();
361 } else {
362 const String& qualifier = String::Handle(unresolved_class.qualifier());
363 LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
364 lib_prefix = cls.LookupLibraryPrefix(qualifier);
365 if (lib_prefix.IsNull()) {
366 const Script& script = Script::Handle(cls.script());
367 ReportError(script, unresolved_class.token_index(),
368 "cannot resolve name '%s'\n",
369 String::Handle(unresolved_class.Name()).ToCString());
370 }
371 lib = lib_prefix.library();
372 }
373 ASSERT(!lib.IsNull());
374 type_class = lib.LookupClass(type_class_name);
375 if (type_class.IsNull()) {
376 const Script& script = Script::Handle(cls.script());
377 ReportError(script, unresolved_class.token_index(),
378 "cannot resolve class name '%s' from '%s'\n",
379 String::Handle(unresolved_class.Name()).ToCString(),
380 String::Handle(cls.Name()).ToCString());
381 }
382 // Replace unresolved class with resolved type class. 415 // Replace unresolved class with resolved type class.
383 ASSERT(type.IsParameterizedType()); 416 ASSERT(type.IsParameterizedType());
384 ParameterizedType& parameterized_type = ParameterizedType::Handle(); 417 ParameterizedType& parameterized_type = ParameterizedType::Handle();
385 parameterized_type ^= type.raw(); 418 parameterized_type ^= type.raw();
386 parameterized_type.set_type_class(Object::Handle(type_class.raw())); 419 parameterized_type.set_type_class(Object::Handle(type_class.raw()));
387 } 420 }
388 421
389 // Resolve type arguments, if any. 422 // Resolve type arguments, if any.
390 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); 423 const TypeArguments& arguments = TypeArguments::Handle(type.arguments());
391 if (!arguments.IsNull()) { 424 if (!arguments.IsNull()) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 if (!arguments.IsNull()) { 532 if (!arguments.IsNull()) {
500 intptr_t num_arguments = arguments.Length(); 533 intptr_t num_arguments = arguments.Length();
501 for (intptr_t i = 0; i < num_arguments; i++) { 534 for (intptr_t i = 0; i < num_arguments; i++) {
502 Type& type_argument = Type::Handle(arguments.TypeAt(i)); 535 Type& type_argument = Type::Handle(arguments.TypeAt(i));
503 type_argument = FinalizeType(type_argument); 536 type_argument = FinalizeType(type_argument);
504 arguments.SetTypeAt(i, type_argument); 537 arguments.SetTypeAt(i, type_argument);
505 } 538 }
506 } 539 }
507 540
508 // The type class does not need to be finalized in order to finalize the type, 541 // The type class does not need to be finalized in order to finalize the type,
509 // however, it must at least be resolved. This was done as part of resolving 542 // however, it must at least be resolved (this was done as part of resolving
510 // the type itself. 543 // the type itself, a precondition to calling FinalizeType) and the upper
544 // bounds of its type parameters must be finalized (done here).
511 Class& type_class = Class::Handle(parameterized_type.type_class()); 545 Class& type_class = Class::Handle(parameterized_type.type_class());
512 546
547 // If the type class is a signature class, finalize it, thereby finalizing the
548 // result and parameter types of its signature function.
549 // Do this before marking this type as finalized in order to detect cycles.
550 if (type_class.IsSignatureClass()) {
551 FinalizeClass(type_class);
552 }
553
513 // The finalized type argument vector needs num_type_arguments types. 554 // The finalized type argument vector needs num_type_arguments types.
514 const intptr_t num_type_arguments = type_class.NumTypeArguments(); 555 const intptr_t num_type_arguments = type_class.NumTypeArguments();
515 // The type class has num_type_parameters type parameters. 556 // The type class has num_type_parameters type parameters.
516 const intptr_t num_type_parameters = type_class.NumTypeParameters(); 557 const intptr_t num_type_parameters = type_class.NumTypeParameters();
517 558
518 // Initialize the type argument vector. 559 // Initialize the type argument vector.
519 // Check the number of parsed type arguments, if any. 560 // Check the number of parsed type arguments, if any.
520 // Specifying no type arguments indicates a raw type, which is not an error. 561 // Specifying no type arguments indicates a raw type, which is not an error.
521 // However, subtyping constraints are checked below, even for a raw type. 562 // However, subtyping constraints are checked below, even for a raw type.
522 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { 563 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) {
(...skipping 15 matching lines...) Expand all
538 // If no type parameters were provided, a raw type is desired, so we 579 // If no type parameters were provided, a raw type is desired, so we
539 // create a vector of DynamicType. 580 // create a vector of DynamicType.
540 if (!arguments.IsNull()) { 581 if (!arguments.IsNull()) {
541 type = arguments.TypeAt(i); 582 type = arguments.TypeAt(i);
542 } 583 }
543 full_arguments.SetTypeAt(offset + i, type); 584 full_arguments.SetTypeAt(offset + i, type);
544 } 585 }
545 FinalizeTypeArguments(type_class, full_arguments); 586 FinalizeTypeArguments(type_class, full_arguments);
546 parameterized_type.set_arguments(full_arguments); 587 parameterized_type.set_arguments(full_arguments);
547 } 588 }
589 // Mark the type as finalized before finalizing the upper bounds, because
590 // cycles via upper bounds are legal at compile time.
591 parameterized_type.set_is_finalized();
592 ResolveAndFinalizeUpperBounds(type_class);
548 593
549 // If the type is a function type, finalize the result and parameter types.
550 if (type_class.IsSignatureClass()) {
551 ResolveAndFinalizeSignature(
552 type_class, Function::Handle(type_class.signature_function()));
553 }
554
555 parameterized_type.set_is_finalized();
556 return parameterized_type.Canonicalize(); 594 return parameterized_type.Canonicalize();
557 } 595 }
558 596
559 597
560 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type, 598 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type,
561 String* errmsg) { 599 String* errmsg) {
562 Isolate* isolate = Isolate::Current(); 600 Isolate* isolate = Isolate::Current();
563 ASSERT(isolate != NULL); 601 ASSERT(isolate != NULL);
564 LongJump* base = isolate->long_jump_base(); 602 LongJump* base = isolate->long_jump_base();
565 LongJump jump; 603 LongJump jump;
566 isolate->set_long_jump_base(&jump); 604 isolate->set_long_jump_base(&jump);
567 if (setjmp(*jump.Set()) == 0) { 605 if (setjmp(*jump.Set()) == 0) {
568 const Type& canonical_type = Type::Handle(FinalizeType(type)); 606 Type& canonical_type = Type::Handle();
607 if (type.IsSignatureType() && !AllClassesFinalized()) {
srdjan 2011/11/09 21:22:43 Maybe have a interim method: CollectingClassesToFi
regis 2011/11/09 23:31:01 Done. Renamed these calls to: ExpectClassesToFinal
608 // Postpone the finalization of this signature type and class.
609 GrowableArray<const Class*> classes;
610 classes.Add(&Class::ZoneHandle(type.type_class()));
611 ClassFinalizer::AddPendingClasses(classes);
612 } else {
613 canonical_type = FinalizeType(type);
614 }
569 isolate->set_long_jump_base(base); 615 isolate->set_long_jump_base(base);
570 *errmsg = String::null(); 616 *errmsg = String::null();
571 return canonical_type.raw(); 617 return canonical_type.raw();
572 } else { 618 } else {
573 // Error occured: Get the error message. 619 // Error occured: Get the error message.
574 isolate->set_long_jump_base(base); 620 isolate->set_long_jump_base(base);
575 *errmsg = isolate->object_store()->sticky_error(); 621 *errmsg = isolate->object_store()->sticky_error();
576 return type.raw(); 622 return type.raw();
577 } 623 }
578 UNREACHABLE(); 624 UNREACHABLE();
579 return Type::null(); 625 return Type::null();
580 } 626 }
581 627
582 628
583 // Top level function signatures are canonicalized, added to the library class
584 // dictionary, and finalized with other library classes and interfaces.
585 // Function signatures used as type of a local variable or of a local function
586 // are canonicalized and finalized upon creation, since all the types they
587 // reference are already resolved.
588 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, 629 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls,
589 const Function& function) { 630 const Function& function) {
590 // Resolve result type. 631 // Resolve result type.
591 Type& type = Type::Handle(function.result_type()); 632 Type& type = Type::Handle(function.result_type());
592 type = ResolveType(cls, type); 633 type = ResolveType(cls, type);
593 function.set_result_type(type); 634 function.set_result_type(type);
594 type = FinalizeType(type); 635 type = FinalizeType(type);
595 function.set_result_type(type); 636 function.set_result_type(type);
596 // Resolve formal parameter types. 637 // Resolve formal parameter types.
597 const intptr_t num_parameters = function.NumberOfParameters(); 638 const intptr_t num_parameters = function.NumberOfParameters();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 function = super_class.LookupFunction(name); 678 function = super_class.LookupFunction(name);
638 if (!function.IsNull()) { 679 if (!function.IsNull()) {
639 return super_class.raw(); 680 return super_class.raw();
640 } 681 }
641 super_class = super_class.SuperClass(); 682 super_class = super_class.SuperClass();
642 } 683 }
643 return Class::null(); 684 return Class::null();
644 } 685 }
645 686
646 687
688 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) {
689 const intptr_t num_type_params = cls.NumTypeParameters();
690 Type& type_extends = Type::Handle();
691 const TypeArguments& extends_array =
692 TypeArguments::Handle(cls.type_parameter_extends());
693 ASSERT((extends_array.IsNull() && (num_type_params == 0)) ||
694 (extends_array.Length() == num_type_params));
695 for (intptr_t i = 0; i < num_type_params; i++) {
696 type_extends = extends_array.TypeAt(i);
697 type_extends = ResolveType(cls, type_extends);
698 extends_array.SetTypeAt(i, type_extends);
699 type_extends = FinalizeType(type_extends);
700 extends_array.SetTypeAt(i, type_extends);
701 }
702 }
703
704
647 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { 705 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) {
648 // Note that getters and setters are explicitly listed as such in the list of 706 // Note that getters and setters are explicitly listed as such in the list of
649 // functions of a class, so we do not need to consider fields as implicitly 707 // functions of a class, so we do not need to consider fields as implicitly
650 // generating getters and setters. 708 // generating getters and setters.
651 // The only compile errors we report are therefore: 709 // The only compile errors we report are therefore:
652 // - a getter having the same name as a method (but not a getter) in a super 710 // - a getter having the same name as a method (but not a getter) in a super
653 // class or in a subclass. 711 // class or in a subclass.
654 // - a setter having the same name as a method (but not a setter) in a super 712 // - a setter having the same name as a method (but not a setter) in a super
655 // class or in a subclass. 713 // class or in a subclass.
656 // - a static field, instance field, or static method (but not an instance 714 // - a static field, instance field, or static method (but not an instance
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 const String& super_class_name = String::Handle(super_class.Name()); 828 const String& super_class_name = String::Handle(super_class.Name());
771 ReportError("function '%s' of class '%s' conflicts with " 829 ReportError("function '%s' of class '%s' conflicts with "
772 "setter '%s' of super class '%s'.\n", 830 "setter '%s' of super class '%s'.\n",
773 function_name.ToCString(), 831 function_name.ToCString(),
774 class_name.ToCString(), 832 class_name.ToCString(),
775 function_name.ToCString(), 833 function_name.ToCString(),
776 super_class_name.ToCString()); 834 super_class_name.ToCString());
777 } 835 }
778 } 836 }
779 } 837 }
780 // Resolve the signature type if this class is a signature class.
781 if (cls.IsSignatureClass()) {
782 Type& signature_type = Type::Handle(cls.SignatureType());
783 signature_type = FinalizeType(signature_type);
784 // Signature types are canonicalized by default.
785 ASSERT(signature_type.raw() == cls.SignatureType());
786 }
787 } 838 }
788 839
789 840
790 void ClassFinalizer::FinalizeClass(const Class& cls) { 841 void ClassFinalizer::FinalizeClass(const Class& cls) {
791 if (cls.is_finalized()) { 842 if (cls.is_finalized()) {
792 return; 843 return;
793 } 844 }
794 if (FLAG_trace_class_finalization) { 845 if (FLAG_trace_class_finalization) {
795 OS::Print("Finalize %s\n", cls.ToCString()); 846 OS::Print("Finalize %s\n", cls.ToCString());
796 } 847 }
(...skipping 29 matching lines...) Expand all
826 } 877 }
827 } 878 }
828 // Finalize interface types (but not necessarily interface classes). 879 // Finalize interface types (but not necessarily interface classes).
829 Array& interface_types = Array::Handle(cls.interfaces()); 880 Array& interface_types = Array::Handle(cls.interfaces());
830 Type& interface_type = Type::Handle(); 881 Type& interface_type = Type::Handle();
831 for (intptr_t i = 0; i < interface_types.Length(); i++) { 882 for (intptr_t i = 0; i < interface_types.Length(); i++) {
832 interface_type ^= interface_types.At(i); 883 interface_type ^= interface_types.At(i);
833 interface_type = FinalizeType(interface_type); 884 interface_type = FinalizeType(interface_type);
834 interface_types.SetAt(i, interface_type); 885 interface_types.SetAt(i, interface_type);
835 } 886 }
836 // Mark as finalized before resolving member types in order to break cycles. 887 // Mark as finalized before resolving type parameter upper bounds and member
888 // types in order to break cycles.
837 cls.Finalize(); 889 cls.Finalize();
890 ResolveAndFinalizeUpperBounds(cls);
838 ResolveAndFinalizeMemberTypes(cls); 891 ResolveAndFinalizeMemberTypes(cls);
892
893 if (cls.IsSignatureClass()) {
894 // Finalize the signature type of this signature class.
895 Type& signature_type = Type::Handle(cls.SignatureType());
896 signature_type = FinalizeType(signature_type);
897 // Signature types are canonicalized by default.
898 ASSERT(signature_type.raw() == cls.SignatureType());
899
900 // Resolve and finalize the result and parameter types of the signature
901 // function of this signature class.
902 ResolveAndFinalizeSignature(cls,
903 Function::Handle(cls.signature_function()));
904 }
905
839 // Run additional checks after all types are finalized. 906 // Run additional checks after all types are finalized.
840 if (cls.is_const()) { 907 if (cls.is_const()) {
841 CheckForLegalConstClass(cls); 908 CheckForLegalConstClass(cls);
842 } 909 }
843 } 910 }
844 911
845 912
846 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { 913 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) {
847 Class& test1 = Class::Handle(cls.raw()); 914 Class& test1 = Class::Handle(cls.raw());
848 Class& test2 = Class::Handle(cls.SuperClass()); 915 Class& test2 = Class::Handle(cls.SuperClass());
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 interface.IsNumberInterface() || 1024 interface.IsNumberInterface() ||
958 interface.IsIntInterface() || 1025 interface.IsIntInterface() ||
959 interface.IsDoubleInterface() || 1026 interface.IsDoubleInterface() ||
960 interface.IsStringInterface() || 1027 interface.IsStringInterface() ||
961 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || 1028 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) ||
962 interface.IsDynamicType()) { 1029 interface.IsDynamicType()) {
963 ReportError("'%s' is not allowed to extend or implement '%s'\n", 1030 ReportError("'%s' is not allowed to extend or implement '%s'\n",
964 String::Handle(cls.Name()).ToCString(), 1031 String::Handle(cls.Name()).ToCString(),
965 String::Handle(interface_class.Name()).ToCString()); 1032 String::Handle(interface_class.Name()).ToCString());
966 } 1033 }
967 // TODO(regis): We also need to prevent extending classes Smi, Mint,
968 // BigInt, Double, OneByteString, TwoByteString, FourByteString.
969 } 1034 }
970 // Now resolve the super interfaces. 1035 // Now resolve the super interfaces.
971 ResolveInterfaces(interface_class, visited); 1036 ResolveInterfaces(interface_class, visited);
972 } 1037 }
973 visited->RemoveLast(); 1038 visited->RemoveLast();
974 } 1039 }
975 1040
976 1041
977 // A class is marked as constant if it has one constant constructor. 1042 // A class is marked as constant if it has one constant constructor.
978 // A constant class: 1043 // A constant class:
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1084 ASSERT(msg_buffer != NULL); 1149 ASSERT(msg_buffer != NULL);
1085 va_list args; 1150 va_list args;
1086 va_start(args, format); 1151 va_start(args, format);
1087 OS::VSNPrint(msg_buffer, kBufferLength, format, args); 1152 OS::VSNPrint(msg_buffer, kBufferLength, format, args);
1088 va_end(args); 1153 va_end(args);
1089 isolate->long_jump_base()->Jump(1, msg_buffer); 1154 isolate->long_jump_base()->Jump(1, msg_buffer);
1090 UNREACHABLE(); 1155 UNREACHABLE();
1091 } 1156 }
1092 1157
1093 } // namespace dart 1158 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698