| 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/object.h" | 5 #include "vm/object.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
| 10 #include "vm/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 RawArray* Object::empty_array_ = reinterpret_cast<RawArray*>(RAW_NULL); | 66 RawArray* Object::empty_array_ = reinterpret_cast<RawArray*>(RAW_NULL); |
| 67 RawInstance* Object::sentinel_ = reinterpret_cast<RawInstance*>(RAW_NULL); | 67 RawInstance* Object::sentinel_ = reinterpret_cast<RawInstance*>(RAW_NULL); |
| 68 RawInstance* Object::transition_sentinel_ = | 68 RawInstance* Object::transition_sentinel_ = |
| 69 reinterpret_cast<RawInstance*>(RAW_NULL); | 69 reinterpret_cast<RawInstance*>(RAW_NULL); |
| 70 RawClass* Object::class_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 70 RawClass* Object::class_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 71 RawClass* Object::null_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 71 RawClass* Object::null_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 72 RawClass* Object::dynamic_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 72 RawClass* Object::dynamic_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 73 RawClass* Object::void_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 73 RawClass* Object::void_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 74 RawClass* Object::unresolved_class_class_ = | 74 RawClass* Object::unresolved_class_class_ = |
| 75 reinterpret_cast<RawClass*>(RAW_NULL); | 75 reinterpret_cast<RawClass*>(RAW_NULL); |
| 76 RawClass* Object::type_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | |
| 77 RawClass* Object::type_parameter_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | |
| 78 RawClass* Object::type_arguments_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 76 RawClass* Object::type_arguments_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 79 RawClass* Object::instantiated_type_arguments_class_ = | 77 RawClass* Object::instantiated_type_arguments_class_ = |
| 80 reinterpret_cast<RawClass*>(RAW_NULL); | 78 reinterpret_cast<RawClass*>(RAW_NULL); |
| 81 RawClass* Object::patch_class_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 79 RawClass* Object::patch_class_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 82 RawClass* Object::function_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 80 RawClass* Object::function_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 83 RawClass* Object::closure_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 81 RawClass* Object::closure_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 84 RawClass* Object::redirection_data_class_ = | 82 RawClass* Object::redirection_data_class_ = |
| 85 reinterpret_cast<RawClass*>(RAW_NULL); | 83 reinterpret_cast<RawClass*>(RAW_NULL); |
| 86 RawClass* Object::field_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 84 RawClass* Object::field_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| 87 RawClass* Object::literal_token_class_ = reinterpret_cast<RawClass*>(RAW_NULL); | 85 RawClass* Object::literal_token_class_ = reinterpret_cast<RawClass*>(RAW_NULL); |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 dynamic_class_ = cls.raw(); | 309 dynamic_class_ = cls.raw(); |
| 312 | 310 |
| 313 // Allocate the remaining VM internal classes. | 311 // Allocate the remaining VM internal classes. |
| 314 cls = Class::New<UnresolvedClass>(); | 312 cls = Class::New<UnresolvedClass>(); |
| 315 unresolved_class_class_ = cls.raw(); | 313 unresolved_class_class_ = cls.raw(); |
| 316 | 314 |
| 317 cls = Class::New<Instance>(kVoidCid); | 315 cls = Class::New<Instance>(kVoidCid); |
| 318 cls.set_is_finalized(); | 316 cls.set_is_finalized(); |
| 319 void_class_ = cls.raw(); | 317 void_class_ = cls.raw(); |
| 320 | 318 |
| 321 cls = Class::New<Type>(); | |
| 322 type_class_ = cls.raw(); | |
| 323 | |
| 324 cls = Class::New<TypeParameter>(); | |
| 325 type_parameter_class_ = cls.raw(); | |
| 326 | |
| 327 cls = Class::New<TypeArguments>(); | 319 cls = Class::New<TypeArguments>(); |
| 328 type_arguments_class_ = cls.raw(); | 320 type_arguments_class_ = cls.raw(); |
| 329 | 321 |
| 330 cls = Class::New<InstantiatedTypeArguments>(); | 322 cls = Class::New<InstantiatedTypeArguments>(); |
| 331 instantiated_type_arguments_class_ = cls.raw(); | 323 instantiated_type_arguments_class_ = cls.raw(); |
| 332 | 324 |
| 333 cls = Class::New<PatchClass>(); | 325 cls = Class::New<PatchClass>(); |
| 334 patch_class_class_ = cls.raw(); | 326 patch_class_class_ = cls.raw(); |
| 335 | 327 |
| 336 cls = Class::New<Function>(); | 328 cls = Class::New<Function>(); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 void Object::RegisterSingletonClassNames() { | 428 void Object::RegisterSingletonClassNames() { |
| 437 Class& cls = Class::Handle(); | 429 Class& cls = Class::Handle(); |
| 438 String& str = String::Handle(); | 430 String& str = String::Handle(); |
| 439 | 431 |
| 440 // Set up names for all VM singleton classes. | 432 // Set up names for all VM singleton classes. |
| 441 SET_CLASS_NAME(class, Class); | 433 SET_CLASS_NAME(class, Class); |
| 442 SET_CLASS_NAME(null, Null); | 434 SET_CLASS_NAME(null, Null); |
| 443 SET_CLASS_NAME(dynamic, Dynamic); | 435 SET_CLASS_NAME(dynamic, Dynamic); |
| 444 SET_CLASS_NAME(void, Void); | 436 SET_CLASS_NAME(void, Void); |
| 445 SET_CLASS_NAME(unresolved_class, UnresolvedClass); | 437 SET_CLASS_NAME(unresolved_class, UnresolvedClass); |
| 446 SET_CLASS_NAME(type, Type); | |
| 447 SET_CLASS_NAME(type_parameter, TypeParameter); | |
| 448 SET_CLASS_NAME(type_arguments, TypeArguments); | 438 SET_CLASS_NAME(type_arguments, TypeArguments); |
| 449 SET_CLASS_NAME(instantiated_type_arguments, InstantiatedTypeArguments); | 439 SET_CLASS_NAME(instantiated_type_arguments, InstantiatedTypeArguments); |
| 450 SET_CLASS_NAME(patch_class, PatchClass); | 440 SET_CLASS_NAME(patch_class, PatchClass); |
| 451 SET_CLASS_NAME(function, Function); | 441 SET_CLASS_NAME(function, Function); |
| 452 SET_CLASS_NAME(closure_data, ClosureData); | 442 SET_CLASS_NAME(closure_data, ClosureData); |
| 453 SET_CLASS_NAME(redirection_data, RedirectionData); | 443 SET_CLASS_NAME(redirection_data, RedirectionData); |
| 454 SET_CLASS_NAME(field, Field); | 444 SET_CLASS_NAME(field, Field); |
| 455 SET_CLASS_NAME(literal_token, LiteralToken); | 445 SET_CLASS_NAME(literal_token, LiteralToken); |
| 456 SET_CLASS_NAME(token_stream, TokenStream); | 446 SET_CLASS_NAME(token_stream, TokenStream); |
| 457 SET_CLASS_NAME(script, Script); | 447 SET_CLASS_NAME(script, Script); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 // class is setup as one of its field is an array object). | 531 // class is setup as one of its field is an array object). |
| 542 cls = Class::New<GrowableObjectArray>(); | 532 cls = Class::New<GrowableObjectArray>(); |
| 543 object_store->set_growable_object_array_class(cls); | 533 object_store->set_growable_object_array_class(cls); |
| 544 cls.set_type_arguments_instance_field_offset( | 534 cls.set_type_arguments_instance_field_offset( |
| 545 GrowableObjectArray::type_arguments_offset()); | 535 GrowableObjectArray::type_arguments_offset()); |
| 546 | 536 |
| 547 // canonical_type_arguments_ are NULL terminated. | 537 // canonical_type_arguments_ are NULL terminated. |
| 548 array = Array::New(4); | 538 array = Array::New(4); |
| 549 object_store->set_canonical_type_arguments(array); | 539 object_store->set_canonical_type_arguments(array); |
| 550 | 540 |
| 541 // Setup type class early in the process. |
| 542 cls = Class::New<Type>(); |
| 543 object_store->set_type_class(cls); |
| 544 |
| 545 cls = Class::New<TypeParameter>(); |
| 546 object_store->set_type_parameter_class(cls); |
| 547 |
| 551 // Pre-allocate the OneByteString class needed by the symbol table. | 548 // Pre-allocate the OneByteString class needed by the symbol table. |
| 552 cls = Class::New<OneByteString>(); | 549 cls = Class::New<OneByteString>(); |
| 553 object_store->set_one_byte_string_class(cls); | 550 object_store->set_one_byte_string_class(cls); |
| 554 | 551 |
| 555 // Setup the symbol table for the symbols created in the isolate. | 552 // Setup the symbol table for the symbols created in the isolate. |
| 556 Symbols::SetupSymbolTable(isolate); | 553 Symbols::SetupSymbolTable(isolate); |
| 557 | 554 |
| 558 // Set up the libraries array before initializing the core library. | 555 // Set up the libraries array before initializing the core library. |
| 559 const GrowableObjectArray& libraries = | 556 const GrowableObjectArray& libraries = |
| 560 GrowableObjectArray::Handle(GrowableObjectArray::New(Heap::kOld)); | 557 GrowableObjectArray::Handle(GrowableObjectArray::New(Heap::kOld)); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 object_store->set_object_class(cls); | 658 object_store->set_object_class(cls); |
| 662 name = Symbols::Object(); | 659 name = Symbols::Object(); |
| 663 cls.set_name(name); | 660 cls.set_name(name); |
| 664 cls.set_script(script); | 661 cls.set_script(script); |
| 665 cls.set_is_prefinalized(); | 662 cls.set_is_prefinalized(); |
| 666 core_lib.AddClass(cls); | 663 core_lib.AddClass(cls); |
| 667 pending_classes.Add(cls, Heap::kOld); | 664 pending_classes.Add(cls, Heap::kOld); |
| 668 type = Type::NewNonParameterizedType(cls); | 665 type = Type::NewNonParameterizedType(cls); |
| 669 object_store->set_object_type(type); | 666 object_store->set_object_type(type); |
| 670 | 667 |
| 668 cls = object_store->type_class(); |
| 669 name = Symbols::Type(); |
| 670 RegisterPrivateClass(cls, name, core_lib); |
| 671 pending_classes.Add(cls, Heap::kOld); |
| 672 |
| 673 cls = object_store->type_parameter_class(); |
| 674 name = Symbols::TypeParameter(); |
| 675 RegisterPrivateClass(cls, name, core_lib); |
| 676 pending_classes.Add(cls, Heap::kOld); |
| 677 |
| 671 cls = Class::New<Integer>(); | 678 cls = Class::New<Integer>(); |
| 672 object_store->set_integer_implementation_class(cls); | 679 object_store->set_integer_implementation_class(cls); |
| 673 name = Symbols::IntegerImplementation(); | 680 name = Symbols::IntegerImplementation(); |
| 674 RegisterPrivateClass(cls, name, core_lib); | 681 RegisterPrivateClass(cls, name, core_lib); |
| 675 pending_classes.Add(cls, Heap::kOld); | 682 pending_classes.Add(cls, Heap::kOld); |
| 676 | 683 |
| 677 cls = Class::New<Smi>(); | 684 cls = Class::New<Smi>(); |
| 678 object_store->set_smi_class(cls); | 685 object_store->set_smi_class(cls); |
| 679 name = Symbols::Smi(); | 686 name = Symbols::Smi(); |
| 680 RegisterPrivateClass(cls, name, core_lib); | 687 RegisterPrivateClass(cls, name, core_lib); |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 990 ObjectStore* object_store = isolate->object_store(); | 997 ObjectStore* object_store = isolate->object_store(); |
| 991 | 998 |
| 992 Class& cls = Class::Handle(); | 999 Class& cls = Class::Handle(); |
| 993 | 1000 |
| 994 // Set up empty classes in the object store, these will get | 1001 // Set up empty classes in the object store, these will get |
| 995 // initialized correctly when we read from the snapshot. | 1002 // initialized correctly when we read from the snapshot. |
| 996 // This is done to allow bootstrapping of reading classes from the snapshot. | 1003 // This is done to allow bootstrapping of reading classes from the snapshot. |
| 997 cls = Class::New<Instance>(kInstanceCid); | 1004 cls = Class::New<Instance>(kInstanceCid); |
| 998 object_store->set_object_class(cls); | 1005 object_store->set_object_class(cls); |
| 999 | 1006 |
| 1007 cls = Class::New<Type>(); |
| 1008 object_store->set_type_class(cls); |
| 1009 |
| 1010 cls = Class::New<TypeParameter>(); |
| 1011 object_store->set_type_parameter_class(cls); |
| 1012 |
| 1000 cls = Class::New<Array>(); | 1013 cls = Class::New<Array>(); |
| 1001 object_store->set_array_class(cls); | 1014 object_store->set_array_class(cls); |
| 1002 | 1015 |
| 1003 cls = Class::New<ImmutableArray>(); | 1016 cls = Class::New<ImmutableArray>(); |
| 1004 object_store->set_immutable_array_class(cls); | 1017 object_store->set_immutable_array_class(cls); |
| 1005 | 1018 |
| 1006 cls = Class::New<GrowableObjectArray>(); | 1019 cls = Class::New<GrowableObjectArray>(); |
| 1007 object_store->set_growable_object_array_class(cls); | 1020 object_store->set_growable_object_array_class(cls); |
| 1008 | 1021 |
| 1009 cls = Class::New<Int8Array>(); | 1022 cls = Class::New<Int8Array>(); |
| (...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2420 return ident(); | 2433 return ident(); |
| 2421 } | 2434 } |
| 2422 } | 2435 } |
| 2423 | 2436 |
| 2424 | 2437 |
| 2425 const char* UnresolvedClass::ToCString() const { | 2438 const char* UnresolvedClass::ToCString() const { |
| 2426 return "UnresolvedClass"; | 2439 return "UnresolvedClass"; |
| 2427 } | 2440 } |
| 2428 | 2441 |
| 2429 | 2442 |
| 2430 bool AbstractType::IsResolved() const { | |
| 2431 // AbstractType is an abstract class. | |
| 2432 UNREACHABLE(); | |
| 2433 return false; | |
| 2434 } | |
| 2435 | |
| 2436 | |
| 2437 bool AbstractType::HasResolvedTypeClass() const { | |
| 2438 // AbstractType is an abstract class. | |
| 2439 UNREACHABLE(); | |
| 2440 return false; | |
| 2441 } | |
| 2442 | |
| 2443 | |
| 2444 RawClass* AbstractType::type_class() const { | |
| 2445 // AbstractType is an abstract class. | |
| 2446 UNREACHABLE(); | |
| 2447 return Class::null(); | |
| 2448 } | |
| 2449 | |
| 2450 | |
| 2451 RawUnresolvedClass* AbstractType::unresolved_class() const { | |
| 2452 // AbstractType is an abstract class. | |
| 2453 UNREACHABLE(); | |
| 2454 return UnresolvedClass::null(); | |
| 2455 } | |
| 2456 | |
| 2457 | |
| 2458 RawAbstractTypeArguments* AbstractType::arguments() const { | |
| 2459 // AbstractType is an abstract class. | |
| 2460 UNREACHABLE(); | |
| 2461 return NULL; | |
| 2462 } | |
| 2463 | |
| 2464 | |
| 2465 intptr_t AbstractType::token_pos() const { | |
| 2466 // AbstractType is an abstract class. | |
| 2467 UNREACHABLE(); | |
| 2468 return -1; | |
| 2469 } | |
| 2470 | |
| 2471 | |
| 2472 bool AbstractType::IsInstantiated() const { | |
| 2473 // AbstractType is an abstract class. | |
| 2474 UNREACHABLE(); | |
| 2475 return false; | |
| 2476 } | |
| 2477 | |
| 2478 | |
| 2479 bool AbstractType::IsFinalized() const { | |
| 2480 // AbstractType is an abstract class. | |
| 2481 UNREACHABLE(); | |
| 2482 return false; | |
| 2483 } | |
| 2484 | |
| 2485 | |
| 2486 bool AbstractType::IsBeingFinalized() const { | |
| 2487 // AbstractType is an abstract class. | |
| 2488 UNREACHABLE(); | |
| 2489 return false; | |
| 2490 } | |
| 2491 | |
| 2492 | |
| 2493 bool AbstractType::IsMalformed() const { | |
| 2494 // AbstractType is an abstract class. | |
| 2495 UNREACHABLE(); | |
| 2496 return false; | |
| 2497 } | |
| 2498 | |
| 2499 | |
| 2500 RawError* AbstractType::malformed_error() const { | |
| 2501 // AbstractType is an abstract class. | |
| 2502 UNREACHABLE(); | |
| 2503 return Error::null(); | |
| 2504 } | |
| 2505 | |
| 2506 | |
| 2507 void AbstractType::set_malformed_error(const Error& value) const { | |
| 2508 // AbstractType is an abstract class. | |
| 2509 UNREACHABLE(); | |
| 2510 } | |
| 2511 | |
| 2512 | |
| 2513 bool AbstractType::Equals(const AbstractType& other) const { | |
| 2514 // AbstractType is an abstract class. | |
| 2515 UNREACHABLE(); | |
| 2516 return false; | |
| 2517 } | |
| 2518 | |
| 2519 | |
| 2520 bool AbstractType::IsIdentical(const AbstractType& other, | |
| 2521 bool check_type_parameter_bound) const { | |
| 2522 // AbstractType is an abstract class. | |
| 2523 UNREACHABLE(); | |
| 2524 return false; | |
| 2525 } | |
| 2526 | |
| 2527 | |
| 2528 RawAbstractType* AbstractType::InstantiateFrom( | |
| 2529 const AbstractTypeArguments& instantiator_type_arguments) const { | |
| 2530 // AbstractType is an abstract class. | |
| 2531 UNREACHABLE(); | |
| 2532 return NULL; | |
| 2533 } | |
| 2534 | |
| 2535 | |
| 2536 RawAbstractType* AbstractType::Canonicalize() const { | |
| 2537 // AbstractType is an abstract class. | |
| 2538 UNREACHABLE(); | |
| 2539 return NULL; | |
| 2540 } | |
| 2541 | |
| 2542 | |
| 2543 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { | |
| 2544 if (IsTypeParameter()) { | |
| 2545 return TypeParameter::Cast(*this).name(); | |
| 2546 } | |
| 2547 // If the type is still being finalized, we may be reporting an error about | |
| 2548 // a malformed type, so proceed with caution. | |
| 2549 const AbstractTypeArguments& args = | |
| 2550 AbstractTypeArguments::Handle(arguments()); | |
| 2551 const intptr_t num_args = args.IsNull() ? 0 : args.Length(); | |
| 2552 String& class_name = String::Handle(); | |
| 2553 intptr_t first_type_param_index; | |
| 2554 intptr_t num_type_params; // Number of type parameters to print. | |
| 2555 if (HasResolvedTypeClass()) { | |
| 2556 const Class& cls = Class::Handle(type_class()); | |
| 2557 num_type_params = cls.NumTypeParameters(); // Do not print the full vector. | |
| 2558 if (name_visibility == kInternalName) { | |
| 2559 class_name = cls.Name(); | |
| 2560 } else { | |
| 2561 ASSERT(name_visibility == kUserVisibleName); | |
| 2562 // Map internal types to their corresponding public interfaces. | |
| 2563 class_name = cls.UserVisibleName(); | |
| 2564 } | |
| 2565 if (num_type_params > num_args) { | |
| 2566 first_type_param_index = 0; | |
| 2567 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) { | |
| 2568 // Most probably a malformed type. Do not fill up with "Dynamic", | |
| 2569 // but use actual vector. | |
| 2570 num_type_params = num_args; | |
| 2571 } else { | |
| 2572 ASSERT(num_args == 0); // Type is raw. | |
| 2573 // No need to fill up with "Dynamic". | |
| 2574 num_type_params = 0; | |
| 2575 } | |
| 2576 } else { | |
| 2577 first_type_param_index = num_args - num_type_params; | |
| 2578 } | |
| 2579 if (cls.IsSignatureClass()) { | |
| 2580 // We may be reporting an error about a malformed function type. In that | |
| 2581 // case, avoid instantiating the signature, since it may lead to cycles. | |
| 2582 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) { | |
| 2583 return class_name.raw(); | |
| 2584 } | |
| 2585 // In order to avoid cycles, print the name of a typedef (non-canonical | |
| 2586 // signature class) as a regular, possibly parameterized, class. | |
| 2587 if (cls.IsCanonicalSignatureClass()) { | |
| 2588 const Function& signature_function = Function::Handle( | |
| 2589 cls.signature_function()); | |
| 2590 // Signature classes have no super type. | |
| 2591 ASSERT(first_type_param_index == 0); | |
| 2592 return signature_function.InstantiatedSignatureFrom(args, | |
| 2593 name_visibility); | |
| 2594 } | |
| 2595 } | |
| 2596 } else { | |
| 2597 const UnresolvedClass& cls = UnresolvedClass::Handle(unresolved_class()); | |
| 2598 class_name = cls.Name(); | |
| 2599 num_type_params = num_args; | |
| 2600 first_type_param_index = 0; | |
| 2601 } | |
| 2602 String& type_name = String::Handle(); | |
| 2603 if (num_type_params == 0) { | |
| 2604 type_name = class_name.raw(); | |
| 2605 } else { | |
| 2606 const String& args_name = String::Handle( | |
| 2607 args.SubvectorName(first_type_param_index, | |
| 2608 num_type_params, | |
| 2609 name_visibility)); | |
| 2610 type_name = String::Concat(class_name, args_name); | |
| 2611 } | |
| 2612 // The name is only used for type checking and debugging purposes. | |
| 2613 // Unless profiling data shows otherwise, it is not worth caching the name in | |
| 2614 // the type. | |
| 2615 return Symbols::New(type_name); | |
| 2616 } | |
| 2617 | |
| 2618 | |
| 2619 RawString* AbstractType::ClassName() const { | |
| 2620 if (HasResolvedTypeClass()) { | |
| 2621 return Class::Handle(type_class()).Name(); | |
| 2622 } else { | |
| 2623 return UnresolvedClass::Handle(unresolved_class()).Name(); | |
| 2624 } | |
| 2625 } | |
| 2626 | |
| 2627 | |
| 2628 bool AbstractType::IsBoolType() const { | |
| 2629 return HasResolvedTypeClass() && | |
| 2630 (type_class() == Type::Handle(Type::BoolType()).type_class()); | |
| 2631 } | |
| 2632 | |
| 2633 | |
| 2634 bool AbstractType::IsIntType() const { | |
| 2635 return HasResolvedTypeClass() && | |
| 2636 (type_class() == Type::Handle(Type::IntType()).type_class()); | |
| 2637 } | |
| 2638 | |
| 2639 | |
| 2640 bool AbstractType::IsDoubleType() const { | |
| 2641 return HasResolvedTypeClass() && | |
| 2642 (type_class() == Type::Handle(Type::Double()).type_class()); | |
| 2643 } | |
| 2644 | |
| 2645 | |
| 2646 bool AbstractType::IsNumberType() const { | |
| 2647 return HasResolvedTypeClass() && | |
| 2648 (type_class() == Type::Handle(Type::Number()).type_class()); | |
| 2649 } | |
| 2650 | |
| 2651 | |
| 2652 bool AbstractType::IsStringInterface() const { | |
| 2653 return HasResolvedTypeClass() && | |
| 2654 (type_class() == Type::Handle(Type::StringInterface()).type_class()); | |
| 2655 } | |
| 2656 | |
| 2657 | |
| 2658 bool AbstractType::IsFunctionType() const { | |
| 2659 return HasResolvedTypeClass() && | |
| 2660 (type_class() == Type::Handle(Type::Function()).type_class()); | |
| 2661 } | |
| 2662 | |
| 2663 | |
| 2664 bool AbstractType::IsListInterface() const { | |
| 2665 return HasResolvedTypeClass() && | |
| 2666 (type_class() == Type::Handle(Type::ListInterface()).type_class()); | |
| 2667 } | |
| 2668 | |
| 2669 | |
| 2670 bool AbstractType::TypeTest(TypeTestKind test_kind, | |
| 2671 const AbstractType& other, | |
| 2672 Error* malformed_error) const { | |
| 2673 ASSERT(IsFinalized()); | |
| 2674 ASSERT(other.IsFinalized()); | |
| 2675 // In case the type checked in a type test is malformed, the code generator | |
| 2676 // may compile a throw instead of a run time call performing the type check. | |
| 2677 // However, in checked mode, a function type may include malformed result type | |
| 2678 // and/or malformed parameter types, which will then be encountered here at | |
| 2679 // run time. | |
| 2680 if (IsMalformed()) { | |
| 2681 ASSERT(FLAG_enable_type_checks); | |
| 2682 if ((malformed_error != NULL) && malformed_error->IsNull()) { | |
| 2683 *malformed_error = this->malformed_error(); | |
| 2684 } | |
| 2685 return false; | |
| 2686 } | |
| 2687 if (other.IsMalformed()) { | |
| 2688 ASSERT(FLAG_enable_type_checks); | |
| 2689 if ((malformed_error != NULL) && malformed_error->IsNull()) { | |
| 2690 *malformed_error = other.malformed_error(); | |
| 2691 } | |
| 2692 return false; | |
| 2693 } | |
| 2694 // AbstractType parameters cannot be handled by Class::TypeTest(). | |
| 2695 // When comparing two uninstantiated function types, one returning type | |
| 2696 // parameter K, the other returning type parameter V, we cannot assume that K | |
| 2697 // is a subtype of V, or vice versa. We only return true if K == V, i.e. if | |
| 2698 // they have the same index (both are finalized, so their indices are | |
| 2699 // comparable). | |
| 2700 // The same rule applies When checking the upper bound of a still | |
| 2701 // uninstantiated type at compile time. Returning false will defer the test | |
| 2702 // to run time. But there are cases where it can be decided at compile time. | |
| 2703 // For example, with class A<K, V extends K>, new A<T, T> called from within | |
| 2704 // a class B<T> will never require a run time bounds check, even it T is | |
| 2705 // uninstantiated at compile time. | |
| 2706 if (IsTypeParameter()) { | |
| 2707 const TypeParameter& type_param = TypeParameter::Cast(*this); | |
| 2708 if (other.IsTypeParameter()) { | |
| 2709 const TypeParameter& other_type_param = TypeParameter::Cast(other); | |
| 2710 return type_param.index() == other_type_param.index(); | |
| 2711 } else if (FLAG_enable_type_checks) { | |
| 2712 // In checked mode, if the upper bound of this type is more specific than | |
| 2713 // the other type, then this type is more specific than the other type. | |
| 2714 const AbstractType& type_param_bound = | |
| 2715 AbstractType::Handle(type_param.bound()); | |
| 2716 if (type_param_bound.IsMoreSpecificThan(other, malformed_error)) { | |
| 2717 return true; | |
| 2718 } | |
| 2719 } | |
| 2720 return false; | |
| 2721 } | |
| 2722 if (other.IsTypeParameter()) { | |
| 2723 return false; | |
| 2724 } | |
| 2725 const Class& cls = Class::Handle(type_class()); | |
| 2726 return cls.TypeTest(test_kind, | |
| 2727 AbstractTypeArguments::Handle(arguments()), | |
| 2728 Class::Handle(other.type_class()), | |
| 2729 AbstractTypeArguments::Handle(other.arguments()), | |
| 2730 malformed_error); | |
| 2731 } | |
| 2732 | |
| 2733 | |
| 2734 const char* AbstractType::ToCString() const { | |
| 2735 // AbstractType is an abstract class. | |
| 2736 UNREACHABLE(); | |
| 2737 return "AbstractType"; | |
| 2738 } | |
| 2739 | |
| 2740 | |
| 2741 RawType* Type::NullType() { | |
| 2742 return Isolate::Current()->object_store()->null_type(); | |
| 2743 } | |
| 2744 | |
| 2745 | |
| 2746 RawType* Type::DynamicType() { | |
| 2747 return Isolate::Current()->object_store()->dynamic_type(); | |
| 2748 } | |
| 2749 | |
| 2750 | |
| 2751 RawType* Type::VoidType() { | |
| 2752 return Isolate::Current()->object_store()->void_type(); | |
| 2753 } | |
| 2754 | |
| 2755 | |
| 2756 RawType* Type::ObjectType() { | |
| 2757 return Isolate::Current()->object_store()->object_type(); | |
| 2758 } | |
| 2759 | |
| 2760 | |
| 2761 RawType* Type::BoolType() { | |
| 2762 return Isolate::Current()->object_store()->bool_type(); | |
| 2763 } | |
| 2764 | |
| 2765 | |
| 2766 RawType* Type::IntType() { | |
| 2767 return Isolate::Current()->object_store()->int_type(); | |
| 2768 } | |
| 2769 | |
| 2770 | |
| 2771 RawType* Type::SmiType() { | |
| 2772 return Isolate::Current()->object_store()->smi_type(); | |
| 2773 } | |
| 2774 | |
| 2775 | |
| 2776 RawType* Type::MintType() { | |
| 2777 return Isolate::Current()->object_store()->mint_type(); | |
| 2778 } | |
| 2779 | |
| 2780 | |
| 2781 RawType* Type::Double() { | |
| 2782 return Isolate::Current()->object_store()->double_type(); | |
| 2783 } | |
| 2784 | |
| 2785 | |
| 2786 RawType* Type::Number() { | |
| 2787 return Isolate::Current()->object_store()->number_type(); | |
| 2788 } | |
| 2789 | |
| 2790 | |
| 2791 RawType* Type::StringInterface() { | |
| 2792 return Isolate::Current()->object_store()->string_interface(); | |
| 2793 } | |
| 2794 | |
| 2795 | |
| 2796 RawType* Type::Function() { | |
| 2797 return Isolate::Current()->object_store()->function_type(); | |
| 2798 } | |
| 2799 | |
| 2800 | |
| 2801 RawType* Type::ListInterface() { | |
| 2802 return Isolate::Current()->object_store()->list_interface(); | |
| 2803 } | |
| 2804 | |
| 2805 | |
| 2806 RawType* Type::NewNonParameterizedType( | |
| 2807 const Class& type_class) { | |
| 2808 ASSERT(!type_class.HasTypeArguments()); | |
| 2809 const TypeArguments& no_type_arguments = TypeArguments::Handle(); | |
| 2810 Type& type = Type::Handle(); | |
| 2811 type ^= Type::New(Object::Handle(type_class.raw()), | |
| 2812 no_type_arguments, | |
| 2813 Scanner::kDummyTokenIndex); | |
| 2814 type.set_is_finalized_instantiated(); | |
| 2815 type ^= type.Canonicalize(); | |
| 2816 return type.raw(); | |
| 2817 } | |
| 2818 | |
| 2819 | |
| 2820 void Type::set_is_finalized_instantiated() const { | |
| 2821 ASSERT(!IsFinalized()); | |
| 2822 set_type_state(RawType::kFinalizedInstantiated); | |
| 2823 } | |
| 2824 | |
| 2825 | |
| 2826 void Type::set_is_finalized_uninstantiated() const { | |
| 2827 ASSERT(!IsFinalized()); | |
| 2828 set_type_state(RawType::kFinalizedUninstantiated); | |
| 2829 } | |
| 2830 | |
| 2831 | |
| 2832 void Type::set_is_being_finalized() const { | |
| 2833 ASSERT(!IsFinalized() && !IsBeingFinalized()); | |
| 2834 set_type_state(RawType::kBeingFinalized); | |
| 2835 } | |
| 2836 | |
| 2837 | |
| 2838 bool Type::IsMalformed() const { | |
| 2839 return raw_ptr()->malformed_error_ != Error::null(); | |
| 2840 } | |
| 2841 | |
| 2842 | |
| 2843 void Type::set_malformed_error(const Error& value) const { | |
| 2844 StorePointer(&raw_ptr()->malformed_error_, value.raw()); | |
| 2845 } | |
| 2846 | |
| 2847 | |
| 2848 RawError* Type::malformed_error() const { | |
| 2849 ASSERT(IsMalformed()); | |
| 2850 return raw_ptr()->malformed_error_; | |
| 2851 } | |
| 2852 | |
| 2853 | |
| 2854 bool Type::IsResolved() const { | |
| 2855 if (IsFinalized()) { | |
| 2856 return true; | |
| 2857 } | |
| 2858 if (!HasResolvedTypeClass()) { | |
| 2859 return false; | |
| 2860 } | |
| 2861 const AbstractTypeArguments& args = | |
| 2862 AbstractTypeArguments::Handle(arguments()); | |
| 2863 return args.IsNull() || args.IsResolved(); | |
| 2864 } | |
| 2865 | |
| 2866 | |
| 2867 bool Type::HasResolvedTypeClass() const { | |
| 2868 const Object& type_class = Object::Handle(raw_ptr()->type_class_); | |
| 2869 return !type_class.IsNull() && type_class.IsClass(); | |
| 2870 } | |
| 2871 | |
| 2872 | |
| 2873 RawClass* Type::type_class() const { | |
| 2874 ASSERT(HasResolvedTypeClass()); | |
| 2875 Class& type_class = Class::Handle(); | |
| 2876 type_class ^= raw_ptr()->type_class_; | |
| 2877 return type_class.raw(); | |
| 2878 } | |
| 2879 | |
| 2880 | |
| 2881 RawUnresolvedClass* Type::unresolved_class() const { | |
| 2882 ASSERT(!HasResolvedTypeClass()); | |
| 2883 UnresolvedClass& unresolved_class = UnresolvedClass::Handle(); | |
| 2884 unresolved_class ^= raw_ptr()->type_class_; | |
| 2885 ASSERT(!unresolved_class.IsNull()); | |
| 2886 return unresolved_class.raw(); | |
| 2887 } | |
| 2888 | |
| 2889 | |
| 2890 RawString* Type::TypeClassName() const { | |
| 2891 if (HasResolvedTypeClass()) { | |
| 2892 const Class& cls = Class::Handle(type_class()); | |
| 2893 return cls.Name(); | |
| 2894 } else { | |
| 2895 const UnresolvedClass& cls = UnresolvedClass::Handle(unresolved_class()); | |
| 2896 return cls.Name(); | |
| 2897 } | |
| 2898 } | |
| 2899 | |
| 2900 | |
| 2901 RawAbstractTypeArguments* Type::arguments() const { | |
| 2902 return raw_ptr()->arguments_; | |
| 2903 } | |
| 2904 | |
| 2905 | |
| 2906 bool Type::IsInstantiated() const { | |
| 2907 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { | |
| 2908 return true; | |
| 2909 } | |
| 2910 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { | |
| 2911 return false; | |
| 2912 } | |
| 2913 const AbstractTypeArguments& args = | |
| 2914 AbstractTypeArguments::Handle(arguments()); | |
| 2915 return args.IsNull() || args.IsInstantiated(); | |
| 2916 } | |
| 2917 | |
| 2918 | |
| 2919 RawAbstractType* Type::InstantiateFrom( | |
| 2920 const AbstractTypeArguments& instantiator_type_arguments) const { | |
| 2921 ASSERT(IsFinalized()); | |
| 2922 ASSERT(!IsInstantiated()); | |
| 2923 AbstractTypeArguments& type_arguments = | |
| 2924 AbstractTypeArguments::Handle(arguments()); | |
| 2925 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments); | |
| 2926 const Class& cls = Class::Handle(type_class()); | |
| 2927 ASSERT(cls.is_finalized()); | |
| 2928 Type& instantiated_type = Type::Handle( | |
| 2929 Type::New(cls, type_arguments, token_pos())); | |
| 2930 ASSERT(type_arguments.IsNull() || | |
| 2931 (type_arguments.Length() == cls.NumTypeArguments())); | |
| 2932 instantiated_type.set_is_finalized_instantiated(); | |
| 2933 return instantiated_type.raw(); | |
| 2934 } | |
| 2935 | |
| 2936 | |
| 2937 bool Type::Equals(const AbstractType& other) const { | |
| 2938 ASSERT(IsFinalized() && other.IsFinalized()); | |
| 2939 if (raw() == other.raw()) { | |
| 2940 return true; | |
| 2941 } | |
| 2942 if (IsMalformed() || !other.IsType() || other.IsMalformed()) { | |
| 2943 return false; | |
| 2944 } | |
| 2945 if (type_class() != other.type_class()) { | |
| 2946 return false; | |
| 2947 } | |
| 2948 return AbstractTypeArguments::AreEqual( | |
| 2949 AbstractTypeArguments::Handle(arguments()), | |
| 2950 AbstractTypeArguments::Handle(other.arguments())); | |
| 2951 } | |
| 2952 | |
| 2953 | |
| 2954 bool Type::IsIdentical(const AbstractType& other, | |
| 2955 bool check_type_parameter_bounds) const { | |
| 2956 if (raw() == other.raw()) { | |
| 2957 return true; | |
| 2958 } | |
| 2959 if (!other.IsType()) { | |
| 2960 return false; | |
| 2961 } | |
| 2962 // Both type classes may not be resolved yet. | |
| 2963 String& name = String::Handle(TypeClassName()); | |
| 2964 String& other_name = String::Handle(Type::Cast(other).TypeClassName()); | |
| 2965 if (!name.Equals(other_name)) { | |
| 2966 return false; | |
| 2967 } | |
| 2968 return AbstractTypeArguments::AreIdentical( | |
| 2969 AbstractTypeArguments::Handle(arguments()), | |
| 2970 AbstractTypeArguments::Handle(other.arguments()), | |
| 2971 false); // Bounds are only checked at the top level. | |
| 2972 } | |
| 2973 | |
| 2974 | |
| 2975 RawAbstractType* Type::Canonicalize() const { | |
| 2976 ASSERT(IsFinalized()); | |
| 2977 if (IsCanonical() || IsMalformed()) { | |
| 2978 ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld()); | |
| 2979 return this->raw(); | |
| 2980 } | |
| 2981 const Class& cls = Class::Handle(type_class()); | |
| 2982 Array& canonical_types = Array::Handle(cls.canonical_types()); | |
| 2983 if (canonical_types.IsNull()) { | |
| 2984 // Types defined in the VM isolate are canonicalized via the object store. | |
| 2985 return this->raw(); | |
| 2986 } | |
| 2987 const intptr_t canonical_types_len = canonical_types.Length(); | |
| 2988 // Linear search to see whether this type is already present in the | |
| 2989 // list of canonicalized types. | |
| 2990 // TODO(asiva): Try to re-factor this lookup code to make sharing | |
| 2991 // easy between the 4 versions of this loop. | |
| 2992 Type& type = Type::Handle(); | |
| 2993 intptr_t index = 0; | |
| 2994 while (index < canonical_types_len) { | |
| 2995 type ^= canonical_types.At(index); | |
| 2996 if (type.IsNull()) { | |
| 2997 break; | |
| 2998 } | |
| 2999 if (!type.IsFinalized()) { | |
| 3000 ASSERT((index == 0) && cls.IsSignatureClass()); | |
| 3001 index++; | |
| 3002 continue; | |
| 3003 } | |
| 3004 if (this->Equals(type)) { | |
| 3005 return type.raw(); | |
| 3006 } | |
| 3007 index++; | |
| 3008 } | |
| 3009 // Canonicalize the type arguments. | |
| 3010 AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(arguments()); | |
| 3011 type_args = type_args.Canonicalize(); | |
| 3012 set_arguments(type_args); | |
| 3013 // The type needs to be added to the list. Grow the list if it is full. | |
| 3014 if (index == canonical_types_len) { | |
| 3015 const intptr_t kLengthIncrement = 2; // Raw and parameterized. | |
| 3016 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; | |
| 3017 const Array& new_canonical_types = | |
| 3018 Array::Handle(Array::Grow(canonical_types, new_length, Heap::kOld)); | |
| 3019 cls.set_canonical_types(new_canonical_types); | |
| 3020 new_canonical_types.SetAt(index, *this); | |
| 3021 } else { | |
| 3022 canonical_types.SetAt(index, *this); | |
| 3023 } | |
| 3024 ASSERT(IsOld()); | |
| 3025 SetCanonical(); | |
| 3026 return this->raw(); | |
| 3027 } | |
| 3028 | |
| 3029 | |
| 3030 void Type::set_type_class(const Object& value) const { | |
| 3031 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); | |
| 3032 StorePointer(&raw_ptr()->type_class_, value.raw()); | |
| 3033 } | |
| 3034 | |
| 3035 | |
| 3036 void Type::set_arguments(const AbstractTypeArguments& value) const { | |
| 3037 StorePointer(&raw_ptr()->arguments_, value.raw()); | |
| 3038 } | |
| 3039 | |
| 3040 | |
| 3041 RawType* Type::New(Heap::Space space) { | |
| 3042 ASSERT(Object::type_class() != Class::null()); | |
| 3043 RawObject* raw = Object::Allocate(Type::kClassId, | |
| 3044 Type::InstanceSize(), | |
| 3045 space); | |
| 3046 return reinterpret_cast<RawType*>(raw); | |
| 3047 } | |
| 3048 | |
| 3049 | |
| 3050 RawType* Type::New(const Object& clazz, | |
| 3051 const AbstractTypeArguments& arguments, | |
| 3052 intptr_t token_pos, | |
| 3053 Heap::Space space) { | |
| 3054 const Type& result = Type::Handle(Type::New(space)); | |
| 3055 result.set_type_class(clazz); | |
| 3056 result.set_arguments(arguments); | |
| 3057 result.set_token_pos(token_pos); | |
| 3058 result.raw_ptr()->type_state_ = RawType::kAllocated; | |
| 3059 return result.raw(); | |
| 3060 } | |
| 3061 | |
| 3062 | |
| 3063 void Type::set_token_pos(intptr_t token_pos) const { | |
| 3064 ASSERT(token_pos >= 0); | |
| 3065 raw_ptr()->token_pos_ = token_pos; | |
| 3066 } | |
| 3067 | |
| 3068 | |
| 3069 void Type::set_type_state(int8_t state) const { | |
| 3070 ASSERT((state == RawType::kAllocated) || | |
| 3071 (state == RawType::kBeingFinalized) || | |
| 3072 (state == RawType::kFinalizedInstantiated) || | |
| 3073 (state == RawType::kFinalizedUninstantiated)); | |
| 3074 raw_ptr()->type_state_ = state; | |
| 3075 } | |
| 3076 | |
| 3077 | |
| 3078 const char* Type::ToCString() const { | |
| 3079 if (IsResolved()) { | |
| 3080 const AbstractTypeArguments& type_arguments = | |
| 3081 AbstractTypeArguments::Handle(arguments()); | |
| 3082 if (type_arguments.IsNull()) { | |
| 3083 const char* format = "Type: class '%s'"; | |
| 3084 const char* class_name = | |
| 3085 String::Handle(Class::Handle(type_class()).Name()).ToCString(); | |
| 3086 intptr_t len = OS::SNPrint(NULL, 0, format, class_name) + 1; | |
| 3087 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | |
| 3088 OS::SNPrint(chars, len, format, class_name); | |
| 3089 return chars; | |
| 3090 } else { | |
| 3091 const char* format = "Type: class '%s', args:[%s]"; | |
| 3092 const char* class_name = | |
| 3093 String::Handle(Class::Handle(type_class()).Name()).ToCString(); | |
| 3094 const char* args_cstr = | |
| 3095 AbstractTypeArguments::Handle(arguments()).ToCString(); | |
| 3096 intptr_t len = OS::SNPrint(NULL, 0, format, class_name, args_cstr) + 1; | |
| 3097 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | |
| 3098 OS::SNPrint(chars, len, format, class_name, args_cstr); | |
| 3099 return chars; | |
| 3100 } | |
| 3101 } else { | |
| 3102 return "Unresolved Type"; | |
| 3103 } | |
| 3104 } | |
| 3105 | |
| 3106 | |
| 3107 void TypeParameter::set_is_finalized() const { | |
| 3108 ASSERT(!IsFinalized()); | |
| 3109 set_type_state(RawTypeParameter::kFinalizedUninstantiated); | |
| 3110 } | |
| 3111 | |
| 3112 | |
| 3113 bool TypeParameter::Equals(const AbstractType& other) const { | |
| 3114 if (raw() == other.raw()) { | |
| 3115 return true; | |
| 3116 } | |
| 3117 if (!other.IsTypeParameter()) { | |
| 3118 return false; | |
| 3119 } | |
| 3120 const TypeParameter& other_type_param = TypeParameter::Cast(other); | |
| 3121 if (IsFinalized() != other_type_param.IsFinalized()) { | |
| 3122 return false; | |
| 3123 } | |
| 3124 if (parameterized_class() != other_type_param.parameterized_class()) { | |
| 3125 return false; | |
| 3126 } | |
| 3127 if (index() != other_type_param.index()) { | |
| 3128 return false; | |
| 3129 } | |
| 3130 const String& type_param_name = String::Handle(name()); | |
| 3131 const String& other_type_param_name = String::Handle(other_type_param.name()); | |
| 3132 return type_param_name.Equals(other_type_param_name); | |
| 3133 } | |
| 3134 | |
| 3135 | |
| 3136 bool TypeParameter::IsIdentical(const AbstractType& other, | |
| 3137 bool check_type_parameter_bound) const { | |
| 3138 if (raw() == other.raw()) { | |
| 3139 return true; | |
| 3140 } | |
| 3141 if (!other.IsTypeParameter()) { | |
| 3142 return false; | |
| 3143 } | |
| 3144 const TypeParameter& other_type_param = TypeParameter::Cast(other); | |
| 3145 // IsIdentical may be called on type parameters belonging to different | |
| 3146 // classes, e.g. to an interface and to its default factory class. | |
| 3147 // Therefore, both type parameters may have different parameterized classes | |
| 3148 // and different indices. Compare the type parameter names only, and their | |
| 3149 // bounds if requested. | |
| 3150 String& type_param_name = String::Handle(name()); | |
| 3151 String& other_type_param_name = String::Handle(other_type_param.name()); | |
| 3152 if (!type_param_name.Equals(other_type_param_name)) { | |
| 3153 return false; | |
| 3154 } | |
| 3155 if (check_type_parameter_bound) { | |
| 3156 AbstractType& this_bound = AbstractType::Handle(bound()); | |
| 3157 AbstractType& other_bound = AbstractType::Handle(other_type_param.bound()); | |
| 3158 // Bounds are only checked at the top level. | |
| 3159 const bool check_type_parameter_bounds = false; | |
| 3160 if (!this_bound.IsIdentical(other_bound, check_type_parameter_bounds)) { | |
| 3161 return false; | |
| 3162 } | |
| 3163 } | |
| 3164 return true; | |
| 3165 } | |
| 3166 | |
| 3167 | |
| 3168 void TypeParameter::set_parameterized_class(const Class& value) const { | |
| 3169 // Set value may be null. | |
| 3170 StorePointer(&raw_ptr()->parameterized_class_, value.raw()); | |
| 3171 } | |
| 3172 | |
| 3173 | |
| 3174 void TypeParameter::set_index(intptr_t value) const { | |
| 3175 ASSERT(value >= 0); | |
| 3176 raw_ptr()->index_ = value; | |
| 3177 } | |
| 3178 | |
| 3179 | |
| 3180 void TypeParameter::set_name(const String& value) const { | |
| 3181 ASSERT(value.IsSymbol()); | |
| 3182 StorePointer(&raw_ptr()->name_, value.raw()); | |
| 3183 } | |
| 3184 | |
| 3185 | |
| 3186 void TypeParameter::set_bound(const AbstractType& value) const { | |
| 3187 StorePointer(&raw_ptr()->bound_, value.raw()); | |
| 3188 } | |
| 3189 | |
| 3190 RawAbstractType* TypeParameter::InstantiateFrom( | |
| 3191 const AbstractTypeArguments& instantiator_type_arguments) const { | |
| 3192 ASSERT(IsFinalized()); | |
| 3193 if (instantiator_type_arguments.IsNull()) { | |
| 3194 return Type::DynamicType(); | |
| 3195 } | |
| 3196 return instantiator_type_arguments.TypeAt(index()); | |
| 3197 } | |
| 3198 | |
| 3199 | |
| 3200 RawTypeParameter* TypeParameter::New() { | |
| 3201 ASSERT(Object::type_parameter_class() != Class::null()); | |
| 3202 RawObject* raw = Object::Allocate(TypeParameter::kClassId, | |
| 3203 TypeParameter::InstanceSize(), | |
| 3204 Heap::kOld); | |
| 3205 return reinterpret_cast<RawTypeParameter*>(raw); | |
| 3206 } | |
| 3207 | |
| 3208 | |
| 3209 RawTypeParameter* TypeParameter::New(const Class& parameterized_class, | |
| 3210 intptr_t index, | |
| 3211 const String& name, | |
| 3212 const AbstractType& bound, | |
| 3213 intptr_t token_pos) { | |
| 3214 const TypeParameter& result = TypeParameter::Handle(TypeParameter::New()); | |
| 3215 result.set_parameterized_class(parameterized_class); | |
| 3216 result.set_index(index); | |
| 3217 result.set_name(name); | |
| 3218 result.set_bound(bound); | |
| 3219 result.set_token_pos(token_pos); | |
| 3220 result.raw_ptr()->type_state_ = RawTypeParameter::kAllocated; | |
| 3221 return result.raw(); | |
| 3222 } | |
| 3223 | |
| 3224 | |
| 3225 void TypeParameter::set_token_pos(intptr_t token_pos) const { | |
| 3226 ASSERT(token_pos >= 0); | |
| 3227 raw_ptr()->token_pos_ = token_pos; | |
| 3228 } | |
| 3229 | |
| 3230 | |
| 3231 void TypeParameter::set_type_state(int8_t state) const { | |
| 3232 ASSERT((state == RawTypeParameter::kAllocated) || | |
| 3233 (state == RawTypeParameter::kBeingFinalized) || | |
| 3234 (state == RawTypeParameter::kFinalizedUninstantiated)); | |
| 3235 raw_ptr()->type_state_ = state; | |
| 3236 } | |
| 3237 | |
| 3238 | |
| 3239 const char* TypeParameter::ToCString() const { | |
| 3240 const char* format = "TypeParameter: name %s; index: %d"; | |
| 3241 const char* name_cstr = String::Handle(Name()).ToCString(); | |
| 3242 intptr_t len = OS::SNPrint(NULL, 0, format, name_cstr, index()) + 1; | |
| 3243 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | |
| 3244 OS::SNPrint(chars, len, format, name_cstr, index()); | |
| 3245 return chars; | |
| 3246 } | |
| 3247 | |
| 3248 | |
| 3249 intptr_t AbstractTypeArguments::Length() const { | 2443 intptr_t AbstractTypeArguments::Length() const { |
| 3250 // AbstractTypeArguments is an abstract class. | 2444 // AbstractTypeArguments is an abstract class. |
| 3251 UNREACHABLE(); | 2445 UNREACHABLE(); |
| 3252 return -1; | 2446 return -1; |
| 3253 } | 2447 } |
| 3254 | 2448 |
| 3255 | 2449 |
| 3256 RawAbstractType* AbstractTypeArguments::TypeAt(intptr_t index) const { | 2450 RawAbstractType* AbstractTypeArguments::TypeAt(intptr_t index) const { |
| 3257 // AbstractTypeArguments is an abstract class. | 2451 // AbstractTypeArguments is an abstract class. |
| 3258 UNREACHABLE(); | 2452 UNREACHABLE(); |
| (...skipping 5667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8926 const String& type_name = String::Handle(type.Name()); | 8120 const String& type_name = String::Handle(type.Name()); |
| 8927 // Calculate the size of the string. | 8121 // Calculate the size of the string. |
| 8928 intptr_t len = OS::SNPrint(NULL, 0, kFormat, type_name.ToCString()) + 1; | 8122 intptr_t len = OS::SNPrint(NULL, 0, kFormat, type_name.ToCString()) + 1; |
| 8929 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 8123 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 8930 OS::SNPrint(chars, len, kFormat, type_name.ToCString()); | 8124 OS::SNPrint(chars, len, kFormat, type_name.ToCString()); |
| 8931 return chars; | 8125 return chars; |
| 8932 } | 8126 } |
| 8933 } | 8127 } |
| 8934 | 8128 |
| 8935 | 8129 |
| 8130 bool AbstractType::IsResolved() const { |
| 8131 // AbstractType is an abstract class. |
| 8132 UNREACHABLE(); |
| 8133 return false; |
| 8134 } |
| 8135 |
| 8136 |
| 8137 bool AbstractType::HasResolvedTypeClass() const { |
| 8138 // AbstractType is an abstract class. |
| 8139 UNREACHABLE(); |
| 8140 return false; |
| 8141 } |
| 8142 |
| 8143 |
| 8144 RawClass* AbstractType::type_class() const { |
| 8145 // AbstractType is an abstract class. |
| 8146 UNREACHABLE(); |
| 8147 return Class::null(); |
| 8148 } |
| 8149 |
| 8150 |
| 8151 RawUnresolvedClass* AbstractType::unresolved_class() const { |
| 8152 // AbstractType is an abstract class. |
| 8153 UNREACHABLE(); |
| 8154 return UnresolvedClass::null(); |
| 8155 } |
| 8156 |
| 8157 |
| 8158 RawAbstractTypeArguments* AbstractType::arguments() const { |
| 8159 // AbstractType is an abstract class. |
| 8160 UNREACHABLE(); |
| 8161 return NULL; |
| 8162 } |
| 8163 |
| 8164 |
| 8165 intptr_t AbstractType::token_pos() const { |
| 8166 // AbstractType is an abstract class. |
| 8167 UNREACHABLE(); |
| 8168 return -1; |
| 8169 } |
| 8170 |
| 8171 |
| 8172 bool AbstractType::IsInstantiated() const { |
| 8173 // AbstractType is an abstract class. |
| 8174 UNREACHABLE(); |
| 8175 return false; |
| 8176 } |
| 8177 |
| 8178 |
| 8179 bool AbstractType::IsFinalized() const { |
| 8180 // AbstractType is an abstract class. |
| 8181 UNREACHABLE(); |
| 8182 return false; |
| 8183 } |
| 8184 |
| 8185 |
| 8186 bool AbstractType::IsBeingFinalized() const { |
| 8187 // AbstractType is an abstract class. |
| 8188 UNREACHABLE(); |
| 8189 return false; |
| 8190 } |
| 8191 |
| 8192 |
| 8193 bool AbstractType::IsMalformed() const { |
| 8194 // AbstractType is an abstract class. |
| 8195 UNREACHABLE(); |
| 8196 return false; |
| 8197 } |
| 8198 |
| 8199 |
| 8200 RawError* AbstractType::malformed_error() const { |
| 8201 // AbstractType is an abstract class. |
| 8202 UNREACHABLE(); |
| 8203 return Error::null(); |
| 8204 } |
| 8205 |
| 8206 |
| 8207 void AbstractType::set_malformed_error(const Error& value) const { |
| 8208 // AbstractType is an abstract class. |
| 8209 UNREACHABLE(); |
| 8210 } |
| 8211 |
| 8212 |
| 8213 bool AbstractType::Equals(const Instance& other) const { |
| 8214 // AbstractType is an abstract class. |
| 8215 UNREACHABLE(); |
| 8216 return false; |
| 8217 } |
| 8218 |
| 8219 |
| 8220 bool AbstractType::IsIdentical(const AbstractType& other, |
| 8221 bool check_type_parameter_bound) const { |
| 8222 // AbstractType is an abstract class. |
| 8223 UNREACHABLE(); |
| 8224 return false; |
| 8225 } |
| 8226 |
| 8227 |
| 8228 RawAbstractType* AbstractType::InstantiateFrom( |
| 8229 const AbstractTypeArguments& instantiator_type_arguments) const { |
| 8230 // AbstractType is an abstract class. |
| 8231 UNREACHABLE(); |
| 8232 return NULL; |
| 8233 } |
| 8234 |
| 8235 |
| 8236 RawAbstractType* AbstractType::Canonicalize() const { |
| 8237 // AbstractType is an abstract class. |
| 8238 UNREACHABLE(); |
| 8239 return NULL; |
| 8240 } |
| 8241 |
| 8242 |
| 8243 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { |
| 8244 if (IsTypeParameter()) { |
| 8245 return TypeParameter::Cast(*this).name(); |
| 8246 } |
| 8247 // If the type is still being finalized, we may be reporting an error about |
| 8248 // a malformed type, so proceed with caution. |
| 8249 const AbstractTypeArguments& args = |
| 8250 AbstractTypeArguments::Handle(arguments()); |
| 8251 const intptr_t num_args = args.IsNull() ? 0 : args.Length(); |
| 8252 String& class_name = String::Handle(); |
| 8253 intptr_t first_type_param_index; |
| 8254 intptr_t num_type_params; // Number of type parameters to print. |
| 8255 if (HasResolvedTypeClass()) { |
| 8256 const Class& cls = Class::Handle(type_class()); |
| 8257 num_type_params = cls.NumTypeParameters(); // Do not print the full vector. |
| 8258 if (name_visibility == kInternalName) { |
| 8259 class_name = cls.Name(); |
| 8260 } else { |
| 8261 ASSERT(name_visibility == kUserVisibleName); |
| 8262 // Map internal types to their corresponding public interfaces. |
| 8263 class_name = cls.UserVisibleName(); |
| 8264 } |
| 8265 if (num_type_params > num_args) { |
| 8266 first_type_param_index = 0; |
| 8267 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) { |
| 8268 // Most probably a malformed type. Do not fill up with "Dynamic", |
| 8269 // but use actual vector. |
| 8270 num_type_params = num_args; |
| 8271 } else { |
| 8272 ASSERT(num_args == 0); // Type is raw. |
| 8273 // No need to fill up with "Dynamic". |
| 8274 num_type_params = 0; |
| 8275 } |
| 8276 } else { |
| 8277 first_type_param_index = num_args - num_type_params; |
| 8278 } |
| 8279 if (cls.IsSignatureClass()) { |
| 8280 // We may be reporting an error about a malformed function type. In that |
| 8281 // case, avoid instantiating the signature, since it may lead to cycles. |
| 8282 if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) { |
| 8283 return class_name.raw(); |
| 8284 } |
| 8285 // In order to avoid cycles, print the name of a typedef (non-canonical |
| 8286 // signature class) as a regular, possibly parameterized, class. |
| 8287 if (cls.IsCanonicalSignatureClass()) { |
| 8288 const Function& signature_function = Function::Handle( |
| 8289 cls.signature_function()); |
| 8290 // Signature classes have no super type. |
| 8291 ASSERT(first_type_param_index == 0); |
| 8292 return signature_function.InstantiatedSignatureFrom(args, |
| 8293 name_visibility); |
| 8294 } |
| 8295 } |
| 8296 } else { |
| 8297 const UnresolvedClass& cls = UnresolvedClass::Handle(unresolved_class()); |
| 8298 class_name = cls.Name(); |
| 8299 num_type_params = num_args; |
| 8300 first_type_param_index = 0; |
| 8301 } |
| 8302 String& type_name = String::Handle(); |
| 8303 if (num_type_params == 0) { |
| 8304 type_name = class_name.raw(); |
| 8305 } else { |
| 8306 const String& args_name = String::Handle( |
| 8307 args.SubvectorName(first_type_param_index, |
| 8308 num_type_params, |
| 8309 name_visibility)); |
| 8310 type_name = String::Concat(class_name, args_name); |
| 8311 } |
| 8312 // The name is only used for type checking and debugging purposes. |
| 8313 // Unless profiling data shows otherwise, it is not worth caching the name in |
| 8314 // the type. |
| 8315 return Symbols::New(type_name); |
| 8316 } |
| 8317 |
| 8318 |
| 8319 RawString* AbstractType::ClassName() const { |
| 8320 if (HasResolvedTypeClass()) { |
| 8321 return Class::Handle(type_class()).Name(); |
| 8322 } else { |
| 8323 return UnresolvedClass::Handle(unresolved_class()).Name(); |
| 8324 } |
| 8325 } |
| 8326 |
| 8327 |
| 8328 bool AbstractType::IsBoolType() const { |
| 8329 return HasResolvedTypeClass() && |
| 8330 (type_class() == Type::Handle(Type::BoolType()).type_class()); |
| 8331 } |
| 8332 |
| 8333 |
| 8334 bool AbstractType::IsIntType() const { |
| 8335 return HasResolvedTypeClass() && |
| 8336 (type_class() == Type::Handle(Type::IntType()).type_class()); |
| 8337 } |
| 8338 |
| 8339 |
| 8340 bool AbstractType::IsDoubleType() const { |
| 8341 return HasResolvedTypeClass() && |
| 8342 (type_class() == Type::Handle(Type::Double()).type_class()); |
| 8343 } |
| 8344 |
| 8345 |
| 8346 bool AbstractType::IsNumberType() const { |
| 8347 return HasResolvedTypeClass() && |
| 8348 (type_class() == Type::Handle(Type::Number()).type_class()); |
| 8349 } |
| 8350 |
| 8351 |
| 8352 bool AbstractType::IsStringInterface() const { |
| 8353 return HasResolvedTypeClass() && |
| 8354 (type_class() == Type::Handle(Type::StringInterface()).type_class()); |
| 8355 } |
| 8356 |
| 8357 |
| 8358 bool AbstractType::IsFunctionType() const { |
| 8359 return HasResolvedTypeClass() && |
| 8360 (type_class() == Type::Handle(Type::Function()).type_class()); |
| 8361 } |
| 8362 |
| 8363 |
| 8364 bool AbstractType::IsListInterface() const { |
| 8365 return HasResolvedTypeClass() && |
| 8366 (type_class() == Type::Handle(Type::ListInterface()).type_class()); |
| 8367 } |
| 8368 |
| 8369 |
| 8370 bool AbstractType::TypeTest(TypeTestKind test_kind, |
| 8371 const AbstractType& other, |
| 8372 Error* malformed_error) const { |
| 8373 ASSERT(IsFinalized()); |
| 8374 ASSERT(other.IsFinalized()); |
| 8375 // In case the type checked in a type test is malformed, the code generator |
| 8376 // may compile a throw instead of a run time call performing the type check. |
| 8377 // However, in checked mode, a function type may include malformed result type |
| 8378 // and/or malformed parameter types, which will then be encountered here at |
| 8379 // run time. |
| 8380 if (IsMalformed()) { |
| 8381 ASSERT(FLAG_enable_type_checks); |
| 8382 if ((malformed_error != NULL) && malformed_error->IsNull()) { |
| 8383 *malformed_error = this->malformed_error(); |
| 8384 } |
| 8385 return false; |
| 8386 } |
| 8387 if (other.IsMalformed()) { |
| 8388 ASSERT(FLAG_enable_type_checks); |
| 8389 if ((malformed_error != NULL) && malformed_error->IsNull()) { |
| 8390 *malformed_error = other.malformed_error(); |
| 8391 } |
| 8392 return false; |
| 8393 } |
| 8394 // AbstractType parameters cannot be handled by Class::TypeTest(). |
| 8395 // When comparing two uninstantiated function types, one returning type |
| 8396 // parameter K, the other returning type parameter V, we cannot assume that K |
| 8397 // is a subtype of V, or vice versa. We only return true if K == V, i.e. if |
| 8398 // they have the same index (both are finalized, so their indices are |
| 8399 // comparable). |
| 8400 // The same rule applies When checking the upper bound of a still |
| 8401 // uninstantiated type at compile time. Returning false will defer the test |
| 8402 // to run time. But there are cases where it can be decided at compile time. |
| 8403 // For example, with class A<K, V extends K>, new A<T, T> called from within |
| 8404 // a class B<T> will never require a run time bounds check, even it T is |
| 8405 // uninstantiated at compile time. |
| 8406 if (IsTypeParameter()) { |
| 8407 const TypeParameter& type_param = TypeParameter::Cast(*this); |
| 8408 if (other.IsTypeParameter()) { |
| 8409 const TypeParameter& other_type_param = TypeParameter::Cast(other); |
| 8410 return type_param.index() == other_type_param.index(); |
| 8411 } else if (FLAG_enable_type_checks) { |
| 8412 // In checked mode, if the upper bound of this type is more specific than |
| 8413 // the other type, then this type is more specific than the other type. |
| 8414 const AbstractType& type_param_bound = |
| 8415 AbstractType::Handle(type_param.bound()); |
| 8416 if (type_param_bound.IsMoreSpecificThan(other, malformed_error)) { |
| 8417 return true; |
| 8418 } |
| 8419 } |
| 8420 return false; |
| 8421 } |
| 8422 if (other.IsTypeParameter()) { |
| 8423 return false; |
| 8424 } |
| 8425 const Class& cls = Class::Handle(type_class()); |
| 8426 return cls.TypeTest(test_kind, |
| 8427 AbstractTypeArguments::Handle(arguments()), |
| 8428 Class::Handle(other.type_class()), |
| 8429 AbstractTypeArguments::Handle(other.arguments()), |
| 8430 malformed_error); |
| 8431 } |
| 8432 |
| 8433 |
| 8434 const char* AbstractType::ToCString() const { |
| 8435 // AbstractType is an abstract class. |
| 8436 UNREACHABLE(); |
| 8437 return "AbstractType"; |
| 8438 } |
| 8439 |
| 8440 |
| 8441 RawType* Type::NullType() { |
| 8442 return Isolate::Current()->object_store()->null_type(); |
| 8443 } |
| 8444 |
| 8445 |
| 8446 RawType* Type::DynamicType() { |
| 8447 return Isolate::Current()->object_store()->dynamic_type(); |
| 8448 } |
| 8449 |
| 8450 |
| 8451 RawType* Type::VoidType() { |
| 8452 return Isolate::Current()->object_store()->void_type(); |
| 8453 } |
| 8454 |
| 8455 |
| 8456 RawType* Type::ObjectType() { |
| 8457 return Isolate::Current()->object_store()->object_type(); |
| 8458 } |
| 8459 |
| 8460 |
| 8461 RawType* Type::BoolType() { |
| 8462 return Isolate::Current()->object_store()->bool_type(); |
| 8463 } |
| 8464 |
| 8465 |
| 8466 RawType* Type::IntType() { |
| 8467 return Isolate::Current()->object_store()->int_type(); |
| 8468 } |
| 8469 |
| 8470 |
| 8471 RawType* Type::SmiType() { |
| 8472 return Isolate::Current()->object_store()->smi_type(); |
| 8473 } |
| 8474 |
| 8475 |
| 8476 RawType* Type::MintType() { |
| 8477 return Isolate::Current()->object_store()->mint_type(); |
| 8478 } |
| 8479 |
| 8480 |
| 8481 RawType* Type::Double() { |
| 8482 return Isolate::Current()->object_store()->double_type(); |
| 8483 } |
| 8484 |
| 8485 |
| 8486 RawType* Type::Number() { |
| 8487 return Isolate::Current()->object_store()->number_type(); |
| 8488 } |
| 8489 |
| 8490 |
| 8491 RawType* Type::StringInterface() { |
| 8492 return Isolate::Current()->object_store()->string_interface(); |
| 8493 } |
| 8494 |
| 8495 |
| 8496 RawType* Type::Function() { |
| 8497 return Isolate::Current()->object_store()->function_type(); |
| 8498 } |
| 8499 |
| 8500 |
| 8501 RawType* Type::ListInterface() { |
| 8502 return Isolate::Current()->object_store()->list_interface(); |
| 8503 } |
| 8504 |
| 8505 |
| 8506 RawType* Type::NewNonParameterizedType(const Class& type_class) { |
| 8507 ASSERT(!type_class.HasTypeArguments()); |
| 8508 const TypeArguments& no_type_arguments = TypeArguments::Handle(); |
| 8509 Type& type = Type::Handle(); |
| 8510 type ^= Type::New(Object::Handle(type_class.raw()), |
| 8511 no_type_arguments, |
| 8512 Scanner::kDummyTokenIndex); |
| 8513 type.set_is_finalized_instantiated(); |
| 8514 type ^= type.Canonicalize(); |
| 8515 return type.raw(); |
| 8516 } |
| 8517 |
| 8518 |
| 8519 void Type::set_is_finalized_instantiated() const { |
| 8520 ASSERT(!IsFinalized()); |
| 8521 set_type_state(RawType::kFinalizedInstantiated); |
| 8522 } |
| 8523 |
| 8524 |
| 8525 void Type::set_is_finalized_uninstantiated() const { |
| 8526 ASSERT(!IsFinalized()); |
| 8527 set_type_state(RawType::kFinalizedUninstantiated); |
| 8528 } |
| 8529 |
| 8530 |
| 8531 void Type::set_is_being_finalized() const { |
| 8532 ASSERT(!IsFinalized() && !IsBeingFinalized()); |
| 8533 set_type_state(RawType::kBeingFinalized); |
| 8534 } |
| 8535 |
| 8536 |
| 8537 bool Type::IsMalformed() const { |
| 8538 return raw_ptr()->malformed_error_ != Error::null(); |
| 8539 } |
| 8540 |
| 8541 |
| 8542 void Type::set_malformed_error(const Error& value) const { |
| 8543 StorePointer(&raw_ptr()->malformed_error_, value.raw()); |
| 8544 } |
| 8545 |
| 8546 |
| 8547 RawError* Type::malformed_error() const { |
| 8548 ASSERT(IsMalformed()); |
| 8549 return raw_ptr()->malformed_error_; |
| 8550 } |
| 8551 |
| 8552 |
| 8553 bool Type::IsResolved() const { |
| 8554 if (IsFinalized()) { |
| 8555 return true; |
| 8556 } |
| 8557 if (!HasResolvedTypeClass()) { |
| 8558 return false; |
| 8559 } |
| 8560 const AbstractTypeArguments& args = |
| 8561 AbstractTypeArguments::Handle(arguments()); |
| 8562 return args.IsNull() || args.IsResolved(); |
| 8563 } |
| 8564 |
| 8565 |
| 8566 bool Type::HasResolvedTypeClass() const { |
| 8567 const Object& type_class = Object::Handle(raw_ptr()->type_class_); |
| 8568 return !type_class.IsNull() && type_class.IsClass(); |
| 8569 } |
| 8570 |
| 8571 |
| 8572 RawClass* Type::type_class() const { |
| 8573 ASSERT(HasResolvedTypeClass()); |
| 8574 Class& type_class = Class::Handle(); |
| 8575 type_class ^= raw_ptr()->type_class_; |
| 8576 return type_class.raw(); |
| 8577 } |
| 8578 |
| 8579 |
| 8580 RawUnresolvedClass* Type::unresolved_class() const { |
| 8581 ASSERT(!HasResolvedTypeClass()); |
| 8582 UnresolvedClass& unresolved_class = UnresolvedClass::Handle(); |
| 8583 unresolved_class ^= raw_ptr()->type_class_; |
| 8584 ASSERT(!unresolved_class.IsNull()); |
| 8585 return unresolved_class.raw(); |
| 8586 } |
| 8587 |
| 8588 |
| 8589 RawString* Type::TypeClassName() const { |
| 8590 if (HasResolvedTypeClass()) { |
| 8591 const Class& cls = Class::Handle(type_class()); |
| 8592 return cls.Name(); |
| 8593 } else { |
| 8594 const UnresolvedClass& cls = UnresolvedClass::Handle(unresolved_class()); |
| 8595 return cls.Name(); |
| 8596 } |
| 8597 } |
| 8598 |
| 8599 |
| 8600 RawAbstractTypeArguments* Type::arguments() const { |
| 8601 return raw_ptr()->arguments_; |
| 8602 } |
| 8603 |
| 8604 |
| 8605 bool Type::IsInstantiated() const { |
| 8606 if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) { |
| 8607 return true; |
| 8608 } |
| 8609 if (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated) { |
| 8610 return false; |
| 8611 } |
| 8612 const AbstractTypeArguments& args = |
| 8613 AbstractTypeArguments::Handle(arguments()); |
| 8614 return args.IsNull() || args.IsInstantiated(); |
| 8615 } |
| 8616 |
| 8617 |
| 8618 RawAbstractType* Type::InstantiateFrom( |
| 8619 const AbstractTypeArguments& instantiator_type_arguments) const { |
| 8620 ASSERT(IsFinalized()); |
| 8621 ASSERT(!IsInstantiated()); |
| 8622 AbstractTypeArguments& type_arguments = |
| 8623 AbstractTypeArguments::Handle(arguments()); |
| 8624 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments); |
| 8625 const Class& cls = Class::Handle(type_class()); |
| 8626 ASSERT(cls.is_finalized()); |
| 8627 Type& instantiated_type = Type::Handle( |
| 8628 Type::New(cls, type_arguments, token_pos())); |
| 8629 ASSERT(type_arguments.IsNull() || |
| 8630 (type_arguments.Length() == cls.NumTypeArguments())); |
| 8631 instantiated_type.set_is_finalized_instantiated(); |
| 8632 return instantiated_type.raw(); |
| 8633 } |
| 8634 |
| 8635 |
| 8636 bool Type::Equals(const Instance& other) const { |
| 8637 if (raw() == other.raw()) { |
| 8638 return true; |
| 8639 } |
| 8640 if (!other.IsType()) { |
| 8641 return false; |
| 8642 } |
| 8643 const AbstractType& other_type = AbstractType::Cast(other); |
| 8644 ASSERT(IsFinalized() && other_type.IsFinalized()); |
| 8645 if (IsMalformed() || other_type.IsMalformed()) { |
| 8646 return false; |
| 8647 } |
| 8648 if (type_class() != other_type.type_class()) { |
| 8649 return false; |
| 8650 } |
| 8651 return AbstractTypeArguments::AreEqual( |
| 8652 AbstractTypeArguments::Handle(arguments()), |
| 8653 AbstractTypeArguments::Handle(other_type.arguments())); |
| 8654 } |
| 8655 |
| 8656 |
| 8657 bool Type::IsIdentical(const AbstractType& other, |
| 8658 bool check_type_parameter_bounds) const { |
| 8659 if (raw() == other.raw()) { |
| 8660 return true; |
| 8661 } |
| 8662 if (!other.IsType()) { |
| 8663 return false; |
| 8664 } |
| 8665 // Both type classes may not be resolved yet. |
| 8666 String& name = String::Handle(TypeClassName()); |
| 8667 String& other_name = String::Handle(Type::Cast(other).TypeClassName()); |
| 8668 if (!name.Equals(other_name)) { |
| 8669 return false; |
| 8670 } |
| 8671 return AbstractTypeArguments::AreIdentical( |
| 8672 AbstractTypeArguments::Handle(arguments()), |
| 8673 AbstractTypeArguments::Handle(other.arguments()), |
| 8674 false); // Bounds are only checked at the top level. |
| 8675 } |
| 8676 |
| 8677 |
| 8678 RawAbstractType* Type::Canonicalize() const { |
| 8679 ASSERT(IsFinalized()); |
| 8680 if (IsCanonical() || IsMalformed()) { |
| 8681 ASSERT(IsMalformed() || AbstractTypeArguments::Handle(arguments()).IsOld()); |
| 8682 return this->raw(); |
| 8683 } |
| 8684 const Class& cls = Class::Handle(type_class()); |
| 8685 Array& canonical_types = Array::Handle(cls.canonical_types()); |
| 8686 if (canonical_types.IsNull()) { |
| 8687 // Types defined in the VM isolate are canonicalized via the object store. |
| 8688 return this->raw(); |
| 8689 } |
| 8690 const intptr_t canonical_types_len = canonical_types.Length(); |
| 8691 // Linear search to see whether this type is already present in the |
| 8692 // list of canonicalized types. |
| 8693 // TODO(asiva): Try to re-factor this lookup code to make sharing |
| 8694 // easy between the 4 versions of this loop. |
| 8695 Type& type = Type::Handle(); |
| 8696 intptr_t index = 0; |
| 8697 while (index < canonical_types_len) { |
| 8698 type ^= canonical_types.At(index); |
| 8699 if (type.IsNull()) { |
| 8700 break; |
| 8701 } |
| 8702 if (!type.IsFinalized()) { |
| 8703 ASSERT((index == 0) && cls.IsSignatureClass()); |
| 8704 index++; |
| 8705 continue; |
| 8706 } |
| 8707 if (this->Equals(type)) { |
| 8708 return type.raw(); |
| 8709 } |
| 8710 index++; |
| 8711 } |
| 8712 // Canonicalize the type arguments. |
| 8713 AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(arguments()); |
| 8714 type_args = type_args.Canonicalize(); |
| 8715 set_arguments(type_args); |
| 8716 // The type needs to be added to the list. Grow the list if it is full. |
| 8717 if (index == canonical_types_len) { |
| 8718 const intptr_t kLengthIncrement = 2; // Raw and parameterized. |
| 8719 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; |
| 8720 const Array& new_canonical_types = |
| 8721 Array::Handle(Array::Grow(canonical_types, new_length, Heap::kOld)); |
| 8722 cls.set_canonical_types(new_canonical_types); |
| 8723 new_canonical_types.SetAt(index, *this); |
| 8724 } else { |
| 8725 canonical_types.SetAt(index, *this); |
| 8726 } |
| 8727 ASSERT(IsOld()); |
| 8728 SetCanonical(); |
| 8729 return this->raw(); |
| 8730 } |
| 8731 |
| 8732 |
| 8733 void Type::set_type_class(const Object& value) const { |
| 8734 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); |
| 8735 StorePointer(&raw_ptr()->type_class_, value.raw()); |
| 8736 } |
| 8737 |
| 8738 |
| 8739 void Type::set_arguments(const AbstractTypeArguments& value) const { |
| 8740 StorePointer(&raw_ptr()->arguments_, value.raw()); |
| 8741 } |
| 8742 |
| 8743 |
| 8744 RawType* Type::New(Heap::Space space) { |
| 8745 ASSERT(Isolate::Current()->object_store()->type_class() != Class::null()); |
| 8746 RawObject* raw = Object::Allocate(Type::kClassId, |
| 8747 Type::InstanceSize(), |
| 8748 space); |
| 8749 return reinterpret_cast<RawType*>(raw); |
| 8750 } |
| 8751 |
| 8752 |
| 8753 RawType* Type::New(const Object& clazz, |
| 8754 const AbstractTypeArguments& arguments, |
| 8755 intptr_t token_pos, |
| 8756 Heap::Space space) { |
| 8757 const Type& result = Type::Handle(Type::New(space)); |
| 8758 result.set_type_class(clazz); |
| 8759 result.set_arguments(arguments); |
| 8760 result.set_token_pos(token_pos); |
| 8761 result.raw_ptr()->type_state_ = RawType::kAllocated; |
| 8762 return result.raw(); |
| 8763 } |
| 8764 |
| 8765 |
| 8766 void Type::set_token_pos(intptr_t token_pos) const { |
| 8767 ASSERT(token_pos >= 0); |
| 8768 raw_ptr()->token_pos_ = token_pos; |
| 8769 } |
| 8770 |
| 8771 |
| 8772 void Type::set_type_state(int8_t state) const { |
| 8773 ASSERT((state == RawType::kAllocated) || |
| 8774 (state == RawType::kBeingFinalized) || |
| 8775 (state == RawType::kFinalizedInstantiated) || |
| 8776 (state == RawType::kFinalizedUninstantiated)); |
| 8777 raw_ptr()->type_state_ = state; |
| 8778 } |
| 8779 |
| 8780 |
| 8781 const char* Type::ToCString() const { |
| 8782 if (IsResolved()) { |
| 8783 const AbstractTypeArguments& type_arguments = |
| 8784 AbstractTypeArguments::Handle(arguments()); |
| 8785 if (type_arguments.IsNull()) { |
| 8786 const char* format = "Type: class '%s'"; |
| 8787 const char* class_name = |
| 8788 String::Handle(Class::Handle(type_class()).Name()).ToCString(); |
| 8789 intptr_t len = OS::SNPrint(NULL, 0, format, class_name) + 1; |
| 8790 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 8791 OS::SNPrint(chars, len, format, class_name); |
| 8792 return chars; |
| 8793 } else { |
| 8794 const char* format = "Type: class '%s', args:[%s]"; |
| 8795 const char* class_name = |
| 8796 String::Handle(Class::Handle(type_class()).Name()).ToCString(); |
| 8797 const char* args_cstr = |
| 8798 AbstractTypeArguments::Handle(arguments()).ToCString(); |
| 8799 intptr_t len = OS::SNPrint(NULL, 0, format, class_name, args_cstr) + 1; |
| 8800 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 8801 OS::SNPrint(chars, len, format, class_name, args_cstr); |
| 8802 return chars; |
| 8803 } |
| 8804 } else { |
| 8805 return "Unresolved Type"; |
| 8806 } |
| 8807 } |
| 8808 |
| 8809 |
| 8810 void TypeParameter::set_is_finalized() const { |
| 8811 ASSERT(!IsFinalized()); |
| 8812 set_type_state(RawTypeParameter::kFinalizedUninstantiated); |
| 8813 } |
| 8814 |
| 8815 |
| 8816 bool TypeParameter::Equals(const Instance& other) const { |
| 8817 if (raw() == other.raw()) { |
| 8818 return true; |
| 8819 } |
| 8820 if (!other.IsTypeParameter()) { |
| 8821 return false; |
| 8822 } |
| 8823 const TypeParameter& other_type_param = TypeParameter::Cast(other); |
| 8824 if (IsFinalized() != other_type_param.IsFinalized()) { |
| 8825 return false; |
| 8826 } |
| 8827 if (parameterized_class() != other_type_param.parameterized_class()) { |
| 8828 return false; |
| 8829 } |
| 8830 if (index() != other_type_param.index()) { |
| 8831 return false; |
| 8832 } |
| 8833 const String& type_param_name = String::Handle(name()); |
| 8834 const String& other_type_param_name = String::Handle(other_type_param.name()); |
| 8835 return type_param_name.Equals(other_type_param_name); |
| 8836 } |
| 8837 |
| 8838 |
| 8839 bool TypeParameter::IsIdentical(const AbstractType& other, |
| 8840 bool check_type_parameter_bound) const { |
| 8841 if (raw() == other.raw()) { |
| 8842 return true; |
| 8843 } |
| 8844 if (!other.IsTypeParameter()) { |
| 8845 return false; |
| 8846 } |
| 8847 const TypeParameter& other_type_param = TypeParameter::Cast(other); |
| 8848 // IsIdentical may be called on type parameters belonging to different |
| 8849 // classes, e.g. to an interface and to its default factory class. |
| 8850 // Therefore, both type parameters may have different parameterized classes |
| 8851 // and different indices. Compare the type parameter names only, and their |
| 8852 // bounds if requested. |
| 8853 String& type_param_name = String::Handle(name()); |
| 8854 String& other_type_param_name = String::Handle(other_type_param.name()); |
| 8855 if (!type_param_name.Equals(other_type_param_name)) { |
| 8856 return false; |
| 8857 } |
| 8858 if (check_type_parameter_bound) { |
| 8859 AbstractType& this_bound = AbstractType::Handle(bound()); |
| 8860 AbstractType& other_bound = AbstractType::Handle(other_type_param.bound()); |
| 8861 // Bounds are only checked at the top level. |
| 8862 const bool check_type_parameter_bounds = false; |
| 8863 if (!this_bound.IsIdentical(other_bound, check_type_parameter_bounds)) { |
| 8864 return false; |
| 8865 } |
| 8866 } |
| 8867 return true; |
| 8868 } |
| 8869 |
| 8870 |
| 8871 void TypeParameter::set_parameterized_class(const Class& value) const { |
| 8872 // Set value may be null. |
| 8873 StorePointer(&raw_ptr()->parameterized_class_, value.raw()); |
| 8874 } |
| 8875 |
| 8876 |
| 8877 void TypeParameter::set_index(intptr_t value) const { |
| 8878 ASSERT(value >= 0); |
| 8879 raw_ptr()->index_ = value; |
| 8880 } |
| 8881 |
| 8882 |
| 8883 void TypeParameter::set_name(const String& value) const { |
| 8884 ASSERT(value.IsSymbol()); |
| 8885 StorePointer(&raw_ptr()->name_, value.raw()); |
| 8886 } |
| 8887 |
| 8888 |
| 8889 void TypeParameter::set_bound(const AbstractType& value) const { |
| 8890 StorePointer(&raw_ptr()->bound_, value.raw()); |
| 8891 } |
| 8892 |
| 8893 RawAbstractType* TypeParameter::InstantiateFrom( |
| 8894 const AbstractTypeArguments& instantiator_type_arguments) const { |
| 8895 ASSERT(IsFinalized()); |
| 8896 if (instantiator_type_arguments.IsNull()) { |
| 8897 return Type::DynamicType(); |
| 8898 } |
| 8899 return instantiator_type_arguments.TypeAt(index()); |
| 8900 } |
| 8901 |
| 8902 |
| 8903 RawTypeParameter* TypeParameter::New() { |
| 8904 ASSERT(Isolate::Current()->object_store()->type_parameter_class() != |
| 8905 Class::null()); |
| 8906 RawObject* raw = Object::Allocate(TypeParameter::kClassId, |
| 8907 TypeParameter::InstanceSize(), |
| 8908 Heap::kOld); |
| 8909 return reinterpret_cast<RawTypeParameter*>(raw); |
| 8910 } |
| 8911 |
| 8912 |
| 8913 RawTypeParameter* TypeParameter::New(const Class& parameterized_class, |
| 8914 intptr_t index, |
| 8915 const String& name, |
| 8916 const AbstractType& bound, |
| 8917 intptr_t token_pos) { |
| 8918 const TypeParameter& result = TypeParameter::Handle(TypeParameter::New()); |
| 8919 result.set_parameterized_class(parameterized_class); |
| 8920 result.set_index(index); |
| 8921 result.set_name(name); |
| 8922 result.set_bound(bound); |
| 8923 result.set_token_pos(token_pos); |
| 8924 result.raw_ptr()->type_state_ = RawTypeParameter::kAllocated; |
| 8925 return result.raw(); |
| 8926 } |
| 8927 |
| 8928 |
| 8929 void TypeParameter::set_token_pos(intptr_t token_pos) const { |
| 8930 ASSERT(token_pos >= 0); |
| 8931 raw_ptr()->token_pos_ = token_pos; |
| 8932 } |
| 8933 |
| 8934 |
| 8935 void TypeParameter::set_type_state(int8_t state) const { |
| 8936 ASSERT((state == RawTypeParameter::kAllocated) || |
| 8937 (state == RawTypeParameter::kBeingFinalized) || |
| 8938 (state == RawTypeParameter::kFinalizedUninstantiated)); |
| 8939 raw_ptr()->type_state_ = state; |
| 8940 } |
| 8941 |
| 8942 |
| 8943 const char* TypeParameter::ToCString() const { |
| 8944 const char* format = "TypeParameter: name %s; index: %d"; |
| 8945 const char* name_cstr = String::Handle(Name()).ToCString(); |
| 8946 intptr_t len = OS::SNPrint(NULL, 0, format, name_cstr, index()) + 1; |
| 8947 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 8948 OS::SNPrint(chars, len, format, name_cstr, index()); |
| 8949 return chars; |
| 8950 } |
| 8951 |
| 8952 |
| 8936 const char* Number::ToCString() const { | 8953 const char* Number::ToCString() const { |
| 8937 // Number is an interface. No instances of Number should exist. | 8954 // Number is an interface. No instances of Number should exist. |
| 8938 UNREACHABLE(); | 8955 UNREACHABLE(); |
| 8939 return "Number"; | 8956 return "Number"; |
| 8940 } | 8957 } |
| 8941 | 8958 |
| 8942 | 8959 |
| 8943 const char* Integer::ToCString() const { | 8960 const char* Integer::ToCString() const { |
| 8944 // Integer is an interface. No instances of Integer should exist. | 8961 // Integer is an interface. No instances of Integer should exist. |
| 8945 UNREACHABLE(); | 8962 UNREACHABLE(); |
| (...skipping 3192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12138 } | 12155 } |
| 12139 return result.raw(); | 12156 return result.raw(); |
| 12140 } | 12157 } |
| 12141 | 12158 |
| 12142 | 12159 |
| 12143 const char* WeakProperty::ToCString() const { | 12160 const char* WeakProperty::ToCString() const { |
| 12144 return "_WeakProperty"; | 12161 return "_WeakProperty"; |
| 12145 } | 12162 } |
| 12146 | 12163 |
| 12147 } // namespace dart | 12164 } // namespace dart |
| OLD | NEW |