| 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, trace_type_finalization, false, "Trace type finalization."); |
| 17 DEFINE_FLAG(bool, verify_implements, false, | 18 DEFINE_FLAG(bool, verify_implements, false, |
| 18 "Verify that all classes implement their interface."); | 19 "Verify that all classes implement their interface."); |
| 19 DECLARE_FLAG(bool, enable_type_checks); | 20 DECLARE_FLAG(bool, enable_type_checks); |
| 20 | 21 |
| 21 void ClassFinalizer::AddPendingClasses( | 22 void ClassFinalizer::AddPendingClasses( |
| 22 const GrowableArray<const Class*>& classes) { | 23 const GrowableArray<const Class*>& classes) { |
| 23 if (!classes.is_empty()) { | 24 if (!classes.is_empty()) { |
| 24 ObjectStore* object_store = Isolate::Current()->object_store(); | 25 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 25 const Array& old_array = Array::Handle(object_store->pending_classes()); | 26 const Array& old_array = Array::Handle(object_store->pending_classes()); |
| 26 const intptr_t old_length = old_array.Length(); | 27 const intptr_t old_length = old_array.Length(); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 OS::PrintErr("Could not verify bootstrap classes : %s\n", err.ToCString()); | 236 OS::PrintErr("Could not verify bootstrap classes : %s\n", err.ToCString()); |
| 236 OS::Exit(255); | 237 OS::Exit(255); |
| 237 } | 238 } |
| 238 if (FLAG_trace_class_finalization) { | 239 if (FLAG_trace_class_finalization) { |
| 239 OS::Print("VerifyBootstrapClasses END.\n"); | 240 OS::Print("VerifyBootstrapClasses END.\n"); |
| 240 } | 241 } |
| 241 Isolate::Current()->heap()->Verify(); | 242 Isolate::Current()->heap()->Verify(); |
| 242 } | 243 } |
| 243 | 244 |
| 244 | 245 |
| 246 // Resolve unresolved_class in the library of cls. |
| 247 RawClass* ClassFinalizer::ResolveClass( |
| 248 const Class& cls, const UnresolvedClass& unresolved_class) { |
| 249 Library& lib = Library::Handle(); |
| 250 if (unresolved_class.qualifier() == String::null()) { |
| 251 lib = cls.library(); |
| 252 } else { |
| 253 const String& qualifier = String::Handle(unresolved_class.qualifier()); |
| 254 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(); |
| 255 lib_prefix = cls.LookupLibraryPrefix(qualifier); |
| 256 if (lib_prefix.IsNull()) { |
| 257 const Script& script = Script::Handle(cls.script()); |
| 258 ReportError(script, unresolved_class.token_index(), |
| 259 "cannot resolve library prefix '%s' from '%s'.\n", |
| 260 String::Handle(unresolved_class.Name()).ToCString(), |
| 261 String::Handle(cls.Name()).ToCString()); |
| 262 } |
| 263 lib = lib_prefix.library(); |
| 264 } |
| 265 ASSERT(!lib.IsNull()); |
| 266 const String& class_name = String::Handle(unresolved_class.ident()); |
| 267 const Class& resolved_class = Class::Handle(lib.LookupClass(class_name)); |
| 268 if (resolved_class.IsNull()) { |
| 269 const Script& script = Script::Handle(cls.script()); |
| 270 ReportError(script, unresolved_class.token_index(), |
| 271 "cannot resolve class name '%s' from '%s'.\n", |
| 272 String::Handle(unresolved_class.Name()).ToCString(), |
| 273 String::Handle(cls.Name()).ToCString()); |
| 274 } |
| 275 return resolved_class.raw(); |
| 276 } |
| 277 |
| 278 |
| 245 // Resolve unresolved superclasses (String -> Class). | 279 // Resolve unresolved superclasses (String -> Class). |
| 246 void ClassFinalizer::ResolveSuperClass(const Class& cls) { | 280 void ClassFinalizer::ResolveSuperClass(const Class& cls) { |
| 247 if (cls.is_finalized()) { | 281 if (cls.is_finalized()) { |
| 248 return; | 282 return; |
| 249 } | 283 } |
| 250 Type& super_type = Type::Handle(cls.super_type()); | 284 Type& super_type = Type::Handle(cls.super_type()); |
| 251 if (super_type.IsNull()) { | 285 if (super_type.IsNull()) { |
| 252 return; | 286 return; |
| 253 } | 287 } |
| 254 // Resolve failures lead to a longjmp. | 288 // Resolve failures lead to a longjmp. |
| 255 super_type = ResolveType(cls, super_type); | 289 super_type = ResolveType(cls, super_type); |
| 290 if (super_type.IsTypeParameter()) { |
| 291 String& class_name = String::Handle(cls.Name()); |
| 292 String& type_parameter_name = String::Handle(super_type.Name()); |
| 293 ReportError("'%s' cannot extend or implement type parameter '%s'.\n", |
| 294 class_name.ToCString(), |
| 295 type_parameter_name.ToCString()); |
| 296 } |
| 256 cls.set_super_type(super_type); | 297 cls.set_super_type(super_type); |
| 257 const Class& super_class = Class::Handle(super_type.type_class()); | 298 const Class& super_class = Class::Handle(super_type.type_class()); |
| 258 if (cls.is_interface() != super_class.is_interface()) { | 299 if (cls.is_interface() != super_class.is_interface()) { |
| 259 String& class_name = String::Handle(cls.Name()); | 300 String& class_name = String::Handle(cls.Name()); |
| 260 String& super_class_name = String::Handle(super_class.Name()); | 301 String& super_class_name = String::Handle(super_class.Name()); |
| 261 ReportError("class '%s' and superclass '%s' are not " | 302 ReportError("class '%s' and superclass '%s' are not " |
| 262 "both classes or both interfaces.\n", | 303 "both classes or both interfaces.\n", |
| 263 class_name.ToCString(), | 304 class_name.ToCString(), |
| 264 super_class_name.ToCString()); | 305 super_class_name.ToCString()); |
| 265 } | 306 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 ReportError("default clause of interface '%s' does not name a class\n", | 360 ReportError("default clause of interface '%s' does not name a class\n", |
| 320 interface_name.ToCString()); | 361 interface_name.ToCString()); |
| 321 } | 362 } |
| 322 } | 363 } |
| 323 | 364 |
| 324 | 365 |
| 325 RawType* ClassFinalizer::ResolveType(const Class& cls, const Type& type) { | 366 RawType* ClassFinalizer::ResolveType(const Class& cls, const Type& type) { |
| 326 if (type.IsResolved()) { | 367 if (type.IsResolved()) { |
| 327 return type.raw(); | 368 return type.raw(); |
| 328 } | 369 } |
| 370 if (FLAG_trace_type_finalization) { |
| 371 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); |
| 372 } |
| 329 | 373 |
| 330 // Resolve the type class. | 374 // Resolve the type class. |
| 331 if (!type.HasResolvedTypeClass()) { | 375 if (!type.HasResolvedTypeClass()) { |
| 332 const UnresolvedClass& unresolved_class = | 376 const UnresolvedClass& unresolved_class = |
| 333 UnresolvedClass::Handle(type.unresolved_class()); | 377 UnresolvedClass::Handle(type.unresolved_class()); |
| 334 const String& type_class_name = String::Handle(unresolved_class.ident()); | 378 const String& type_class_name = String::Handle(unresolved_class.ident()); |
| 335 | 379 |
| 336 // The type class name may be a type parameter of cls that was not resolved | 380 // The type class name may be a type parameter of cls that was not resolved |
| 337 // by the parser because it appeared as part of the declaration | 381 // by the parser because it appeared as part of the declaration |
| 338 // as T1 in B<T1, T2 extends A<T1>> or | 382 // as T1 in B<T1, T2 extends A<T1>> or |
| 339 // as T2 in B<T1 extends A<T2>, T2>>. | 383 // as T2 in B<T1 extends A<T2>, T2>>. |
| 340 const TypeParameter& type_parameter = TypeParameter::Handle( | 384 const TypeParameter& type_parameter = TypeParameter::Handle( |
| 341 cls.LookupTypeParameter(type_class_name)); | 385 cls.LookupTypeParameter(type_class_name)); |
| 342 if (!type_parameter.IsNull()) { | 386 if (!type_parameter.IsNull()) { |
| 343 // No need to check for proper instance scoping, since another type | 387 // No need to check for proper instance scoping, since another type |
| 344 // parameter must be involved for the type to still be unresolved. | 388 // parameter must be involved for the type to still be unresolved. |
| 345 // The scope checking was performed for the other type parameter already. | 389 // The scope checking was performed for the other type parameter already. |
| 346 | 390 |
| 347 // A type parameter cannot be parameterized, so report an error if type | 391 // A type parameter cannot be parameterized, so report an error if type |
| 348 // arguments have previously been parsed. | 392 // arguments have previously been parsed. |
| 349 if (type.arguments() != TypeArguments::null()) { | 393 if (type.arguments() != TypeArguments::null()) { |
| 350 ReportError("type parameter '%s' cannot be parameterized", | 394 ReportError("type parameter '%s' cannot be parameterized", |
| 351 type_class_name.ToCString()); | 395 type_class_name.ToCString()); |
| 352 } | 396 } |
| 353 return type_parameter.raw(); | 397 return type_parameter.raw(); |
| 354 } | 398 } |
| 355 | 399 |
| 356 // Lookup the type class. | 400 // Lookup the type class. |
| 357 Class& type_class = Class::Handle(); | 401 const Class& type_class = |
| 358 Library& lib = Library::Handle(); | 402 Class::Handle(ResolveClass(cls, unresolved_class)); |
| 359 if (unresolved_class.qualifier() == String::null()) { | 403 |
| 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. | 404 // Replace unresolved class with resolved type class. |
| 383 ASSERT(type.IsParameterizedType()); | 405 ASSERT(type.IsParameterizedType()); |
| 384 ParameterizedType& parameterized_type = ParameterizedType::Handle(); | 406 ParameterizedType& parameterized_type = ParameterizedType::Handle(); |
| 385 parameterized_type ^= type.raw(); | 407 parameterized_type ^= type.raw(); |
| 386 parameterized_type.set_type_class(Object::Handle(type_class.raw())); | 408 parameterized_type.set_type_class(Object::Handle(type_class.raw())); |
| 387 } | 409 } |
| 388 | 410 |
| 389 // Resolve type arguments, if any. | 411 // Resolve type arguments, if any. |
| 390 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); | 412 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); |
| 391 if (!arguments.IsNull()) { | 413 if (!arguments.IsNull()) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 411 // Example: | 433 // Example: |
| 412 // Declared: class C<K, V> extends B<V> { ... } | 434 // Declared: class C<K, V> extends B<V> { ... } |
| 413 // class B<T> extends Array<int> { ... } | 435 // class B<T> extends Array<int> { ... } |
| 414 // Input: C<String, double> expressed as | 436 // Input: C<String, double> expressed as |
| 415 // cls = C, arguments = [null, null, String, double], | 437 // cls = C, arguments = [null, null, String, double], |
| 416 // i.e. cls_args = [String, double], offset = 2, length = 2. | 438 // i.e. cls_args = [String, double], offset = 2, length = 2. |
| 417 // Output: arguments = [int, double, String, double] | 439 // Output: arguments = [int, double, String, double] |
| 418 void ClassFinalizer::FinalizeTypeArguments(const Class& cls, | 440 void ClassFinalizer::FinalizeTypeArguments(const Class& cls, |
| 419 const TypeArguments& arguments) { | 441 const TypeArguments& arguments) { |
| 420 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 442 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
| 421 // If type checks are enabled, verify the subtyping constraints. | |
| 422 if (FLAG_enable_type_checks) { | |
| 423 const intptr_t num_type_params = cls.NumTypeParameters(); | |
| 424 const intptr_t offset = cls.NumTypeArguments() - num_type_params; | |
| 425 Type& type = Type::Handle(); | |
| 426 Type& type_extends = Type::Handle(); | |
| 427 const TypeArguments& extends_array = | |
| 428 TypeArguments::Handle(cls.type_parameter_extends()); | |
| 429 ASSERT((extends_array.IsNull() && (num_type_params == 0)) || | |
| 430 (extends_array.Length() == num_type_params)); | |
| 431 for (intptr_t i = 0; i < num_type_params; i++) { | |
| 432 type_extends = extends_array.TypeAt(i); | |
| 433 if (!type_extends.IsDynamicType()) { | |
| 434 type = arguments.TypeAt(offset + i); | |
| 435 if (type.IsInstantiated()) { | |
| 436 if (!type_extends.IsInstantiated()) { | |
| 437 type_extends = type_extends.InstantiateFrom(arguments, offset); | |
| 438 } | |
| 439 // TODO(regis): Where do we check the constraints when the type is | |
| 440 // generic? | |
| 441 if (!type.IsSubtypeOf(type_extends)) { | |
| 442 const String& type_name = String::Handle(type.Name()); | |
| 443 const String& extends_name = String::Handle(type_extends.Name()); | |
| 444 ReportError("type argument '%s' does not extend type '%s'\n", | |
| 445 type_name.ToCString(), | |
| 446 extends_name.ToCString()); | |
| 447 } | |
| 448 } | |
| 449 } | |
| 450 } | |
| 451 } | |
| 452 Type& super_type = Type::Handle(cls.super_type()); | 443 Type& super_type = Type::Handle(cls.super_type()); |
| 453 if (!super_type.IsNull()) { | 444 if (!super_type.IsNull()) { |
| 454 super_type = FinalizeType(super_type); | 445 super_type = FinalizeType(super_type); |
| 455 cls.set_super_type(super_type); | 446 cls.set_super_type(super_type); |
| 456 const Class& super_class = Class::Handle(super_type.type_class()); | 447 const Class& super_class = Class::Handle(super_type.type_class()); |
| 457 const TypeArguments& super_type_args = | 448 const TypeArguments& super_type_args = |
| 458 TypeArguments::Handle(super_type.arguments()); | 449 TypeArguments::Handle(super_type.arguments()); |
| 459 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 450 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| 460 const intptr_t offset = super_class.NumTypeArguments(); | 451 const intptr_t offset = super_class.NumTypeArguments(); |
| 461 const intptr_t super_offset = offset - num_super_type_params; | 452 const intptr_t super_offset = offset - num_super_type_params; |
| 462 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); | 453 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); |
| 463 Type& super_type_arg = Type::Handle(); | 454 Type& super_type_arg = Type::Handle(); |
| 464 for (intptr_t i = 0; i < num_super_type_params; i++) { | 455 for (intptr_t i = 0; i < num_super_type_params; i++) { |
| 465 super_type_arg = super_type_args.TypeAt(super_offset + i); | 456 super_type_arg = super_type_args.TypeAt(super_offset + i); |
| 466 if (!super_type_arg.IsInstantiated()) { | 457 if (!super_type_arg.IsInstantiated()) { |
| 467 super_type_arg = super_type_arg.InstantiateFrom(arguments, offset); | 458 super_type_arg = super_type_arg.InstantiateFrom(arguments, offset); |
| 468 } | 459 } |
| 469 super_type_arg = super_type_arg.Canonicalize(); | 460 super_type_arg = super_type_arg.Canonicalize(); |
| 470 arguments.SetTypeAt(super_offset + i, super_type_arg); | 461 arguments.SetTypeAt(super_offset + i, super_type_arg); |
| 471 } | 462 } |
| 472 FinalizeTypeArguments(super_class, arguments); | 463 FinalizeTypeArguments(super_class, arguments); |
| 473 } | 464 } |
| 474 } | 465 } |
| 475 | 466 |
| 476 | 467 |
| 468 // Verify the upper bounds of the type arguments of class cls. |
| 469 void ClassFinalizer::VerifyUpperBounds(const Class& cls, |
| 470 const TypeArguments& arguments) { |
| 471 ASSERT(FLAG_enable_type_checks); |
| 472 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
| 473 const intptr_t num_type_params = cls.NumTypeParameters(); |
| 474 const intptr_t offset = cls.NumTypeArguments() - num_type_params; |
| 475 Type& type = Type::Handle(); |
| 476 Type& type_extends = Type::Handle(); |
| 477 const TypeArguments& extends_array = |
| 478 TypeArguments::Handle(cls.type_parameter_extends()); |
| 479 ASSERT((extends_array.IsNull() && (num_type_params == 0)) || |
| 480 (extends_array.Length() == num_type_params)); |
| 481 for (intptr_t i = 0; i < num_type_params; i++) { |
| 482 type_extends = extends_array.TypeAt(i); |
| 483 if (!type_extends.IsDynamicType()) { |
| 484 type = arguments.TypeAt(offset + i); |
| 485 if (type.IsInstantiated()) { |
| 486 if (!type_extends.IsInstantiated()) { |
| 487 type_extends = type_extends.InstantiateFrom(arguments, offset); |
| 488 } |
| 489 // TODO(regis): Where do we check the constraints when the type is |
| 490 // generic? |
| 491 if (!type.IsSubtypeOf(type_extends)) { |
| 492 const String& type_name = String::Handle(type.Name()); |
| 493 const String& extends_name = String::Handle(type_extends.Name()); |
| 494 ReportError("type argument '%s' of class '%s' " |
| 495 "does not extend type '%s'\n", |
| 496 type_name.ToCString(), |
| 497 extends_name.ToCString()); |
| 498 } |
| 499 } |
| 500 } |
| 501 } |
| 502 Type& super_type = Type::Handle(cls.super_type()); |
| 503 if (!super_type.IsNull()) { |
| 504 ASSERT(super_type.IsFinalized()); |
| 505 const Class& super_class = Class::Handle(super_type.type_class()); |
| 506 VerifyUpperBounds(super_class, arguments); |
| 507 } |
| 508 } |
| 509 |
| 510 |
| 477 RawType* ClassFinalizer::FinalizeType(const Type& type) { | 511 RawType* ClassFinalizer::FinalizeType(const Type& type) { |
| 478 ASSERT(type.IsResolved()); | 512 ASSERT(type.IsResolved()); |
| 479 if (type.IsFinalized()) { | 513 if (type.IsFinalized()) { |
| 480 return type.raw(); | 514 return type.raw(); |
| 481 } | 515 } |
| 516 if (FLAG_trace_type_finalization) { |
| 517 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); |
| 518 } |
| 482 | 519 |
| 483 // At this point, we can only have a parameterized_type. | 520 // At this point, we can only have a parameterized_type. |
| 484 ParameterizedType& parameterized_type = ParameterizedType::Handle(); | 521 ParameterizedType& parameterized_type = ParameterizedType::Handle(); |
| 485 parameterized_type ^= type.raw(); | 522 parameterized_type ^= type.raw(); |
| 486 | 523 |
| 487 if (parameterized_type.IsBeingFinalized()) { | 524 if (parameterized_type.IsBeingFinalized()) { |
| 488 ReportError("type '%s' illegally refers to itself\n", | 525 ReportError("type '%s' illegally refers to itself\n", |
| 489 String::Handle(parameterized_type.Name()).ToCString()); | 526 String::Handle(parameterized_type.Name()).ToCString()); |
| 490 } | 527 } |
| 491 | 528 |
| 492 // Mark type as being finalized in order to detect illegal self reference. | 529 // Mark type as being finalized in order to detect illegal self reference. |
| 493 parameterized_type.set_is_being_finalized(); | 530 parameterized_type.set_is_being_finalized(); |
| 494 | 531 |
| 495 // Finalize the current type arguments of the type, which are still the | 532 // Finalize the current type arguments of the type, which are still the |
| 496 // parsed type arguments. | 533 // parsed type arguments. |
| 497 TypeArguments& arguments = | 534 TypeArguments& arguments = |
| 498 TypeArguments::Handle(parameterized_type.arguments()); | 535 TypeArguments::Handle(parameterized_type.arguments()); |
| 499 if (!arguments.IsNull()) { | 536 if (!arguments.IsNull()) { |
| 500 intptr_t num_arguments = arguments.Length(); | 537 intptr_t num_arguments = arguments.Length(); |
| 501 for (intptr_t i = 0; i < num_arguments; i++) { | 538 for (intptr_t i = 0; i < num_arguments; i++) { |
| 502 Type& type_argument = Type::Handle(arguments.TypeAt(i)); | 539 Type& type_argument = Type::Handle(arguments.TypeAt(i)); |
| 503 type_argument = FinalizeType(type_argument); | 540 type_argument = FinalizeType(type_argument); |
| 504 arguments.SetTypeAt(i, type_argument); | 541 arguments.SetTypeAt(i, type_argument); |
| 505 } | 542 } |
| 506 } | 543 } |
| 507 | 544 |
| 508 // The type class does not need to be finalized in order to finalize the type, | 545 // 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 | 546 // however, it must at least be resolved (this was done as part of resolving |
| 510 // the type itself. | 547 // the type itself, a precondition to calling FinalizeType) and the upper |
| 548 // bounds of its type parameters must be finalized (done here). |
| 511 Class& type_class = Class::Handle(parameterized_type.type_class()); | 549 Class& type_class = Class::Handle(parameterized_type.type_class()); |
| 512 | 550 |
| 551 // If the type class is a signature class, we are finalizing its signature |
| 552 // type, thereby finalizing the result type and parameter types of its |
| 553 // signature function. |
| 554 // Do this before marking this type as finalized in order to detect cycles. |
| 555 if (type_class.IsSignatureClass()) { |
| 556 // Signature classes are finalized upon creation. |
| 557 ASSERT(type_class.is_finalized()); |
| 558 // Resolve and finalize the result and parameter types of the signature |
| 559 // function of this signature class. |
| 560 ResolveAndFinalizeSignature( |
| 561 type_class, Function::Handle(type_class.signature_function())); |
| 562 } |
| 563 |
| 513 // The finalized type argument vector needs num_type_arguments types. | 564 // The finalized type argument vector needs num_type_arguments types. |
| 514 const intptr_t num_type_arguments = type_class.NumTypeArguments(); | 565 const intptr_t num_type_arguments = type_class.NumTypeArguments(); |
| 515 // The type class has num_type_parameters type parameters. | 566 // The type class has num_type_parameters type parameters. |
| 516 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 567 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 517 | 568 |
| 518 // Initialize the type argument vector. | 569 // Initialize the type argument vector. |
| 519 // Check the number of parsed type arguments, if any. | 570 // Check the number of parsed type arguments, if any. |
| 520 // Specifying no type arguments indicates a raw type, which is not an error. | 571 // 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. | 572 // However, subtyping constraints are checked below, even for a raw type. |
| 522 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 573 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 535 const intptr_t offset = num_type_arguments - num_type_parameters; | 586 const intptr_t offset = num_type_arguments - num_type_parameters; |
| 536 Type& type = Type::Handle(Type::DynamicType()); | 587 Type& type = Type::Handle(Type::DynamicType()); |
| 537 for (intptr_t i = 0; i < num_type_parameters; i++) { | 588 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 538 // If no type parameters were provided, a raw type is desired, so we | 589 // If no type parameters were provided, a raw type is desired, so we |
| 539 // create a vector of DynamicType. | 590 // create a vector of DynamicType. |
| 540 if (!arguments.IsNull()) { | 591 if (!arguments.IsNull()) { |
| 541 type = arguments.TypeAt(i); | 592 type = arguments.TypeAt(i); |
| 542 } | 593 } |
| 543 full_arguments.SetTypeAt(offset + i, type); | 594 full_arguments.SetTypeAt(offset + i, type); |
| 544 } | 595 } |
| 545 FinalizeTypeArguments(type_class, full_arguments); | 596 if (type_class.IsSignatureClass()) { |
| 597 const Function& signature_fun = |
| 598 Function::Handle(type_class.signature_function()); |
| 599 ASSERT(!signature_fun.is_static()); |
| 600 const Class& signature_fun_owner = Class::Handle(signature_fun.owner()); |
| 601 FinalizeTypeArguments(signature_fun_owner, full_arguments); |
| 602 } else { |
| 603 FinalizeTypeArguments(type_class, full_arguments); |
| 604 } |
| 546 parameterized_type.set_arguments(full_arguments); | 605 parameterized_type.set_arguments(full_arguments); |
| 606 |
| 607 // Mark the type as finalized before finalizing the upper bounds, because |
| 608 // cycles via upper bounds are legal at compile time. |
| 609 parameterized_type.set_is_finalized(); |
| 610 |
| 611 ResolveAndFinalizeUpperBounds(type_class); |
| 612 if (FLAG_enable_type_checks) { |
| 613 VerifyUpperBounds(type_class, full_arguments); |
| 614 } |
| 615 } else { |
| 616 parameterized_type.set_is_finalized(); |
| 547 } | 617 } |
| 548 | |
| 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(); | 618 return parameterized_type.Canonicalize(); |
| 557 } | 619 } |
| 558 | 620 |
| 559 | 621 |
| 560 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type, | 622 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type, |
| 561 String* errmsg) { | 623 String* errmsg) { |
| 562 Isolate* isolate = Isolate::Current(); | 624 Isolate* isolate = Isolate::Current(); |
| 563 ASSERT(isolate != NULL); | 625 ASSERT(isolate != NULL); |
| 564 LongJump* base = isolate->long_jump_base(); | 626 LongJump* base = isolate->long_jump_base(); |
| 565 LongJump jump; | 627 LongJump jump; |
| 566 isolate->set_long_jump_base(&jump); | 628 isolate->set_long_jump_base(&jump); |
| 567 if (setjmp(*jump.Set()) == 0) { | 629 if (setjmp(*jump.Set()) == 0) { |
| 568 const Type& canonical_type = Type::Handle(FinalizeType(type)); | 630 const Type& canonical_type = Type::Handle(FinalizeType(type)); |
| 569 isolate->set_long_jump_base(base); | 631 isolate->set_long_jump_base(base); |
| 570 *errmsg = String::null(); | 632 *errmsg = String::null(); |
| 571 return canonical_type.raw(); | 633 return canonical_type.raw(); |
| 572 } else { | 634 } else { |
| 573 // Error occured: Get the error message. | 635 // Error occured: Get the error message. |
| 574 isolate->set_long_jump_base(base); | 636 isolate->set_long_jump_base(base); |
| 575 *errmsg = isolate->object_store()->sticky_error(); | 637 *errmsg = isolate->object_store()->sticky_error(); |
| 576 return type.raw(); | 638 return type.raw(); |
| 577 } | 639 } |
| 578 UNREACHABLE(); | 640 UNREACHABLE(); |
| 579 return Type::null(); | 641 return Type::null(); |
| 580 } | 642 } |
| 581 | 643 |
| 582 | 644 |
| 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, | 645 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, |
| 589 const Function& function) { | 646 const Function& function) { |
| 590 // Resolve result type. | 647 // Resolve result type. |
| 591 Type& type = Type::Handle(function.result_type()); | 648 Type& type = Type::Handle(function.result_type()); |
| 592 type = ResolveType(cls, type); | 649 type = ResolveType(cls, type); |
| 593 function.set_result_type(type); | 650 function.set_result_type(type); |
| 594 type = FinalizeType(type); | 651 type = FinalizeType(type); |
| 595 function.set_result_type(type); | 652 function.set_result_type(type); |
| 596 // Resolve formal parameter types. | 653 // Resolve formal parameter types. |
| 597 const intptr_t num_parameters = function.NumberOfParameters(); | 654 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); | 694 function = super_class.LookupFunction(name); |
| 638 if (!function.IsNull()) { | 695 if (!function.IsNull()) { |
| 639 return super_class.raw(); | 696 return super_class.raw(); |
| 640 } | 697 } |
| 641 super_class = super_class.SuperClass(); | 698 super_class = super_class.SuperClass(); |
| 642 } | 699 } |
| 643 return Class::null(); | 700 return Class::null(); |
| 644 } | 701 } |
| 645 | 702 |
| 646 | 703 |
| 704 // Resolve and finalize the upper bounds of the type parameters of class cls. |
| 705 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) { |
| 706 const intptr_t num_type_params = cls.NumTypeParameters(); |
| 707 Type& type_extends = Type::Handle(); |
| 708 const TypeArguments& extends_array = |
| 709 TypeArguments::Handle(cls.type_parameter_extends()); |
| 710 ASSERT((extends_array.IsNull() && (num_type_params == 0)) || |
| 711 (extends_array.Length() == num_type_params)); |
| 712 for (intptr_t i = 0; i < num_type_params; i++) { |
| 713 type_extends = extends_array.TypeAt(i); |
| 714 type_extends = ResolveType(cls, type_extends); |
| 715 extends_array.SetTypeAt(i, type_extends); |
| 716 type_extends = FinalizeType(type_extends); |
| 717 extends_array.SetTypeAt(i, type_extends); |
| 718 } |
| 719 } |
| 720 |
| 721 |
| 647 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { | 722 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { |
| 648 // Note that getters and setters are explicitly listed as such in the list of | 723 // 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 | 724 // functions of a class, so we do not need to consider fields as implicitly |
| 650 // generating getters and setters. | 725 // generating getters and setters. |
| 651 // The only compile errors we report are therefore: | 726 // 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 | 727 // - a getter having the same name as a method (but not a getter) in a super |
| 653 // class or in a subclass. | 728 // class or in a subclass. |
| 654 // - a setter having the same name as a method (but not a setter) in a super | 729 // - a setter having the same name as a method (but not a setter) in a super |
| 655 // class or in a subclass. | 730 // class or in a subclass. |
| 656 // - a static field, instance field, or static method (but not an instance | 731 // - 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()); | 845 const String& super_class_name = String::Handle(super_class.Name()); |
| 771 ReportError("function '%s' of class '%s' conflicts with " | 846 ReportError("function '%s' of class '%s' conflicts with " |
| 772 "setter '%s' of super class '%s'.\n", | 847 "setter '%s' of super class '%s'.\n", |
| 773 function_name.ToCString(), | 848 function_name.ToCString(), |
| 774 class_name.ToCString(), | 849 class_name.ToCString(), |
| 775 function_name.ToCString(), | 850 function_name.ToCString(), |
| 776 super_class_name.ToCString()); | 851 super_class_name.ToCString()); |
| 777 } | 852 } |
| 778 } | 853 } |
| 779 } | 854 } |
| 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 } | 855 } |
| 788 | 856 |
| 789 | 857 |
| 790 void ClassFinalizer::FinalizeClass(const Class& cls) { | 858 void ClassFinalizer::FinalizeClass(const Class& cls) { |
| 791 if (cls.is_finalized()) { | 859 if (cls.is_finalized()) { |
| 792 return; | 860 return; |
| 793 } | 861 } |
| 794 if (FLAG_trace_class_finalization) { | 862 if (FLAG_trace_class_finalization) { |
| 795 OS::Print("Finalize %s\n", cls.ToCString()); | 863 OS::Print("Finalize %s\n", cls.ToCString()); |
| 796 } | 864 } |
| 865 // Signature classes are finalized upon creation. |
| 866 ASSERT(!cls.IsSignatureClass()); |
| 797 if (!IsSuperCycleFree(cls)) { | 867 if (!IsSuperCycleFree(cls)) { |
| 798 const String& name = String::Handle(cls.Name()); | 868 const String& name = String::Handle(cls.Name()); |
| 799 ReportError("class '%s' has a cycle in its superclass relationship.\n", | 869 ReportError("class '%s' has a cycle in its superclass relationship.\n", |
| 800 name.ToCString()); | 870 name.ToCString()); |
| 801 } | 871 } |
| 802 GrowableArray<const Class*> visited; | 872 GrowableArray<const Class*> visited; |
| 803 ResolveInterfaces(cls, &visited); | 873 ResolveInterfaces(cls, &visited); |
| 804 Type& super_type = Type::Handle(cls.super_type()); | 874 Type& super_type = Type::Handle(cls.super_type()); |
| 805 if (!super_type.IsNull()) { | 875 if (!super_type.IsNull()) { |
| 806 const Class& super_class = Class::Handle(super_type.type_class()); | 876 const Class& super_class = Class::Handle(super_type.type_class()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 826 } | 896 } |
| 827 } | 897 } |
| 828 // Finalize interface types (but not necessarily interface classes). | 898 // Finalize interface types (but not necessarily interface classes). |
| 829 Array& interface_types = Array::Handle(cls.interfaces()); | 899 Array& interface_types = Array::Handle(cls.interfaces()); |
| 830 Type& interface_type = Type::Handle(); | 900 Type& interface_type = Type::Handle(); |
| 831 for (intptr_t i = 0; i < interface_types.Length(); i++) { | 901 for (intptr_t i = 0; i < interface_types.Length(); i++) { |
| 832 interface_type ^= interface_types.At(i); | 902 interface_type ^= interface_types.At(i); |
| 833 interface_type = FinalizeType(interface_type); | 903 interface_type = FinalizeType(interface_type); |
| 834 interface_types.SetAt(i, interface_type); | 904 interface_types.SetAt(i, interface_type); |
| 835 } | 905 } |
| 836 // Mark as finalized before resolving member types in order to break cycles. | 906 // Mark as finalized before resolving type parameter upper bounds and member |
| 907 // types in order to break cycles. |
| 837 cls.Finalize(); | 908 cls.Finalize(); |
| 909 ResolveAndFinalizeUpperBounds(cls); |
| 838 ResolveAndFinalizeMemberTypes(cls); | 910 ResolveAndFinalizeMemberTypes(cls); |
| 839 // Run additional checks after all types are finalized. | 911 // Run additional checks after all types are finalized. |
| 840 if (cls.is_const()) { | 912 if (cls.is_const()) { |
| 841 CheckForLegalConstClass(cls); | 913 CheckForLegalConstClass(cls); |
| 842 } | 914 } |
| 843 } | 915 } |
| 844 | 916 |
| 845 | 917 |
| 846 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { | 918 bool ClassFinalizer::IsSuperCycleFree(const Class& cls) { |
| 847 Class& test1 = Class::Handle(cls.raw()); | 919 Class& test1 = Class::Handle(cls.raw()); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 interface.IsNumberInterface() || | 1029 interface.IsNumberInterface() || |
| 958 interface.IsIntInterface() || | 1030 interface.IsIntInterface() || |
| 959 interface.IsDoubleInterface() || | 1031 interface.IsDoubleInterface() || |
| 960 interface.IsStringInterface() || | 1032 interface.IsStringInterface() || |
| 961 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || | 1033 (interface.IsFunctionInterface() && !cls.IsSignatureClass()) || |
| 962 interface.IsDynamicType()) { | 1034 interface.IsDynamicType()) { |
| 963 ReportError("'%s' is not allowed to extend or implement '%s'\n", | 1035 ReportError("'%s' is not allowed to extend or implement '%s'\n", |
| 964 String::Handle(cls.Name()).ToCString(), | 1036 String::Handle(cls.Name()).ToCString(), |
| 965 String::Handle(interface_class.Name()).ToCString()); | 1037 String::Handle(interface_class.Name()).ToCString()); |
| 966 } | 1038 } |
| 967 // TODO(regis): We also need to prevent extending classes Smi, Mint, | |
| 968 // BigInt, Double, OneByteString, TwoByteString, FourByteString. | |
| 969 } | 1039 } |
| 970 // Now resolve the super interfaces. | 1040 // Now resolve the super interfaces. |
| 971 ResolveInterfaces(interface_class, visited); | 1041 ResolveInterfaces(interface_class, visited); |
| 972 } | 1042 } |
| 973 visited->RemoveLast(); | 1043 visited->RemoveLast(); |
| 974 } | 1044 } |
| 975 | 1045 |
| 976 | 1046 |
| 977 // A class is marked as constant if it has one constant constructor. | 1047 // A class is marked as constant if it has one constant constructor. |
| 978 // A constant class: | 1048 // A constant class: |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1084 ASSERT(msg_buffer != NULL); | 1154 ASSERT(msg_buffer != NULL); |
| 1085 va_list args; | 1155 va_list args; |
| 1086 va_start(args, format); | 1156 va_start(args, format); |
| 1087 OS::VSNPrint(msg_buffer, kBufferLength, format, args); | 1157 OS::VSNPrint(msg_buffer, kBufferLength, format, args); |
| 1088 va_end(args); | 1158 va_end(args); |
| 1089 isolate->long_jump_base()->Jump(1, msg_buffer); | 1159 isolate->long_jump_base()->Jump(1, msg_buffer); |
| 1090 UNREACHABLE(); | 1160 UNREACHABLE(); |
| 1091 } | 1161 } |
| 1092 | 1162 |
| 1093 } // namespace dart | 1163 } // namespace dart |
| OLD | NEW |