| 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::ExpectClassesToFinalize() { | 21 void ClassFinalizer::AddPendingClasses( |
| 22 if (!IsExpectingClassesToFinalize()) { | |
| 23 ObjectStore* object_store = Isolate::Current()->object_store(); | |
| 24 object_store->set_pending_classes(Array::Handle(Array::Empty())); | |
| 25 ASSERT(IsExpectingClassesToFinalize()); | |
| 26 } | |
| 27 } | |
| 28 | |
| 29 | |
| 30 bool ClassFinalizer::IsExpectingClassesToFinalize() { | |
| 31 ObjectStore* object_store = Isolate::Current()->object_store(); | |
| 32 const Array& classes = Array::Handle(object_store->pending_classes()); | |
| 33 return !classes.IsNull(); | |
| 34 } | |
| 35 | |
| 36 | |
| 37 void ClassFinalizer::AddClassesToFinalize( | |
| 38 const GrowableArray<const Class*>& classes) { | 22 const GrowableArray<const Class*>& classes) { |
| 39 // ExpectClassesToFinalize() must be called prior to calling | |
| 40 // AddClassesToFinalize(). | |
| 41 ASSERT(IsExpectingClassesToFinalize()); | |
| 42 if (!classes.is_empty()) { | 23 if (!classes.is_empty()) { |
| 43 ObjectStore* object_store = Isolate::Current()->object_store(); | 24 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 44 const Array& old_array = Array::Handle(object_store->pending_classes()); | 25 const Array& old_array = Array::Handle(object_store->pending_classes()); |
| 45 const intptr_t old_length = old_array.Length(); | 26 const intptr_t old_length = old_array.Length(); |
| 46 const int new_length = old_length + classes.length(); | 27 const int new_length = old_length + classes.length(); |
| 47 const Array& new_array = Array::Handle(Array::Grow(old_array, new_length)); | 28 const Array& new_array = Array::Handle(Array::Grow(old_array, new_length)); |
| 48 // Add new classes. | 29 // Add new classes. |
| 49 for (int i = 0; i < classes.length(); i++) { | 30 for (int i = 0; i < classes.length(); i++) { |
| 50 new_array.SetAt(i + old_length, *classes[i]); | 31 new_array.SetAt(i + old_length, *classes[i]); |
| 51 } | 32 } |
| 52 object_store->set_pending_classes(new_array); | 33 object_store->set_pending_classes(new_array); |
| 53 ASSERT(IsExpectingClassesToFinalize()); | |
| 54 } | 34 } |
| 55 } | 35 } |
| 56 | 36 |
| 57 | 37 |
| 38 bool ClassFinalizer::AllClassesFinalized() { |
| 39 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 40 const Array& classes = Array::Handle(object_store->pending_classes()); |
| 41 return classes.Length() == 0; |
| 42 } |
| 43 |
| 44 |
| 58 // Class finalization occurs: | 45 // Class finalization occurs: |
| 59 // a) when bootstrap process completes (VerifyBootstrapClasses). | 46 // a) when bootstrap process completes (VerifyBootstrapClasses). |
| 60 // b) after the user classes are loaded (dart_api). | 47 // b) after the user classes are loaded (dart_api). |
| 61 bool ClassFinalizer::FinalizeAllClasses() { | 48 bool ClassFinalizer::FinalizePendingClasses() { |
| 62 bool retval = true; | 49 bool retval = true; |
| 63 Isolate* isolate = Isolate::Current(); | 50 Isolate* isolate = Isolate::Current(); |
| 64 ASSERT(isolate != NULL); | 51 ASSERT(isolate != NULL); |
| 65 ObjectStore* object_store = isolate->object_store(); | 52 ObjectStore* object_store = isolate->object_store(); |
| 66 const String& error = String::Handle(object_store->sticky_error()); | 53 const String& error = String::Handle(object_store->sticky_error()); |
| 67 if (!error.IsNull()) { | 54 if (!error.IsNull()) { |
| 68 return false; | 55 return false; |
| 69 } | 56 } |
| 70 LongJump* base = isolate->long_jump_base(); | 57 LongJump* base = isolate->long_jump_base(); |
| 71 LongJump jump; | 58 LongJump jump; |
| 72 isolate->set_long_jump_base(&jump); | 59 isolate->set_long_jump_base(&jump); |
| 73 if (setjmp(*jump.Set()) == 0) { | 60 if (setjmp(*jump.Set()) == 0) { |
| 74 const Array& class_array = Array::Handle(object_store->pending_classes()); | 61 const Array& class_array = Array::Handle(object_store->pending_classes()); |
| 75 const intptr_t num_pending_classes = | 62 ASSERT(!class_array.IsNull()); |
| 76 class_array.IsNull() ? 0 : class_array.Length(); | |
| 77 Class& cls = Class::Handle(); | 63 Class& cls = Class::Handle(); |
| 78 // First resolve all superclasses. | 64 // First resolve all superclasses. |
| 79 for (intptr_t i = 0; i < num_pending_classes; i++) { | 65 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 80 cls ^= class_array.At(i); | 66 cls ^= class_array.At(i); |
| 81 if (FLAG_trace_class_finalization) { | 67 if (FLAG_trace_class_finalization) { |
| 82 OS::Print("Resolving super and default: %s\n", cls.ToCString()); | 68 OS::Print("Resolving super and default: %s\n", cls.ToCString()); |
| 83 } | 69 } |
| 84 ResolveSuperClass(cls); | 70 ResolveSuperClass(cls); |
| 85 if (cls.is_interface()) { | 71 if (cls.is_interface()) { |
| 86 ResolveDefaultClass(cls); | 72 ResolveDefaultClass(cls); |
| 87 } | 73 } |
| 88 } | 74 } |
| 89 // Finalize all classes. | 75 // Finalize all classes. |
| 90 for (intptr_t i = 0; i < num_pending_classes; i++) { | 76 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 91 cls ^= class_array.At(i); | 77 cls ^= class_array.At(i); |
| 92 FinalizeClass(cls); | 78 FinalizeClass(cls); |
| 93 } | 79 } |
| 94 if (FLAG_print_classes) { | 80 if (FLAG_print_classes) { |
| 95 for (intptr_t i = 0; i < num_pending_classes; i++) { | 81 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 96 cls ^= class_array.At(i); | 82 cls ^= class_array.At(i); |
| 97 PrintClassInformation(cls); | 83 PrintClassInformation(cls); |
| 98 } | 84 } |
| 99 } | 85 } |
| 100 if (FLAG_verify_implements) { | 86 if (FLAG_verify_implements) { |
| 101 for (intptr_t i = 0; i < num_pending_classes; i++) { | 87 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 102 cls ^= class_array.At(i); | 88 cls ^= class_array.At(i); |
| 103 if (!cls.is_interface()) { | 89 if (!cls.is_interface()) { |
| 104 VerifyClassImplements(cls); | 90 VerifyClassImplements(cls); |
| 105 } | 91 } |
| 106 } | 92 } |
| 107 } | 93 } |
| 108 // Clear pending classes array. | 94 // Clear pending classes array. |
| 109 object_store->set_pending_classes(Array::Handle()); | 95 object_store->set_pending_classes(Array::Handle(Array::Empty())); |
| 110 ASSERT(!IsExpectingClassesToFinalize()); | |
| 111 | 96 |
| 112 // Check to ensure there are no duplicate definitions in the library | 97 // Check to ensure there are no duplicate definitions in the library |
| 113 // hierarchy. | 98 // hierarchy. |
| 114 const String& str = String::Handle(Library::CheckForDuplicateDefinition()); | 99 const String& str = String::Handle(Library::CheckForDuplicateDefinition()); |
| 115 if (!str.IsNull()) { | 100 if (!str.IsNull()) { |
| 116 ReportError("Duplicate definition : %s\n", str.ToCString()); | 101 ReportError("Duplicate definition : %s\n", str.ToCString()); |
| 117 } | 102 } |
| 118 } else { | 103 } else { |
| 119 retval = false; | 104 retval = false; |
| 120 } | 105 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 for (intptr_t i = 0; i < class_array.Length(); i++) { | 222 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 238 // TODO(iposva): Add real checks. | 223 // TODO(iposva): Add real checks. |
| 239 cls ^= class_array.At(i); | 224 cls ^= class_array.At(i); |
| 240 if (cls.is_finalized() || cls.is_prefinalized()) { | 225 if (cls.is_finalized() || cls.is_prefinalized()) { |
| 241 // Pre-finalized bootstrap classes must not define any fields. | 226 // Pre-finalized bootstrap classes must not define any fields. |
| 242 ASSERT(Array::Handle(cls.fields()).Length() == 0); | 227 ASSERT(Array::Handle(cls.fields()).Length() == 0); |
| 243 } | 228 } |
| 244 } | 229 } |
| 245 | 230 |
| 246 // Finalize classes that aren't pre-finalized by Object::Init(). | 231 // Finalize classes that aren't pre-finalized by Object::Init(). |
| 247 if (!FinalizeAllClasses()) { | 232 if (!FinalizePendingClasses()) { |
| 248 // TODO(srdjan): Exit like a real VM instead. | 233 // TODO(srdjan): Exit like a real VM instead. |
| 249 const String& err = String::Handle(object_store->sticky_error()); | 234 const String& err = String::Handle(object_store->sticky_error()); |
| 250 OS::PrintErr("Could not verify bootstrap classes : %s\n", err.ToCString()); | 235 OS::PrintErr("Could not verify bootstrap classes : %s\n", err.ToCString()); |
| 251 OS::Exit(255); | 236 OS::Exit(255); |
| 252 } | 237 } |
| 253 if (FLAG_trace_class_finalization) { | 238 if (FLAG_trace_class_finalization) { |
| 254 OS::Print("VerifyBootstrapClasses END.\n"); | 239 OS::Print("VerifyBootstrapClasses END.\n"); |
| 255 } | 240 } |
| 256 Isolate::Current()->heap()->Verify(); | 241 Isolate::Current()->heap()->Verify(); |
| 257 } | 242 } |
| 258 | 243 |
| 259 | 244 |
| 260 // Resolve unresolved_class in the library of cls. | |
| 261 RawClass* ClassFinalizer::ResolveClass( | |
| 262 const Class& cls, const UnresolvedClass& unresolved_class) { | |
| 263 Library& lib = Library::Handle(); | |
| 264 if (unresolved_class.qualifier() == String::null()) { | |
| 265 lib = cls.library(); | |
| 266 } else { | |
| 267 const String& qualifier = String::Handle(unresolved_class.qualifier()); | |
| 268 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); | |
| 269 lib_prefix = cls.LookupLibraryPrefix(qualifier); | |
| 270 if (lib_prefix.IsNull()) { | |
| 271 const Script& script = Script::Handle(cls.script()); | |
| 272 ReportError(script, unresolved_class.token_index(), | |
| 273 "cannot resolve library prefix '%s' from '%s'.\n", | |
| 274 String::Handle(unresolved_class.Name()).ToCString(), | |
| 275 String::Handle(cls.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 | |
| 293 // Resolve unresolved superclasses (String -> Class). | 245 // Resolve unresolved superclasses (String -> Class). |
| 294 void ClassFinalizer::ResolveSuperClass(const Class& cls) { | 246 void ClassFinalizer::ResolveSuperClass(const Class& cls) { |
| 295 if (cls.is_finalized()) { | 247 if (cls.is_finalized()) { |
| 296 return; | 248 return; |
| 297 } | 249 } |
| 298 Type& super_type = Type::Handle(cls.super_type()); | 250 Type& super_type = Type::Handle(cls.super_type()); |
| 299 if (super_type.IsNull()) { | 251 if (super_type.IsNull()) { |
| 300 return; | 252 return; |
| 301 } | 253 } |
| 302 // Resolve failures lead to a longjmp. | 254 // Resolve failures lead to a longjmp. |
| 303 super_type = ResolveType(cls, super_type); | 255 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 } | |
| 311 cls.set_super_type(super_type); | 256 cls.set_super_type(super_type); |
| 312 const Class& super_class = Class::Handle(super_type.type_class()); | 257 const Class& super_class = Class::Handle(super_type.type_class()); |
| 313 if (cls.is_interface() != super_class.is_interface()) { | 258 if (cls.is_interface() != super_class.is_interface()) { |
| 314 String& class_name = String::Handle(cls.Name()); | 259 String& class_name = String::Handle(cls.Name()); |
| 315 String& super_class_name = String::Handle(super_class.Name()); | 260 String& super_class_name = String::Handle(super_class.Name()); |
| 316 ReportError("class '%s' and superclass '%s' are not " | 261 ReportError("class '%s' and superclass '%s' are not " |
| 317 "both classes or both interfaces.\n", | 262 "both classes or both interfaces.\n", |
| 318 class_name.ToCString(), | 263 class_name.ToCString(), |
| 319 super_class_name.ToCString()); | 264 super_class_name.ToCString()); |
| 320 } | 265 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 // A type parameter cannot be parameterized, so report an error if type | 347 // A type parameter cannot be parameterized, so report an error if type |
| 403 // arguments have previously been parsed. | 348 // arguments have previously been parsed. |
| 404 if (type.arguments() != TypeArguments::null()) { | 349 if (type.arguments() != TypeArguments::null()) { |
| 405 ReportError("type parameter '%s' cannot be parameterized", | 350 ReportError("type parameter '%s' cannot be parameterized", |
| 406 type_class_name.ToCString()); | 351 type_class_name.ToCString()); |
| 407 } | 352 } |
| 408 return type_parameter.raw(); | 353 return type_parameter.raw(); |
| 409 } | 354 } |
| 410 | 355 |
| 411 // Lookup the type class. | 356 // Lookup the type class. |
| 412 const Class& type_class = | 357 Class& type_class = Class::Handle(); |
| 413 Class::Handle(ResolveClass(cls, unresolved_class)); | 358 Library& lib = Library::Handle(); |
| 414 | 359 if (unresolved_class.qualifier() == String::null()) { |
| 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 } |
| 415 // Replace unresolved class with resolved type class. | 382 // Replace unresolved class with resolved type class. |
| 416 ASSERT(type.IsParameterizedType()); | 383 ASSERT(type.IsParameterizedType()); |
| 417 ParameterizedType& parameterized_type = ParameterizedType::Handle(); | 384 ParameterizedType& parameterized_type = ParameterizedType::Handle(); |
| 418 parameterized_type ^= type.raw(); | 385 parameterized_type ^= type.raw(); |
| 419 parameterized_type.set_type_class(Object::Handle(type_class.raw())); | 386 parameterized_type.set_type_class(Object::Handle(type_class.raw())); |
| 420 } | 387 } |
| 421 | 388 |
| 422 // Resolve type arguments, if any. | 389 // Resolve type arguments, if any. |
| 423 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); | 390 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); |
| 424 if (!arguments.IsNull()) { | 391 if (!arguments.IsNull()) { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 if (!arguments.IsNull()) { | 499 if (!arguments.IsNull()) { |
| 533 intptr_t num_arguments = arguments.Length(); | 500 intptr_t num_arguments = arguments.Length(); |
| 534 for (intptr_t i = 0; i < num_arguments; i++) { | 501 for (intptr_t i = 0; i < num_arguments; i++) { |
| 535 Type& type_argument = Type::Handle(arguments.TypeAt(i)); | 502 Type& type_argument = Type::Handle(arguments.TypeAt(i)); |
| 536 type_argument = FinalizeType(type_argument); | 503 type_argument = FinalizeType(type_argument); |
| 537 arguments.SetTypeAt(i, type_argument); | 504 arguments.SetTypeAt(i, type_argument); |
| 538 } | 505 } |
| 539 } | 506 } |
| 540 | 507 |
| 541 // The type class does not need to be finalized in order to finalize the type, | 508 // The type class does not need to be finalized in order to finalize the type, |
| 542 // however, it must at least be resolved (this was done as part of resolving | 509 // however, it must at least be resolved. This was done as part of resolving |
| 543 // the type itself, a precondition to calling FinalizeType) and the upper | 510 // the type itself. |
| 544 // bounds of its type parameters must be finalized (done here). | |
| 545 Class& type_class = Class::Handle(parameterized_type.type_class()); | 511 Class& type_class = Class::Handle(parameterized_type.type_class()); |
| 546 | 512 |
| 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 | |
| 554 // The finalized type argument vector needs num_type_arguments types. | 513 // The finalized type argument vector needs num_type_arguments types. |
| 555 const intptr_t num_type_arguments = type_class.NumTypeArguments(); | 514 const intptr_t num_type_arguments = type_class.NumTypeArguments(); |
| 556 // The type class has num_type_parameters type parameters. | 515 // The type class has num_type_parameters type parameters. |
| 557 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 516 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 558 | 517 |
| 559 // Initialize the type argument vector. | 518 // Initialize the type argument vector. |
| 560 // Check the number of parsed type arguments, if any. | 519 // Check the number of parsed type arguments, if any. |
| 561 // Specifying no type arguments indicates a raw type, which is not an error. | 520 // Specifying no type arguments indicates a raw type, which is not an error. |
| 562 // However, subtyping constraints are checked below, even for a raw type. | 521 // However, subtyping constraints are checked below, even for a raw type. |
| 563 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 522 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 579 // If no type parameters were provided, a raw type is desired, so we | 538 // If no type parameters were provided, a raw type is desired, so we |
| 580 // create a vector of DynamicType. | 539 // create a vector of DynamicType. |
| 581 if (!arguments.IsNull()) { | 540 if (!arguments.IsNull()) { |
| 582 type = arguments.TypeAt(i); | 541 type = arguments.TypeAt(i); |
| 583 } | 542 } |
| 584 full_arguments.SetTypeAt(offset + i, type); | 543 full_arguments.SetTypeAt(offset + i, type); |
| 585 } | 544 } |
| 586 FinalizeTypeArguments(type_class, full_arguments); | 545 FinalizeTypeArguments(type_class, full_arguments); |
| 587 parameterized_type.set_arguments(full_arguments); | 546 parameterized_type.set_arguments(full_arguments); |
| 588 } | 547 } |
| 589 // Mark the type as finalized before finalizing the upper bounds, because | 548 |
| 590 // cycles via upper bounds are legal at compile time. | 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 |
| 591 parameterized_type.set_is_finalized(); | 555 parameterized_type.set_is_finalized(); |
| 592 ResolveAndFinalizeUpperBounds(type_class); | |
| 593 | |
| 594 return parameterized_type.Canonicalize(); | 556 return parameterized_type.Canonicalize(); |
| 595 } | 557 } |
| 596 | 558 |
| 597 | 559 |
| 598 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type, | 560 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type, |
| 599 String* errmsg) { | 561 String* errmsg) { |
| 600 Isolate* isolate = Isolate::Current(); | 562 Isolate* isolate = Isolate::Current(); |
| 601 ASSERT(isolate != NULL); | 563 ASSERT(isolate != NULL); |
| 602 LongJump* base = isolate->long_jump_base(); | 564 LongJump* base = isolate->long_jump_base(); |
| 603 LongJump jump; | 565 LongJump jump; |
| 604 isolate->set_long_jump_base(&jump); | 566 isolate->set_long_jump_base(&jump); |
| 605 if (setjmp(*jump.Set()) == 0) { | 567 if (setjmp(*jump.Set()) == 0) { |
| 606 Type& canonical_type = Type::Handle(); | 568 const Type& canonical_type = Type::Handle(FinalizeType(type)); |
| 607 if (type.IsSignatureType() && !AllClassesFinalized()) { | |
| 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::AddClassesToFinalize(classes); | |
| 612 } else { | |
| 613 canonical_type = FinalizeType(type); | |
| 614 } | |
| 615 isolate->set_long_jump_base(base); | 569 isolate->set_long_jump_base(base); |
| 616 *errmsg = String::null(); | 570 *errmsg = String::null(); |
| 617 return canonical_type.raw(); | 571 return canonical_type.raw(); |
| 618 } else { | 572 } else { |
| 619 // Error occured: Get the error message. | 573 // Error occured: Get the error message. |
| 620 isolate->set_long_jump_base(base); | 574 isolate->set_long_jump_base(base); |
| 621 *errmsg = isolate->object_store()->sticky_error(); | 575 *errmsg = isolate->object_store()->sticky_error(); |
| 622 return type.raw(); | 576 return type.raw(); |
| 623 } | 577 } |
| 624 UNREACHABLE(); | 578 UNREACHABLE(); |
| 625 return Type::null(); | 579 return Type::null(); |
| 626 } | 580 } |
| 627 | 581 |
| 628 | 582 |
| 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. |
| 629 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, | 588 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, |
| 630 const Function& function) { | 589 const Function& function) { |
| 631 // Resolve result type. | 590 // Resolve result type. |
| 632 Type& type = Type::Handle(function.result_type()); | 591 Type& type = Type::Handle(function.result_type()); |
| 633 type = ResolveType(cls, type); | 592 type = ResolveType(cls, type); |
| 634 function.set_result_type(type); | 593 function.set_result_type(type); |
| 635 type = FinalizeType(type); | 594 type = FinalizeType(type); |
| 636 function.set_result_type(type); | 595 function.set_result_type(type); |
| 637 // Resolve formal parameter types. | 596 // Resolve formal parameter types. |
| 638 const intptr_t num_parameters = function.NumberOfParameters(); | 597 const intptr_t num_parameters = function.NumberOfParameters(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 function = super_class.LookupFunction(name); | 637 function = super_class.LookupFunction(name); |
| 679 if (!function.IsNull()) { | 638 if (!function.IsNull()) { |
| 680 return super_class.raw(); | 639 return super_class.raw(); |
| 681 } | 640 } |
| 682 super_class = super_class.SuperClass(); | 641 super_class = super_class.SuperClass(); |
| 683 } | 642 } |
| 684 return Class::null(); | 643 return Class::null(); |
| 685 } | 644 } |
| 686 | 645 |
| 687 | 646 |
| 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 | |
| 705 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { | 647 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { |
| 706 // Note that getters and setters are explicitly listed as such in the list of | 648 // Note that getters and setters are explicitly listed as such in the list of |
| 707 // functions of a class, so we do not need to consider fields as implicitly | 649 // functions of a class, so we do not need to consider fields as implicitly |
| 708 // generating getters and setters. | 650 // generating getters and setters. |
| 709 // The only compile errors we report are therefore: | 651 // The only compile errors we report are therefore: |
| 710 // - a getter having the same name as a method (but not a getter) in a super | 652 // - a getter having the same name as a method (but not a getter) in a super |
| 711 // class or in a subclass. | 653 // class or in a subclass. |
| 712 // - a setter having the same name as a method (but not a setter) in a super | 654 // - a setter having the same name as a method (but not a setter) in a super |
| 713 // class or in a subclass. | 655 // class or in a subclass. |
| 714 // - a static field, instance field, or static method (but not an instance | 656 // - 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... |
| 828 const String& super_class_name = String::Handle(super_class.Name()); | 770 const String& super_class_name = String::Handle(super_class.Name()); |
| 829 ReportError("function '%s' of class '%s' conflicts with " | 771 ReportError("function '%s' of class '%s' conflicts with " |
| 830 "setter '%s' of super class '%s'.\n", | 772 "setter '%s' of super class '%s'.\n", |
| 831 function_name.ToCString(), | 773 function_name.ToCString(), |
| 832 class_name.ToCString(), | 774 class_name.ToCString(), |
| 833 function_name.ToCString(), | 775 function_name.ToCString(), |
| 834 super_class_name.ToCString()); | 776 super_class_name.ToCString()); |
| 835 } | 777 } |
| 836 } | 778 } |
| 837 } | 779 } |
| 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 } |
| 838 } | 787 } |
| 839 | 788 |
| 840 | 789 |
| 841 void ClassFinalizer::FinalizeClass(const Class& cls) { | 790 void ClassFinalizer::FinalizeClass(const Class& cls) { |
| 842 if (cls.is_finalized()) { | 791 if (cls.is_finalized()) { |
| 843 return; | 792 return; |
| 844 } | 793 } |
| 845 if (FLAG_trace_class_finalization) { | 794 if (FLAG_trace_class_finalization) { |
| 846 OS::Print("Finalize %s\n", cls.ToCString()); | 795 OS::Print("Finalize %s\n", cls.ToCString()); |
| 847 } | 796 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 877 } | 826 } |
| 878 } | 827 } |
| 879 // Finalize interface types (but not necessarily interface classes). | 828 // Finalize interface types (but not necessarily interface classes). |
| 880 Array& interface_types = Array::Handle(cls.interfaces()); | 829 Array& interface_types = Array::Handle(cls.interfaces()); |
| 881 Type& interface_type = Type::Handle(); | 830 Type& interface_type = Type::Handle(); |
| 882 for (intptr_t i = 0; i < interface_types.Length(); i++) { | 831 for (intptr_t i = 0; i < interface_types.Length(); i++) { |
| 883 interface_type ^= interface_types.At(i); | 832 interface_type ^= interface_types.At(i); |
| 884 interface_type = FinalizeType(interface_type); | 833 interface_type = FinalizeType(interface_type); |
| 885 interface_types.SetAt(i, interface_type); | 834 interface_types.SetAt(i, interface_type); |
| 886 } | 835 } |
| 887 // Mark as finalized before resolving type parameter upper bounds and member | 836 // Mark as finalized before resolving member types in order to break cycles. |
| 888 // types in order to break cycles. | |
| 889 cls.Finalize(); | 837 cls.Finalize(); |
| 890 ResolveAndFinalizeUpperBounds(cls); | |
| 891 ResolveAndFinalizeMemberTypes(cls); | 838 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 | |
| 906 // Run additional checks after all types are finalized. | 839 // Run additional checks after all types are finalized. |
| 907 if (cls.is_const()) { | 840 if (cls.is_const()) { |
| 908 CheckForLegalConstClass(cls); | 841 CheckForLegalConstClass(cls); |
| 909 } | 842 } |
| 910 } | 843 } |
| 911 | 844 |
| 912 | 845 |
| 913 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { | 846 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { |
| 914 Class& test1 = Class::Handle(cls.raw()); | 847 Class& test1 = Class::Handle(cls.raw()); |
| 915 Class& test2 = Class::Handle(cls.SuperClass()); | 848 Class& test2 = Class::Handle(cls.SuperClass()); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1024 interface.IsNumberInterface() || | 957 interface.IsNumberInterface() || |
| 1025 interface.IsIntInterface() || | 958 interface.IsIntInterface() || |
| 1026 interface.IsDoubleInterface() || | 959 interface.IsDoubleInterface() || |
| 1027 interface.IsStringInterface() || | 960 interface.IsStringInterface() || |
| 1028 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || | 961 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || |
| 1029 interface.IsDynamicType()) { | 962 interface.IsDynamicType()) { |
| 1030 ReportError("'%s' is not allowed to extend or implement '%s'\n", | 963 ReportError("'%s' is not allowed to extend or implement '%s'\n", |
| 1031 String::Handle(cls.Name()).ToCString(), | 964 String::Handle(cls.Name()).ToCString(), |
| 1032 String::Handle(interface_class.Name()).ToCString()); | 965 String::Handle(interface_class.Name()).ToCString()); |
| 1033 } | 966 } |
| 967 // TODO(regis): We also need to prevent extending classes Smi, Mint, |
| 968 // BigInt, Double, OneByteString, TwoByteString, FourByteString. |
| 1034 } | 969 } |
| 1035 // Now resolve the super interfaces. | 970 // Now resolve the super interfaces. |
| 1036 ResolveInterfaces(interface_class, visited); | 971 ResolveInterfaces(interface_class, visited); |
| 1037 } | 972 } |
| 1038 visited->RemoveLast(); | 973 visited->RemoveLast(); |
| 1039 } | 974 } |
| 1040 | 975 |
| 1041 | 976 |
| 1042 // A class is marked as constant if it has one constant constructor. | 977 // A class is marked as constant if it has one constant constructor. |
| 1043 // A constant class: | 978 // A constant class: |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1149 ASSERT(msg_buffer != NULL); | 1084 ASSERT(msg_buffer != NULL); |
| 1150 va_list args; | 1085 va_list args; |
| 1151 va_start(args, format); | 1086 va_start(args, format); |
| 1152 OS::VSNPrint(msg_buffer, kBufferLength, format, args); | 1087 OS::VSNPrint(msg_buffer, kBufferLength, format, args); |
| 1153 va_end(args); | 1088 va_end(args); |
| 1154 isolate->long_jump_base()->Jump(1, msg_buffer); | 1089 isolate->long_jump_base()->Jump(1, msg_buffer); |
| 1155 UNREACHABLE(); | 1090 UNREACHABLE(); |
| 1156 } | 1091 } |
| 1157 | 1092 |
| 1158 } // namespace dart | 1093 } // namespace dart |
| OLD | NEW |