| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 if (FLAG_trace_class_finalization) { | 189 if (FLAG_trace_class_finalization) { |
| 190 OS::Print("VerifyBootstrapClasses START.\n"); | 190 OS::Print("VerifyBootstrapClasses START.\n"); |
| 191 } | 191 } |
| 192 ObjectStore* object_store = Isolate::Current()->object_store(); | 192 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 193 | 193 |
| 194 Class& cls = Class::Handle(); | 194 Class& cls = Class::Handle(); |
| 195 #if defined(DEBUG) | 195 #if defined(DEBUG) |
| 196 // Basic checking. | 196 // Basic checking. |
| 197 cls = object_store->object_class(); | 197 cls = object_store->object_class(); |
| 198 ASSERT(Instance::InstanceSize() == cls.instance_size()); | 198 ASSERT(Instance::InstanceSize() == cls.instance_size()); |
| 199 cls = object_store->integer_implementation_class(); |
| 200 ASSERT(Integer::InstanceSize() == cls.instance_size()); |
| 199 cls = object_store->smi_class(); | 201 cls = object_store->smi_class(); |
| 200 ASSERT(Smi::InstanceSize() == cls.instance_size()); | 202 ASSERT(Smi::InstanceSize() == cls.instance_size()); |
| 203 cls = object_store->mint_class(); |
| 204 ASSERT(Mint::InstanceSize() == cls.instance_size()); |
| 205 cls = object_store->bigint_class(); |
| 206 ASSERT(Bigint::InstanceSize() == cls.instance_size()); |
| 201 cls = object_store->one_byte_string_class(); | 207 cls = object_store->one_byte_string_class(); |
| 202 ASSERT(OneByteString::InstanceSize() == cls.instance_size()); | 208 ASSERT(OneByteString::InstanceSize() == cls.instance_size()); |
| 203 cls = object_store->two_byte_string_class(); | 209 cls = object_store->two_byte_string_class(); |
| 204 ASSERT(TwoByteString::InstanceSize() == cls.instance_size()); | 210 ASSERT(TwoByteString::InstanceSize() == cls.instance_size()); |
| 205 cls = object_store->four_byte_string_class(); | 211 cls = object_store->four_byte_string_class(); |
| 206 ASSERT(FourByteString::InstanceSize() == cls.instance_size()); | 212 ASSERT(FourByteString::InstanceSize() == cls.instance_size()); |
| 207 cls = object_store->external_one_byte_string_class(); | 213 cls = object_store->external_one_byte_string_class(); |
| 208 ASSERT(ExternalOneByteString::InstanceSize() == cls.instance_size()); | 214 ASSERT(ExternalOneByteString::InstanceSize() == cls.instance_size()); |
| 209 cls = object_store->external_two_byte_string_class(); | 215 cls = object_store->external_two_byte_string_class(); |
| 210 ASSERT(ExternalTwoByteString::InstanceSize() == cls.instance_size()); | 216 ASSERT(ExternalTwoByteString::InstanceSize() == cls.instance_size()); |
| 211 cls = object_store->external_four_byte_string_class(); | 217 cls = object_store->external_four_byte_string_class(); |
| 212 ASSERT(ExternalFourByteString::InstanceSize() == cls.instance_size()); | 218 ASSERT(ExternalFourByteString::InstanceSize() == cls.instance_size()); |
| 213 cls = object_store->double_class(); | 219 cls = object_store->double_class(); |
| 214 ASSERT(Double::InstanceSize() == cls.instance_size()); | 220 ASSERT(Double::InstanceSize() == cls.instance_size()); |
| 215 cls = object_store->mint_class(); | |
| 216 ASSERT(Mint::InstanceSize() == cls.instance_size()); | |
| 217 cls = object_store->bigint_class(); | |
| 218 ASSERT(Bigint::InstanceSize() == cls.instance_size()); | |
| 219 cls = object_store->bool_class(); | 221 cls = object_store->bool_class(); |
| 220 ASSERT(Bool::InstanceSize() == cls.instance_size()); | 222 ASSERT(Bool::InstanceSize() == cls.instance_size()); |
| 221 cls = object_store->array_class(); | 223 cls = object_store->array_class(); |
| 222 ASSERT(Array::InstanceSize() == cls.instance_size()); | 224 ASSERT(Array::InstanceSize() == cls.instance_size()); |
| 223 cls = object_store->immutable_array_class(); | 225 cls = object_store->immutable_array_class(); |
| 224 ASSERT(ImmutableArray::InstanceSize() == cls.instance_size()); | 226 ASSERT(ImmutableArray::InstanceSize() == cls.instance_size()); |
| 225 cls = object_store->uint8_array_class(); | 227 cls = object_store->uint8_array_class(); |
| 226 ASSERT(Uint8Array::InstanceSize() == cls.instance_size()); | 228 ASSERT(Uint8Array::InstanceSize() == cls.instance_size()); |
| 227 cls = object_store->int16_array_class(); | 229 cls = object_store->int16_array_class(); |
| 228 ASSERT(Int16Array::InstanceSize() == cls.instance_size()); | 230 ASSERT(Int16Array::InstanceSize() == cls.instance_size()); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 ReportError(script, cls.token_pos(), | 330 ReportError(script, cls.token_pos(), |
| 329 "class '%s' and superclass '%s' are not " | 331 "class '%s' and superclass '%s' are not " |
| 330 "both classes or both interfaces", | 332 "both classes or both interfaces", |
| 331 class_name.ToCString(), | 333 class_name.ToCString(), |
| 332 super_class_name.ToCString()); | 334 super_class_name.ToCString()); |
| 333 } | 335 } |
| 334 // If cls belongs to core lib or to core lib's implementation, restrictions | 336 // If cls belongs to core lib or to core lib's implementation, restrictions |
| 335 // about allowed interfaces are lifted. | 337 // about allowed interfaces are lifted. |
| 336 if ((cls.library() != Library::CoreLibrary()) && | 338 if ((cls.library() != Library::CoreLibrary()) && |
| 337 (cls.library() != Library::CoreImplLibrary())) { | 339 (cls.library() != Library::CoreImplLibrary())) { |
| 338 // Prevent extending core implementation classes Bool, Double, ObjectArray, | 340 // Prevent extending core implementation classes. |
| 339 // ImmutableArray, GrowableObjectArray, IntegerImplementation, Smi, Mint, | 341 switch (super_class.id()) { |
| 340 // BigInt, OneByteString, TwoByteString, FourByteString. | 342 case kInteger: |
| 341 ObjectStore* object_store = Isolate::Current()->object_store(); | 343 case kSmi: |
| 342 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); | 344 case kMint: |
| 343 const String& integer_implementation_name = | 345 case kBigint: |
| 344 String::Handle(String::NewSymbol("IntegerImplementation")); | 346 case kDouble: |
| 345 const Class& integer_implementation_class = | 347 case kOneByteString: |
| 346 Class::Handle(core_impl_lib.LookupClass(integer_implementation_name)); | 348 case kTwoByteString: |
| 347 const String& growable_object_array_name = | 349 case kFourByteString: |
| 348 String::Handle(String::NewSymbol("GrowableObjectArray")); | 350 case kExternalOneByteString: |
| 349 const Class& growable_object_array_class = | 351 case kExternalTwoByteString: |
| 350 Class::Handle(core_impl_lib.LookupClass(growable_object_array_name)); | 352 case kExternalFourByteString: |
| 351 if ((super_class.raw() == object_store->bool_class()) || | 353 case kBool: |
| 352 (super_class.raw() == object_store->double_class()) || | 354 case kArray: |
| 353 (super_class.raw() == object_store->array_class()) || | 355 case kImmutableArray: |
| 354 (super_class.raw() == object_store->immutable_array_class()) || | 356 case kGrowableObjectArray: |
| 355 (super_class.raw() == growable_object_array_class.raw()) || | 357 case kInt8Array: |
| 356 (super_class.raw() == object_store->int8_array_class()) || | 358 case kExternalInt8Array: |
| 357 (super_class.raw() == object_store->uint8_array_class()) || | 359 case kUint8Array: |
| 358 (super_class.raw() == object_store->int16_array_class()) || | 360 case kExternalUint8Array: |
| 359 (super_class.raw() == object_store->uint16_array_class()) || | 361 case kInt16Array: |
| 360 (super_class.raw() == object_store->int32_array_class()) || | 362 case kExternalInt16Array: |
| 361 (super_class.raw() == object_store->uint32_array_class()) || | 363 case kUint16Array: |
| 362 (super_class.raw() == object_store->int64_array_class()) || | 364 case kExternalUint16Array: |
| 363 (super_class.raw() == object_store->uint64_array_class()) || | 365 case kInt32Array: |
| 364 (super_class.raw() == object_store->float32_array_class()) || | 366 case kExternalInt32Array: |
| 365 (super_class.raw() == object_store->float64_array_class()) || | 367 case kUint32Array: |
| 366 (super_class.raw() == object_store->external_int8_array_class()) || | 368 case kExternalUint32Array: |
| 367 (super_class.raw() == object_store->external_uint8_array_class()) || | 369 case kInt64Array: |
| 368 (super_class.raw() == object_store->external_int16_array_class()) || | 370 case kExternalInt64Array: |
| 369 (super_class.raw() == object_store->external_uint16_array_class()) || | 371 case kUint64Array: |
| 370 (super_class.raw() == object_store->external_int32_array_class()) || | 372 case kExternalUint64Array: |
| 371 (super_class.raw() == object_store->external_uint32_array_class()) || | 373 case kFloat32Array: |
| 372 (super_class.raw() == object_store->external_int64_array_class()) || | 374 case kExternalFloat32Array: |
| 373 (super_class.raw() == object_store->external_uint64_array_class()) || | 375 case kFloat64Array: |
| 374 (super_class.raw() == object_store->external_float32_array_class()) || | 376 case kExternalFloat64Array: { |
| 375 (super_class.raw() == object_store->external_float64_array_class()) || | 377 const Script& script = Script::Handle(cls.script()); |
| 376 (super_class.raw() == integer_implementation_class.raw()) || | 378 ReportError(script, cls.token_pos(), |
| 377 (super_class.raw() == object_store->smi_class()) || | 379 "'%s' is not allowed to extend '%s'", |
| 378 (super_class.raw() == object_store->mint_class()) || | 380 String::Handle(cls.Name()).ToCString(), |
| 379 (super_class.raw() == object_store->bigint_class()) || | 381 String::Handle(super_class.Name()).ToCString()); |
| 380 (super_class.raw() == object_store->one_byte_string_class()) || | 382 break; |
| 381 (super_class.raw() == object_store->two_byte_string_class()) || | 383 } |
| 382 (super_class.raw() == object_store->four_byte_string_class())) { | 384 default: break; |
| 383 const Script& script = Script::Handle(cls.script()); | |
| 384 ReportError(script, cls.token_pos(), | |
| 385 "'%s' is not allowed to extend '%s'", | |
| 386 String::Handle(cls.Name()).ToCString(), | |
| 387 String::Handle(super_class.Name()).ToCString()); | |
| 388 } | 385 } |
| 389 } | 386 } |
| 390 return; | 387 return; |
| 391 } | 388 } |
| 392 | 389 |
| 393 | 390 |
| 394 void ClassFinalizer::ResolveFactoryClass(const Class& interface) { | 391 void ClassFinalizer::ResolveFactoryClass(const Class& interface) { |
| 395 ASSERT(interface.is_interface()); | 392 ASSERT(interface.is_interface()); |
| 396 if (interface.is_finalized() || | 393 if (interface.is_finalized() || |
| 397 !interface.HasFactoryClass() || | 394 !interface.HasFactoryClass() || |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 | 642 |
| 646 // At this point, we can only have a parameterized_type. | 643 // At this point, we can only have a parameterized_type. |
| 647 const Type& parameterized_type = Type::Cast(type); | 644 const Type& parameterized_type = Type::Cast(type); |
| 648 | 645 |
| 649 if (parameterized_type.IsBeingFinalized()) { | 646 if (parameterized_type.IsBeingFinalized()) { |
| 650 // Self reference detected. The type is malformed. | 647 // Self reference detected. The type is malformed. |
| 651 FinalizeMalformedType( | 648 FinalizeMalformedType( |
| 652 Error::Handle(), // No previous error. | 649 Error::Handle(), // No previous error. |
| 653 cls, parameterized_type, finalization, | 650 cls, parameterized_type, finalization, |
| 654 "type '%s' illegally refers to itself", | 651 "type '%s' illegally refers to itself", |
| 655 String::Handle(parameterized_type.Name()).ToCString()); | 652 String::Handle(parameterized_type.UserVisibleName()).ToCString()); |
| 656 return parameterized_type.raw(); | 653 return parameterized_type.raw(); |
| 657 } | 654 } |
| 658 | 655 |
| 659 // Mark type as being finalized in order to detect illegal self reference. | 656 // Mark type as being finalized in order to detect illegal self reference. |
| 660 parameterized_type.set_is_being_finalized(); | 657 parameterized_type.set_is_being_finalized(); |
| 661 | 658 |
| 662 // The type class does not need to be finalized in order to finalize the type, | 659 // The type class does not need to be finalized in order to finalize the type, |
| 663 // however, it must at least be resolved (this was done as part of resolving | 660 // however, it must at least be resolved (this was done as part of resolving |
| 664 // the type itself, a precondition to calling FinalizeType). | 661 // the type itself, a precondition to calling FinalizeType). |
| 665 // Also, the interfaces of the type class must be resolved and the type | 662 // Also, the interfaces of the type class must be resolved and the type |
| (...skipping 13 matching lines...) Expand all Loading... |
| 679 intptr_t num_arguments = arguments.Length(); | 676 intptr_t num_arguments = arguments.Length(); |
| 680 AbstractType& type_argument = AbstractType::Handle(); | 677 AbstractType& type_argument = AbstractType::Handle(); |
| 681 for (intptr_t i = 0; i < num_arguments; i++) { | 678 for (intptr_t i = 0; i < num_arguments; i++) { |
| 682 type_argument = arguments.TypeAt(i); | 679 type_argument = arguments.TypeAt(i); |
| 683 type_argument = FinalizeType(cls, type_argument, finalization); | 680 type_argument = FinalizeType(cls, type_argument, finalization); |
| 684 if (type_argument.IsMalformed()) { | 681 if (type_argument.IsMalformed()) { |
| 685 // In production mode, malformed type arguments are mapped to Dynamic. | 682 // In production mode, malformed type arguments are mapped to Dynamic. |
| 686 // In checked mode, a type with malformed type arguments is malformed. | 683 // In checked mode, a type with malformed type arguments is malformed. |
| 687 if (FLAG_enable_type_checks) { | 684 if (FLAG_enable_type_checks) { |
| 688 const Error& error = Error::Handle(type_argument.malformed_error()); | 685 const Error& error = Error::Handle(type_argument.malformed_error()); |
| 689 const String& type_name = String::Handle(parameterized_type.Name()); | 686 const String& type_name = |
| 687 String::Handle(parameterized_type.UserVisibleName()); |
| 690 FinalizeMalformedType(error, cls, parameterized_type, finalization, | 688 FinalizeMalformedType(error, cls, parameterized_type, finalization, |
| 691 "type '%s' has malformed type argument", | 689 "type '%s' has malformed type argument", |
| 692 type_name.ToCString()); | 690 type_name.ToCString()); |
| 693 return parameterized_type.raw(); | 691 return parameterized_type.raw(); |
| 694 } else { | 692 } else { |
| 695 type_argument = Type::DynamicType(); | 693 type_argument = Type::DynamicType(); |
| 696 } | 694 } |
| 697 } | 695 } |
| 698 arguments.SetTypeAt(i, type_argument); | 696 arguments.SetTypeAt(i, type_argument); |
| 699 } | 697 } |
| 700 } | 698 } |
| 701 | 699 |
| 702 // The finalized type argument vector needs num_type_arguments types. | 700 // The finalized type argument vector needs num_type_arguments types. |
| 703 const intptr_t num_type_arguments = type_class.NumTypeArguments(); | 701 const intptr_t num_type_arguments = type_class.NumTypeArguments(); |
| 704 // The type class has num_type_parameters type parameters. | 702 // The type class has num_type_parameters type parameters. |
| 705 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 703 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 706 | 704 |
| 707 // Initialize the type argument vector. | 705 // Initialize the type argument vector. |
| 708 // Check the number of parsed type arguments, if any. | 706 // Check the number of parsed type arguments, if any. |
| 709 // Specifying no type arguments indicates a raw type, which is not an error. | 707 // Specifying no type arguments indicates a raw type, which is not an error. |
| 710 // However, type parameter bounds are checked below, even for a raw type. | 708 // However, type parameter bounds are checked below, even for a raw type. |
| 711 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 709 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| 712 // Wrong number of type arguments. The type is malformed. | 710 // Wrong number of type arguments. The type is malformed. |
| 713 FinalizeMalformedType( | 711 FinalizeMalformedType( |
| 714 Error::Handle(), // No previous error. | 712 Error::Handle(), // No previous error. |
| 715 cls, parameterized_type, finalization, | 713 cls, parameterized_type, finalization, |
| 716 "wrong number of type arguments in type '%s'", | 714 "wrong number of type arguments in type '%s'", |
| 717 String::Handle(parameterized_type.Name()).ToCString()); | 715 String::Handle(parameterized_type.UserVisibleName()).ToCString()); |
| 718 return parameterized_type.raw(); | 716 return parameterized_type.raw(); |
| 719 } | 717 } |
| 720 // The full type argument vector consists of the type arguments of the | 718 // The full type argument vector consists of the type arguments of the |
| 721 // super types of type_class, which may be initialized from the parsed | 719 // super types of type_class, which may be initialized from the parsed |
| 722 // type arguments, followed by the parsed type arguments. | 720 // type arguments, followed by the parsed type arguments. |
| 723 TypeArguments& full_arguments = TypeArguments::Handle(); | 721 TypeArguments& full_arguments = TypeArguments::Handle(); |
| 724 if (num_type_arguments > 0) { | 722 if (num_type_arguments > 0) { |
| 725 // If no type arguments were parsed and if the super types do not prepend | 723 // If no type arguments were parsed and if the super types do not prepend |
| 726 // type arguments to the vector, we can leave the vector as null. | 724 // type arguments to the vector, we can leave the vector as null. |
| 727 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { | 725 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 // The type argument vector of the type is not within bounds. The type | 786 // The type argument vector of the type is not within bounds. The type |
| 789 // is malformed. Prepend malformed_error to new malformed type error in | 787 // is malformed. Prepend malformed_error to new malformed type error in |
| 790 // order to report both locations. | 788 // order to report both locations. |
| 791 // Note that malformed bounds never result in a compile time error, even | 789 // Note that malformed bounds never result in a compile time error, even |
| 792 // in checked mode. Therefore, overwrite finalization with kFinalize | 790 // in checked mode. Therefore, overwrite finalization with kFinalize |
| 793 // when finalizing the malformed type. | 791 // when finalizing the malformed type. |
| 794 FinalizeMalformedType( | 792 FinalizeMalformedType( |
| 795 malformed_error, | 793 malformed_error, |
| 796 cls, parameterized_type, kFinalize, | 794 cls, parameterized_type, kFinalize, |
| 797 "type arguments of type '%s' are not within bounds", | 795 "type arguments of type '%s' are not within bounds", |
| 798 String::Handle(parameterized_type.Name()).ToCString()); | 796 String::Handle(parameterized_type.UserVisibleName()).ToCString()); |
| 799 return parameterized_type.raw(); | 797 return parameterized_type.raw(); |
| 800 } | 798 } |
| 801 } | 799 } |
| 802 | 800 |
| 803 // If the type class is a signature class, we are currently finalizing a | 801 // If the type class is a signature class, we are currently finalizing a |
| 804 // signature type, i.e. finalizing the result type and parameter types of the | 802 // signature type, i.e. finalizing the result type and parameter types of the |
| 805 // signature function of this signature type. | 803 // signature function of this signature type. |
| 806 // We do this after marking this type as finalized in order to allow a | 804 // We do this after marking this type as finalized in order to allow a |
| 807 // function type to refer to itself via its parameter types and result type. | 805 // function type to refer to itself via its parameter types and result type. |
| 808 if (type_class.IsSignatureClass()) { | 806 if (type_class.IsSignatureClass()) { |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1505 void ClassFinalizer::ReportError(const char* format, ...) { | 1503 void ClassFinalizer::ReportError(const char* format, ...) { |
| 1506 va_list args; | 1504 va_list args; |
| 1507 va_start(args, format); | 1505 va_start(args, format); |
| 1508 const Error& error = Error::Handle( | 1506 const Error& error = Error::Handle( |
| 1509 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1507 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
| 1510 va_end(args); | 1508 va_end(args); |
| 1511 ReportError(error); | 1509 ReportError(error); |
| 1512 } | 1510 } |
| 1513 | 1511 |
| 1514 } // namespace dart | 1512 } // namespace dart |
| OLD | NEW |