Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |