Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: runtime/vm/object.cc

Issue 10696013: Consider upper bounds of type parameters in type checks. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "platform/assert.h" 7 #include "platform/assert.h"
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/bigint_operations.h" 9 #include "vm/bigint_operations.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 void Class::set_library(const Library& value) const { 1180 void Class::set_library(const Library& value) const {
1181 StorePointer(&raw_ptr()->library_, value.raw()); 1181 StorePointer(&raw_ptr()->library_, value.raw());
1182 } 1182 }
1183 1183
1184 1184
1185 void Class::set_type_parameters(const TypeArguments& value) const { 1185 void Class::set_type_parameters(const TypeArguments& value) const {
1186 StorePointer(&raw_ptr()->type_parameters_, value.raw()); 1186 StorePointer(&raw_ptr()->type_parameters_, value.raw());
1187 } 1187 }
1188 1188
1189 1189
1190 void Class::set_type_parameter_bounds(const TypeArguments& value) const {
1191 StorePointer(&raw_ptr()->type_parameter_bounds_, value.raw());
1192 }
1193
1194
1195 intptr_t Class::NumTypeParameters() const { 1190 intptr_t Class::NumTypeParameters() const {
1196 const TypeArguments& type_params = TypeArguments::Handle(type_parameters()); 1191 const TypeArguments& type_params = TypeArguments::Handle(type_parameters());
1197 if (type_params.IsNull()) { 1192 if (type_params.IsNull()) {
1198 return 0; 1193 return 0;
1199 } else { 1194 } else {
1200 return type_params.Length(); 1195 return type_params.Length();
1201 } 1196 }
1202 } 1197 }
1203 1198
1204 1199
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 // Return a TypeParameter if the type_name is a type parameter of this class. 1280 // Return a TypeParameter if the type_name is a type parameter of this class.
1286 // Return null otherwise. 1281 // Return null otherwise.
1287 RawTypeParameter* Class::LookupTypeParameter(const String& type_name, 1282 RawTypeParameter* Class::LookupTypeParameter(const String& type_name,
1288 intptr_t token_pos) const { 1283 intptr_t token_pos) const {
1289 ASSERT(!type_name.IsNull()); 1284 ASSERT(!type_name.IsNull());
1290 const TypeArguments& type_params = TypeArguments::Handle(type_parameters()); 1285 const TypeArguments& type_params = TypeArguments::Handle(type_parameters());
1291 if (!type_params.IsNull()) { 1286 if (!type_params.IsNull()) {
1292 intptr_t num_type_params = type_params.Length(); 1287 intptr_t num_type_params = type_params.Length();
1293 TypeParameter& type_param = TypeParameter::Handle(); 1288 TypeParameter& type_param = TypeParameter::Handle();
1294 String& type_param_name = String::Handle(); 1289 String& type_param_name = String::Handle();
1290 AbstractType& bound = AbstractType::Handle();
1295 for (intptr_t i = 0; i < num_type_params; i++) { 1291 for (intptr_t i = 0; i < num_type_params; i++) {
1296 type_param ^= type_params.TypeAt(i); 1292 type_param ^= type_params.TypeAt(i);
1297 type_param_name = type_param.Name(); 1293 type_param_name = type_param.Name();
1298 if (type_param_name.Equals(type_name)) { 1294 if (type_param_name.Equals(type_name)) {
1299 intptr_t index = type_param.Index(); 1295 intptr_t index = type_param.index();
1296 bound = type_param.bound();
1300 // Create a non-finalized new TypeParameter with the given token_pos. 1297 // Create a non-finalized new TypeParameter with the given token_pos.
1301 if (type_param.IsFinalized()) { 1298 if (type_param.IsFinalized()) {
1302 // The index was adjusted during finalization. Revert. 1299 // The index was adjusted during finalization. Revert.
1303 index -= NumTypeArguments() - num_type_params; 1300 index -= NumTypeArguments() - num_type_params;
1304 } else { 1301 } else {
1305 ASSERT(type_param.Index() == i); 1302 ASSERT(type_param.index() == i);
1306 } 1303 }
1307 return TypeParameter::New(*this, index, type_name, token_pos); 1304 return TypeParameter::New(*this, index, type_name, bound, token_pos);
1308 } 1305 }
1309 } 1306 }
1310 } 1307 }
1311 return TypeParameter::null(); 1308 return TypeParameter::null();
1312 } 1309 }
1313 1310
1314 1311
1315 void Class::CalculateFieldOffsets() const { 1312 void Class::CalculateFieldOffsets() const {
1316 Array& flds = Array::Handle(fields()); 1313 Array& flds = Array::Handle(fields());
1317 const Class& super = Class::Handle(SuperClass()); 1314 const Class& super = Class::Handle(SuperClass());
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 } 1439 }
1443 1440
1444 1441
1445 RawClass* Class::NewSignatureClass(const String& name, 1442 RawClass* Class::NewSignatureClass(const String& name,
1446 const Function& signature_function, 1443 const Function& signature_function,
1447 const Script& script) { 1444 const Script& script) {
1448 ASSERT(!signature_function.IsNull()); 1445 ASSERT(!signature_function.IsNull());
1449 const Class& owner_class = Class::Handle(signature_function.owner()); 1446 const Class& owner_class = Class::Handle(signature_function.owner());
1450 ASSERT(!owner_class.IsNull()); 1447 ASSERT(!owner_class.IsNull());
1451 TypeArguments& type_parameters = TypeArguments::Handle(); 1448 TypeArguments& type_parameters = TypeArguments::Handle();
1452 TypeArguments& type_parameter_bounds = TypeArguments::Handle();
1453 // A signature class extends class Instance and is parameterized in the same 1449 // A signature class extends class Instance and is parameterized in the same
1454 // way as the owner class of its non-static signature function. 1450 // way as the owner class of its non-static signature function.
1455 // It is not type parameterized if its signature function is static. 1451 // It is not type parameterized if its signature function is static.
1456 if (!signature_function.is_static()) { 1452 if (!signature_function.is_static()) {
1457 if ((owner_class.NumTypeParameters() > 0) && 1453 if ((owner_class.NumTypeParameters() > 0) &&
1458 !signature_function.HasInstantiatedSignature()) { 1454 !signature_function.HasInstantiatedSignature()) {
1459 type_parameters = owner_class.type_parameters(); 1455 type_parameters = owner_class.type_parameters();
1460 type_parameter_bounds = owner_class.type_parameter_bounds();
1461 } 1456 }
1462 } 1457 }
1463 const intptr_t token_pos = signature_function.token_pos(); 1458 const intptr_t token_pos = signature_function.token_pos();
1464 Class& result = Class::Handle(New<Closure>(name, script, token_pos)); 1459 Class& result = Class::Handle(New<Closure>(name, script, token_pos));
1465 const Type& super_type = Type::Handle(Type::ObjectType()); 1460 const Type& super_type = Type::Handle(Type::ObjectType());
1466 ASSERT(!super_type.IsNull()); 1461 ASSERT(!super_type.IsNull());
1467 result.set_super_type(super_type); 1462 result.set_super_type(super_type);
1468 result.set_signature_function(signature_function); 1463 result.set_signature_function(signature_function);
1469 result.set_type_parameters(type_parameters); 1464 result.set_type_parameters(type_parameters);
1470 result.set_type_parameter_bounds(type_parameter_bounds);
1471 result.SetFields(Array::Handle(Array::Empty())); 1465 result.SetFields(Array::Handle(Array::Empty()));
1472 result.SetFunctions(Array::Handle(Array::Empty())); 1466 result.SetFunctions(Array::Handle(Array::Empty()));
1473 result.set_type_arguments_instance_field_offset( 1467 result.set_type_arguments_instance_field_offset(
1474 Closure::type_arguments_offset()); 1468 Closure::type_arguments_offset());
1475 // Implements interface "Function". 1469 // Implements interface "Function".
1476 const Type& function_interface = Type::Handle(Type::FunctionInterface()); 1470 const Type& function_interface = Type::Handle(Type::FunctionInterface());
1477 const Array& interfaces = Array::Handle(Array::New(1, Heap::kOld)); 1471 const Array& interfaces = Array::Handle(Array::New(1, Heap::kOld));
1478 interfaces.SetAt(0, function_interface); 1472 interfaces.SetAt(0, function_interface);
1479 result.set_interfaces(interfaces); 1473 result.set_interfaces(interfaces);
1480 // Unless the signature function already has a signature class, create a 1474 // Unless the signature function already has a signature class, create a
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after
2268 } 2262 }
2269 2263
2270 2264
2271 bool AbstractType::Equals(const AbstractType& other) const { 2265 bool AbstractType::Equals(const AbstractType& other) const {
2272 // AbstractType is an abstract class. 2266 // AbstractType is an abstract class.
2273 UNREACHABLE(); 2267 UNREACHABLE();
2274 return false; 2268 return false;
2275 } 2269 }
2276 2270
2277 2271
2278 bool AbstractType::IsIdentical(const AbstractType& other) const { 2272 bool AbstractType::IsIdentical(const AbstractType& other,
2273 bool check_type_parameter_bound) const {
2279 // AbstractType is an abstract class. 2274 // AbstractType is an abstract class.
2280 UNREACHABLE(); 2275 UNREACHABLE();
2281 return false; 2276 return false;
2282 } 2277 }
2283 2278
2284 2279
2285 RawAbstractType* AbstractType::InstantiateFrom( 2280 RawAbstractType* AbstractType::InstantiateFrom(
2286 const AbstractTypeArguments& instantiator_type_arguments) const { 2281 const AbstractTypeArguments& instantiator_type_arguments) const {
2287 // AbstractType is an abstract class. 2282 // AbstractType is an abstract class.
2288 UNREACHABLE(); 2283 UNREACHABLE();
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2352 args.SubvectorName(first_type_param_index, num_type_params)); 2347 args.SubvectorName(first_type_param_index, num_type_params));
2353 type_name = String::Concat(class_name, args_name); 2348 type_name = String::Concat(class_name, args_name);
2354 } 2349 }
2355 // The name is only used for type checking and debugging purposes. 2350 // The name is only used for type checking and debugging purposes.
2356 // Unless profiling data shows otherwise, it is not worth caching the name in 2351 // Unless profiling data shows otherwise, it is not worth caching the name in
2357 // the type. 2352 // the type.
2358 return String::NewSymbol(type_name); 2353 return String::NewSymbol(type_name);
2359 } 2354 }
2360 2355
2361 2356
2362 intptr_t AbstractType::Index() const {
2363 // AbstractType is an abstract class.
2364 UNREACHABLE();
2365 return -1;
2366 }
2367
2368
2369 RawString* AbstractType::ClassName() const { 2357 RawString* AbstractType::ClassName() const {
2370 if (HasResolvedTypeClass()) { 2358 if (HasResolvedTypeClass()) {
2371 return Class::Handle(type_class()).Name(); 2359 return Class::Handle(type_class()).Name();
2372 } else { 2360 } else {
2373 return UnresolvedClass::Handle(unresolved_class()).Name(); 2361 return UnresolvedClass::Handle(unresolved_class()).Name();
2374 } 2362 }
2375 } 2363 }
2376 2364
2377 2365
2378 bool AbstractType::IsBoolInterface() const { 2366 bool AbstractType::IsBoolInterface() const {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2447 // is a subtype of V, or vice versa. We only return true if K == V, i.e. if 2435 // is a subtype of V, or vice versa. We only return true if K == V, i.e. if
2448 // they have the same index (both are finalized, so their indices are 2436 // they have the same index (both are finalized, so their indices are
2449 // comparable). 2437 // comparable).
2450 // The same rule applies When checking the upper bound of a still 2438 // The same rule applies When checking the upper bound of a still
2451 // uninstantiated type at compile time. Returning false will defer the test 2439 // uninstantiated type at compile time. Returning false will defer the test
2452 // to run time. But there are cases where it can be decided at compile time. 2440 // to run time. But there are cases where it can be decided at compile time.
2453 // For example, with class A<K, V extends K>, new A<T, T> called from within 2441 // For example, with class A<K, V extends K>, new A<T, T> called from within
2454 // a class B<T> will never require a run time bounds check, even it T is 2442 // a class B<T> will never require a run time bounds check, even it T is
2455 // uninstantiated at compile time. 2443 // uninstantiated at compile time.
2456 if (IsTypeParameter()) { 2444 if (IsTypeParameter()) {
2445 // TODO(regis): Introduce and use TypeParameter::Cast().
2446 const TypeParameter* type_param =
2447 reinterpret_cast<const TypeParameter*>(this);
2457 if (other.IsTypeParameter()) { 2448 if (other.IsTypeParameter()) {
2458 return Index() == other.Index(); 2449 const TypeParameter* other_type_param =
2459 } else { 2450 reinterpret_cast<const TypeParameter*>(&other);
2460 // TODO(regis): In checked mode, if the other type is the upper bound of 2451 return type_param->index() == other_type_param->index();
2461 // this type parameter, then return true. 2452 } else if (FLAG_enable_type_checks) {
2462 // We would need to keep the upper bound associated to the type parameter. 2453 // In checked mode, if the upper bound of this type is more specific than
2454 // the other type, then this type is more specific than the other type.
2455 const AbstractType& type_param_bound =
2456 AbstractType::Handle(type_param->bound());
2457 if (type_param_bound.IsMoreSpecificThan(other, malformed_error)) {
2458 return true;
2459 }
2463 } 2460 }
2464 return false; 2461 return false;
2465 } 2462 }
2466 if (other.IsTypeParameter()) { 2463 if (other.IsTypeParameter()) {
2467 return false; 2464 return false;
2468 } 2465 }
2469 const Class& cls = Class::Handle(type_class()); 2466 const Class& cls = Class::Handle(type_class());
2470 return cls.TypeTest(test_kind, 2467 return cls.TypeTest(test_kind,
2471 AbstractTypeArguments::Handle(arguments()), 2468 AbstractTypeArguments::Handle(arguments()),
2472 Class::Handle(other.type_class()), 2469 Class::Handle(other.type_class()),
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
2678 } 2675 }
2679 if (type_class() != other.type_class()) { 2676 if (type_class() != other.type_class()) {
2680 return false; 2677 return false;
2681 } 2678 }
2682 return AbstractTypeArguments::AreEqual( 2679 return AbstractTypeArguments::AreEqual(
2683 AbstractTypeArguments::Handle(arguments()), 2680 AbstractTypeArguments::Handle(arguments()),
2684 AbstractTypeArguments::Handle(other.arguments())); 2681 AbstractTypeArguments::Handle(other.arguments()));
2685 } 2682 }
2686 2683
2687 2684
2688 bool Type::IsIdentical(const AbstractType& other) const { 2685 bool Type::IsIdentical(const AbstractType& other,
2686 bool check_type_parameter_bounds) const {
2689 if (raw() == other.raw()) { 2687 if (raw() == other.raw()) {
2690 return true; 2688 return true;
2691 } 2689 }
2692 if (!other.IsType()) { 2690 if (!other.IsType()) {
2693 return false; 2691 return false;
2694 } 2692 }
2695 Type& other_type = Type::Handle(); 2693 Type& other_type = Type::Handle();
2696 other_type ^= other.raw(); 2694 other_type ^= other.raw();
2697 // Both type classes may not be resolved yet. 2695 // Both type classes may not be resolved yet.
2698 String& name = String::Handle(TypeClassName()); 2696 String& name = String::Handle(TypeClassName());
2699 String& other_name = String::Handle(other_type.TypeClassName()); 2697 String& other_name = String::Handle(other_type.TypeClassName());
2700 if (!name.Equals(other_name)) { 2698 if (!name.Equals(other_name)) {
2701 return false; 2699 return false;
2702 } 2700 }
2703 return AbstractTypeArguments::AreIdentical( 2701 return AbstractTypeArguments::AreIdentical(
2704 AbstractTypeArguments::Handle(arguments()), 2702 AbstractTypeArguments::Handle(arguments()),
2705 AbstractTypeArguments::Handle(other.arguments())); 2703 AbstractTypeArguments::Handle(other.arguments()),
2704 false); // Bounds are only checked at the top level.
hausner 2012/06/27 19:59:40 Indentation
regis 2012/06/27 20:06:50 I think the indentation is correct.
2706 } 2705 }
2707 2706
2708 2707
2709 RawAbstractType* Type::Canonicalize() const { 2708 RawAbstractType* Type::Canonicalize() const {
2710 ASSERT(IsFinalized()); 2709 ASSERT(IsFinalized());
2711 const Class& cls = Class::Handle(type_class()); 2710 const Class& cls = Class::Handle(type_class());
2712 Array& canonical_types = Array::Handle(cls.canonical_types()); 2711 Array& canonical_types = Array::Handle(cls.canonical_types());
2713 if (canonical_types.IsNull()) { 2712 if (canonical_types.IsNull()) {
2714 // Types defined in the VM isolate are canonicalized via the object store. 2713 // Types defined in the VM isolate are canonicalized via the object store.
2715 return this->raw(); 2714 return this->raw();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2828 } 2827 }
2829 } else { 2828 } else {
2830 return "Unresolved Type"; 2829 return "Unresolved Type";
2831 } 2830 }
2832 } 2831 }
2833 2832
2834 2833
2835 void TypeParameter::set_is_finalized() const { 2834 void TypeParameter::set_is_finalized() const {
2836 ASSERT(!IsFinalized()); 2835 ASSERT(!IsFinalized());
2837 set_type_state(RawTypeParameter::kFinalizedUninstantiated); 2836 set_type_state(RawTypeParameter::kFinalizedUninstantiated);
2838 // Field parameterized_class_ is not needed after finalization anymore.
2839 set_parameterized_class(Class::Handle());
2840 } 2837 }
2841 2838
2842 2839
2843 bool TypeParameter::Equals(const AbstractType& other) const { 2840 bool TypeParameter::Equals(const AbstractType& other) const {
2844 if (raw() == other.raw()) { 2841 if (raw() == other.raw()) {
2845 return true; 2842 return true;
2846 } 2843 }
2847 if (!other.IsTypeParameter()) { 2844 if (!other.IsTypeParameter()) {
2848 return false; 2845 return false;
2849 } 2846 }
2850 TypeParameter& other_type_param = TypeParameter::Handle(); 2847 TypeParameter& other_type_param = TypeParameter::Handle();
2851 other_type_param ^= other.raw(); 2848 other_type_param ^= other.raw();
2852 if (IsFinalized() != other_type_param.IsFinalized()) { 2849 if (IsFinalized() != other_type_param.IsFinalized()) {
2853 return false; 2850 return false;
2854 } 2851 }
2855 if (parameterized_class() != other_type_param.parameterized_class()) { 2852 if (parameterized_class() != other_type_param.parameterized_class()) {
2856 return false; 2853 return false;
2857 } 2854 }
2858 if (Index() != other_type_param.Index()) { 2855 if (index() != other_type_param.index()) {
2859 return false; 2856 return false;
2860 } 2857 }
2861 const String& name = String::Handle(Name()); 2858 const String& name = String::Handle(Name());
2862 const String& other_type_param_name = String::Handle(other_type_param.Name()); 2859 const String& other_type_param_name = String::Handle(other_type_param.Name());
2863 return name.Equals(other_type_param_name); 2860 return name.Equals(other_type_param_name);
2864 } 2861 }
2865 2862
2866 2863
2867 bool TypeParameter::IsIdentical(const AbstractType& other) const { 2864 bool TypeParameter::IsIdentical(const AbstractType& other,
2865 bool check_type_parameter_bound) const {
2868 if (raw() == other.raw()) { 2866 if (raw() == other.raw()) {
2869 return true; 2867 return true;
2870 } 2868 }
2871 if (!other.IsTypeParameter()) { 2869 if (!other.IsTypeParameter()) {
2872 return false; 2870 return false;
2873 } 2871 }
2874 TypeParameter& other_type_param = TypeParameter::Handle(); 2872 TypeParameter& other_type_param = TypeParameter::Handle();
2875 other_type_param ^= other.raw(); 2873 other_type_param ^= other.raw();
2876 // IsIdentical may be called on type parameters belonging to different 2874 // IsIdentical may be called on type parameters belonging to different
2877 // classes, e.g. to an interface and to its default factory class. 2875 // classes, e.g. to an interface and to its default factory class.
2878 // Therefore, both type parameters may have different parameterized classes 2876 // Therefore, both type parameters may have different parameterized classes
2879 // and different indices. Compare the type parameter names only. 2877 // and different indices. Compare the type parameter names only, and their
2878 // bounds if requested.
2880 String& name = String::Handle(Name()); 2879 String& name = String::Handle(Name());
2881 String& other_name = String::Handle(other_type_param.Name()); 2880 String& other_name = String::Handle(other_type_param.Name());
2882 return name.Equals(other_name); 2881 if (!name.Equals(other_name)) {
2882 return false;
2883 }
2884 if (check_type_parameter_bound) {
2885 AbstractType& this_bound = AbstractType::Handle(bound());
2886 AbstractType& other_bound = AbstractType::Handle(other_type_param.bound());
2887 // Bounds are only checked at the top level.
2888 const bool check_type_parameter_bounds = false;
2889 if (!this_bound.IsIdentical(other_bound, check_type_parameter_bounds)) {
2890 return false;
2891 }
2892 }
2893 return true;
2883 } 2894 }
2884 2895
2885 2896
2886 void TypeParameter::set_parameterized_class(const Class& value) const { 2897 void TypeParameter::set_parameterized_class(const Class& value) const {
2887 // Set value may be null. 2898 // Set value may be null.
2888 StorePointer(&raw_ptr()->parameterized_class_, value.raw()); 2899 StorePointer(&raw_ptr()->parameterized_class_, value.raw());
2889 } 2900 }
2890 2901
2891 2902
2892 void TypeParameter::set_index(intptr_t value) const { 2903 void TypeParameter::set_index(intptr_t value) const {
2893 ASSERT(value >= 0); 2904 ASSERT(value >= 0);
2894 raw_ptr()->index_ = value; 2905 raw_ptr()->index_ = value;
2895 } 2906 }
2896 2907
2897 2908
2898 void TypeParameter::set_name(const String& value) const { 2909 void TypeParameter::set_name(const String& value) const {
2899 ASSERT(value.IsSymbol()); 2910 ASSERT(value.IsSymbol());
2900 StorePointer(&raw_ptr()->name_, value.raw()); 2911 StorePointer(&raw_ptr()->name_, value.raw());
2901 } 2912 }
2902 2913
2903 2914
2915 void TypeParameter::set_bound(const AbstractType& value) const {
2916 StorePointer(&raw_ptr()->bound_, value.raw());
2917 }
2918
2904 RawAbstractType* TypeParameter::InstantiateFrom( 2919 RawAbstractType* TypeParameter::InstantiateFrom(
2905 const AbstractTypeArguments& instantiator_type_arguments) const { 2920 const AbstractTypeArguments& instantiator_type_arguments) const {
2906 ASSERT(IsFinalized()); 2921 ASSERT(IsFinalized());
2907 if (instantiator_type_arguments.IsNull()) { 2922 if (instantiator_type_arguments.IsNull()) {
2908 return Type::DynamicType(); 2923 return Type::DynamicType();
2909 } 2924 }
2910 return instantiator_type_arguments.TypeAt(Index()); 2925 return instantiator_type_arguments.TypeAt(index());
2911 } 2926 }
2912 2927
2913 2928
2914 RawTypeParameter* TypeParameter::New() { 2929 RawTypeParameter* TypeParameter::New() {
2915 const Class& type_parameter_class = 2930 const Class& type_parameter_class =
2916 Class::Handle(Object::type_parameter_class()); 2931 Class::Handle(Object::type_parameter_class());
2917 RawObject* raw = Object::Allocate(type_parameter_class, 2932 RawObject* raw = Object::Allocate(type_parameter_class,
2918 TypeParameter::InstanceSize(), 2933 TypeParameter::InstanceSize(),
2919 Heap::kOld); 2934 Heap::kOld);
2920 return reinterpret_cast<RawTypeParameter*>(raw); 2935 return reinterpret_cast<RawTypeParameter*>(raw);
2921 } 2936 }
2922 2937
2923 2938
2924 RawTypeParameter* TypeParameter::New(const Class& parameterized_class, 2939 RawTypeParameter* TypeParameter::New(const Class& parameterized_class,
2925 intptr_t index, 2940 intptr_t index,
2926 const String& name, 2941 const String& name,
2942 const AbstractType& bound,
2927 intptr_t token_pos) { 2943 intptr_t token_pos) {
2928 const TypeParameter& result = TypeParameter::Handle(TypeParameter::New()); 2944 const TypeParameter& result = TypeParameter::Handle(TypeParameter::New());
2929 result.set_parameterized_class(parameterized_class); 2945 result.set_parameterized_class(parameterized_class);
2930 result.set_index(index); 2946 result.set_index(index);
2931 result.set_name(name); 2947 result.set_name(name);
2948 result.set_bound(bound);
2932 result.set_token_pos(token_pos); 2949 result.set_token_pos(token_pos);
2933 result.raw_ptr()->type_state_ = RawTypeParameter::kAllocated; 2950 result.raw_ptr()->type_state_ = RawTypeParameter::kAllocated;
2934 return result.raw(); 2951 return result.raw();
2935 } 2952 }
2936 2953
2937 2954
2938 void TypeParameter::set_token_pos(intptr_t token_pos) const { 2955 void TypeParameter::set_token_pos(intptr_t token_pos) const {
2939 ASSERT(token_pos >= 0); 2956 ASSERT(token_pos >= 0);
2940 raw_ptr()->token_pos_ = token_pos; 2957 raw_ptr()->token_pos_ = token_pos;
2941 } 2958 }
2942 2959
2943 2960
2944 void TypeParameter::set_type_state(int8_t state) const { 2961 void TypeParameter::set_type_state(int8_t state) const {
2945 ASSERT((state == RawTypeParameter::kAllocated) || 2962 ASSERT((state == RawTypeParameter::kAllocated) ||
2946 (state == RawTypeParameter::kBeingFinalized) || 2963 (state == RawTypeParameter::kBeingFinalized) ||
2947 (state == RawTypeParameter::kFinalizedUninstantiated)); 2964 (state == RawTypeParameter::kFinalizedUninstantiated));
2948 raw_ptr()->type_state_ = state; 2965 raw_ptr()->type_state_ = state;
2949 } 2966 }
2950 2967
2951 2968
2952 const char* TypeParameter::ToCString() const { 2969 const char* TypeParameter::ToCString() const {
2953 const char* format = "TypeParameter: name %s; index: %d"; 2970 const char* format = "TypeParameter: name %s; index: %d";
2954 const char* name_cstr = String::Handle(Name()).ToCString(); 2971 const char* name_cstr = String::Handle(Name()).ToCString();
2955 intptr_t len = OS::SNPrint(NULL, 0, format, name_cstr, Index()) + 1; 2972 intptr_t len = OS::SNPrint(NULL, 0, format, name_cstr, index()) + 1;
2956 char* chars = reinterpret_cast<char*>( 2973 char* chars = reinterpret_cast<char*>(
2957 Isolate::Current()->current_zone()->Allocate(len)); 2974 Isolate::Current()->current_zone()->Allocate(len));
2958 OS::SNPrint(chars, len, format, name_cstr, Index()); 2975 OS::SNPrint(chars, len, format, name_cstr, index());
2959 return chars; 2976 return chars;
2960 } 2977 }
2961 2978
2962 2979
2963 intptr_t AbstractTypeArguments::Length() const { 2980 intptr_t AbstractTypeArguments::Length() const {
2964 // AbstractTypeArguments is an abstract class. 2981 // AbstractTypeArguments is an abstract class.
2965 UNREACHABLE(); 2982 UNREACHABLE();
2966 return -1; 2983 return -1;
2967 } 2984 }
2968 2985
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
3063 } 3080 }
3064 if (other_arguments.IsNull()) { 3081 if (other_arguments.IsNull()) {
3065 return arguments.IsDynamicTypes(false, arguments.Length()); 3082 return arguments.IsDynamicTypes(false, arguments.Length());
3066 } 3083 }
3067 return arguments.Equals(other_arguments); 3084 return arguments.Equals(other_arguments);
3068 } 3085 }
3069 3086
3070 3087
3071 bool AbstractTypeArguments::AreIdentical( 3088 bool AbstractTypeArguments::AreIdentical(
3072 const AbstractTypeArguments& arguments, 3089 const AbstractTypeArguments& arguments,
3073 const AbstractTypeArguments& other_arguments) { 3090 const AbstractTypeArguments& other_arguments,
3091 bool check_type_parameter_bounds) {
3074 if (arguments.raw() == other_arguments.raw()) { 3092 if (arguments.raw() == other_arguments.raw()) {
3075 return true; 3093 return true;
3076 } 3094 }
3077 if (arguments.IsNull() || other_arguments.IsNull()) { 3095 if (arguments.IsNull() || other_arguments.IsNull()) {
3078 return false; 3096 return false;
3079 } 3097 }
3080 intptr_t num_types = arguments.Length(); 3098 intptr_t num_types = arguments.Length();
3081 if (num_types != other_arguments.Length()) { 3099 if (num_types != other_arguments.Length()) {
3082 return false; 3100 return false;
3083 } 3101 }
3084 AbstractType& type = AbstractType::Handle(); 3102 AbstractType& type = AbstractType::Handle();
3085 AbstractType& other_type = AbstractType::Handle(); 3103 AbstractType& other_type = AbstractType::Handle();
3086 for (intptr_t i = 0; i < num_types; i++) { 3104 for (intptr_t i = 0; i < num_types; i++) {
3087 type ^= arguments.TypeAt(i); 3105 type ^= arguments.TypeAt(i);
3088 ASSERT(!type.IsNull()); 3106 ASSERT(!type.IsNull());
3089 other_type ^= other_arguments.TypeAt(i); 3107 other_type ^= other_arguments.TypeAt(i);
3090 if (!type.IsIdentical(other_type)) { 3108 if (!type.IsIdentical(other_type, check_type_parameter_bounds)) {
3091 return false; 3109 return false;
3092 } 3110 }
3093 } 3111 }
3094 return true; 3112 return true;
3095 } 3113 }
3096 3114
3097 3115
3098 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom( 3116 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom(
3099 const AbstractTypeArguments& instantiator_type_arguments) const { 3117 const AbstractTypeArguments& instantiator_type_arguments) const {
3100 // AbstractTypeArguments is an abstract class. 3118 // AbstractTypeArguments is an abstract class.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3149 const AbstractTypeArguments& bounds_instantiator, 3167 const AbstractTypeArguments& bounds_instantiator,
3150 Error* malformed_error) const { 3168 Error* malformed_error) const {
3151 ASSERT(FLAG_enable_type_checks); 3169 ASSERT(FLAG_enable_type_checks);
3152 // This function may be called at compile time on (partially) uninstantiated 3170 // This function may be called at compile time on (partially) uninstantiated
3153 // type arguments and may return true, in which case a run time bounds check 3171 // type arguments and may return true, in which case a run time bounds check
3154 // can be avoided. 3172 // can be avoided.
3155 ASSERT(Length() >= cls.NumTypeArguments()); 3173 ASSERT(Length() >= cls.NumTypeArguments());
3156 const intptr_t num_type_params = cls.NumTypeParameters(); 3174 const intptr_t num_type_params = cls.NumTypeParameters();
3157 const intptr_t offset = cls.NumTypeArguments() - num_type_params; 3175 const intptr_t offset = cls.NumTypeArguments() - num_type_params;
3158 AbstractType& type = AbstractType::Handle(); 3176 AbstractType& type = AbstractType::Handle();
3177 TypeParameter& type_param = TypeParameter::Handle();
3159 AbstractType& bound = AbstractType::Handle(); 3178 AbstractType& bound = AbstractType::Handle();
3160 const TypeArguments& bounds = 3179 const TypeArguments& type_params =
3161 TypeArguments::Handle(cls.type_parameter_bounds()); 3180 TypeArguments::Handle(cls.type_parameters());
3162 ASSERT((bounds.IsNull() && (num_type_params == 0)) || 3181 ASSERT((type_params.IsNull() && (num_type_params == 0)) ||
3163 (bounds.Length() == num_type_params)); 3182 (type_params.Length() == num_type_params));
3164 for (intptr_t i = 0; i < num_type_params; i++) { 3183 for (intptr_t i = 0; i < num_type_params; i++) {
3165 bound = bounds.TypeAt(i); 3184 type_param ^= type_params.TypeAt(i);
3185 bound = type_param.bound();
3166 if (!bound.IsDynamicType()) { 3186 if (!bound.IsDynamicType()) {
3167 type = TypeAt(offset + i); 3187 type = TypeAt(offset + i);
3168 Error& malformed_bound_error = Error::Handle(); 3188 Error& malformed_bound_error = Error::Handle();
3169 if (bound.IsMalformed()) { 3189 if (bound.IsMalformed()) {
3170 malformed_bound_error = bound.malformed_error(); 3190 malformed_bound_error = bound.malformed_error();
3171 } else if (!bound.IsInstantiated()) { 3191 } else if (!bound.IsInstantiated()) {
3172 bound = bound.InstantiateFrom(bounds_instantiator); 3192 bound = bound.InstantiateFrom(bounds_instantiator);
3173 } 3193 }
3174 if (!malformed_bound_error.IsNull() || 3194 if (!malformed_bound_error.IsNull() ||
3175 !type.IsSubtypeOf(bound, malformed_error)) { 3195 !type.IsSubtypeOf(bound, malformed_error)) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
3283 return true; 3303 return true;
3284 } 3304 }
3285 3305
3286 3306
3287 bool TypeArguments::IsUninstantiatedIdentity() const { 3307 bool TypeArguments::IsUninstantiatedIdentity() const {
3288 ASSERT(!IsInstantiated()); 3308 ASSERT(!IsInstantiated());
3289 AbstractType& type = AbstractType::Handle(); 3309 AbstractType& type = AbstractType::Handle();
3290 intptr_t num_types = Length(); 3310 intptr_t num_types = Length();
3291 for (intptr_t i = 0; i < num_types; i++) { 3311 for (intptr_t i = 0; i < num_types; i++) {
3292 type = TypeAt(i); 3312 type = TypeAt(i);
3293 if (!type.IsTypeParameter() || (type.Index() != i)) { 3313 if (!type.IsTypeParameter()) {
3314 return false;
3315 }
3316 // TODO(regis): Introduce and use TypeParameter::Cast().
3317 TypeParameter* type_param = reinterpret_cast<TypeParameter*>(&type);
3318 if ((type_param->index() != i)) {
3294 return false; 3319 return false;
3295 } 3320 }
3296 } 3321 }
3297 return true; 3322 return true;
3298 } 3323 }
3299 3324
3300 3325
3301 RawAbstractTypeArguments* TypeArguments::InstantiateFrom( 3326 RawAbstractTypeArguments* TypeArguments::InstantiateFrom(
3302 const AbstractTypeArguments& instantiator_type_arguments) const { 3327 const AbstractTypeArguments& instantiator_type_arguments) const {
3303 ASSERT(!IsInstantiated()); 3328 ASSERT(!IsInstantiated());
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
4038 String::Handle(String::NewSymbol(" extends ")); 4063 String::Handle(String::NewSymbol(" extends "));
4039 const String& kLAngleBracket = String::Handle(String::NewSymbol("<")); 4064 const String& kLAngleBracket = String::Handle(String::NewSymbol("<"));
4040 const String& kRAngleBracket = String::Handle(String::NewSymbol(">")); 4065 const String& kRAngleBracket = String::Handle(String::NewSymbol(">"));
4041 const Class& function_class = Class::Handle(owner()); 4066 const Class& function_class = Class::Handle(owner());
4042 ASSERT(!function_class.IsNull()); 4067 ASSERT(!function_class.IsNull());
4043 const TypeArguments& type_parameters = TypeArguments::Handle( 4068 const TypeArguments& type_parameters = TypeArguments::Handle(
4044 function_class.type_parameters()); 4069 function_class.type_parameters());
4045 if (!type_parameters.IsNull()) { 4070 if (!type_parameters.IsNull()) {
4046 intptr_t num_type_parameters = type_parameters.Length(); 4071 intptr_t num_type_parameters = type_parameters.Length();
4047 pieces.Add(kLAngleBracket); 4072 pieces.Add(kLAngleBracket);
4048 const TypeArguments& bounds = TypeArguments::Handle( 4073 TypeParameter& type_parameter = TypeParameter::Handle();
4049 function_class.type_parameter_bounds());
4050 AbstractType& type_parameter = AbstractType::Handle();
4051 AbstractType& bound = AbstractType::Handle(); 4074 AbstractType& bound = AbstractType::Handle();
4052 for (intptr_t i = 0; i < num_type_parameters; i++) { 4075 for (intptr_t i = 0; i < num_type_parameters; i++) {
4053 type_parameter ^= type_parameters.TypeAt(i); 4076 type_parameter ^= type_parameters.TypeAt(i);
4054 name = type_parameter.Name(); 4077 name = type_parameter.Name();
4055 pieces.Add(name); 4078 pieces.Add(name);
4056 bound = bounds.TypeAt(i); 4079 bound = type_parameter.bound();
4057 if (!bound.IsNull() && !bound.IsDynamicType()) { 4080 if (!bound.IsNull() && !bound.IsDynamicType()) {
4058 pieces.Add(kSpaceExtendsSpace); 4081 pieces.Add(kSpaceExtendsSpace);
4059 name = bound.Name(); 4082 name = bound.Name();
4060 pieces.Add(name); 4083 pieces.Add(name);
4061 } 4084 }
4062 if (i < num_type_parameters - 1) { 4085 if (i < num_type_parameters - 1) {
4063 pieces.Add(kCommaSpace); 4086 pieces.Add(kCommaSpace);
4064 } 4087 }
4065 } 4088 }
4066 pieces.Add(kRAngleBracket); 4089 pieces.Add(kRAngleBracket);
(...skipping 3119 matching lines...) Expand 10 before | Expand all | Expand 10 after
7186 ASSERT(other.IsFinalized()); 7209 ASSERT(other.IsFinalized());
7187 ASSERT(!other.IsDynamicType()); 7210 ASSERT(!other.IsDynamicType());
7188 ASSERT(!other.IsVoidType()); 7211 ASSERT(!other.IsVoidType());
7189 ASSERT(!other.IsMalformed()); 7212 ASSERT(!other.IsMalformed());
7190 if (IsNull()) { 7213 if (IsNull()) {
7191 Class& other_class = Class::Handle(); 7214 Class& other_class = Class::Handle();
7192 if (other.IsTypeParameter()) { 7215 if (other.IsTypeParameter()) {
7193 if (other_instantiator.IsNull()) { 7216 if (other_instantiator.IsNull()) {
7194 return true; // Other type is uninstantiated, i.e. Dynamic. 7217 return true; // Other type is uninstantiated, i.e. Dynamic.
7195 } 7218 }
7196 const AbstractType& instantiated_other = 7219 // TODO(regis): Introduce and use TypeParameter::Cast().
7197 AbstractType::Handle(other_instantiator.TypeAt(other.Index())); 7220 const TypeParameter* other_type_param =
7221 reinterpret_cast<const TypeParameter*>(&other);
7222 const AbstractType& instantiated_other = AbstractType::Handle(
7223 other_instantiator.TypeAt(other_type_param->index()));
7198 ASSERT(instantiated_other.IsInstantiated()); 7224 ASSERT(instantiated_other.IsInstantiated());
7199 other_class = instantiated_other.type_class(); 7225 other_class = instantiated_other.type_class();
7200 } else { 7226 } else {
7201 other_class = other.type_class(); 7227 other_class = other.type_class();
7202 } 7228 }
7203 return other_class.IsObjectClass() || other_class.IsDynamicClass(); 7229 return other_class.IsObjectClass() || other_class.IsDynamicClass();
7204 } 7230 }
7205 const Class& cls = Class::Handle(clazz()); 7231 const Class& cls = Class::Handle(clazz());
7206 // We must not encounter Object::sentinel() or Object::transition_sentinel(), 7232 // We must not encounter Object::sentinel() or Object::transition_sentinel(),
7207 // both instances of class NullClass, but not instance Object::null(). 7233 // both instances of class NullClass, but not instance Object::null().
(...skipping 20 matching lines...) Expand all
7228 Class& other_class = Class::Handle(); 7254 Class& other_class = Class::Handle();
7229 AbstractTypeArguments& other_type_arguments = AbstractTypeArguments::Handle(); 7255 AbstractTypeArguments& other_type_arguments = AbstractTypeArguments::Handle();
7230 // In case 'other' is not instantiated, we could simply call 7256 // In case 'other' is not instantiated, we could simply call
7231 // other.InstantiateFrom(other_instantiator), however, we can save the 7257 // other.InstantiateFrom(other_instantiator), however, we can save the
7232 // allocation of a new AbstractType by inlining the code. 7258 // allocation of a new AbstractType by inlining the code.
7233 if (other.IsTypeParameter()) { 7259 if (other.IsTypeParameter()) {
7234 if (other_instantiator.IsNull()) { 7260 if (other_instantiator.IsNull()) {
7235 // An uninstantiated type parameter is equivalent to Dynamic. 7261 // An uninstantiated type parameter is equivalent to Dynamic.
7236 return true; 7262 return true;
7237 } 7263 }
7264 const TypeParameter* other_type_param =
7265 reinterpret_cast<const TypeParameter*>(&other);
7238 AbstractType& instantiated_other = AbstractType::Handle( 7266 AbstractType& instantiated_other = AbstractType::Handle(
7239 other_instantiator.TypeAt(other.Index())); 7267 other_instantiator.TypeAt(other_type_param->index()));
7240 if (instantiated_other.IsDynamicType() || 7268 if (instantiated_other.IsDynamicType() ||
7241 instantiated_other.IsTypeParameter()) { 7269 instantiated_other.IsTypeParameter()) {
7242 return true; 7270 return true;
7243 } 7271 }
7244 other_class = instantiated_other.type_class(); 7272 other_class = instantiated_other.type_class();
7245 other_type_arguments = instantiated_other.arguments(); 7273 other_type_arguments = instantiated_other.arguments();
7246 } else { 7274 } else {
7247 other_class = other.type_class(); 7275 other_class = other.type_class();
7248 other_type_arguments = other.arguments(); 7276 other_type_arguments = other.arguments();
7249 if (!other_type_arguments.IsNull() && 7277 if (!other_type_arguments.IsNull() &&
(...skipping 2994 matching lines...) Expand 10 before | Expand all | Expand 10 after
10244 const String& str = String::Handle(pattern()); 10272 const String& str = String::Handle(pattern());
10245 const char* format = "JSRegExp: pattern=%s flags=%s"; 10273 const char* format = "JSRegExp: pattern=%s flags=%s";
10246 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); 10274 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags());
10247 char* chars = reinterpret_cast<char*>( 10275 char* chars = reinterpret_cast<char*>(
10248 Isolate::Current()->current_zone()->Allocate(len + 1)); 10276 Isolate::Current()->current_zone()->Allocate(len + 1));
10249 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); 10277 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags());
10250 return chars; 10278 return chars;
10251 } 10279 }
10252 10280
10253 } // namespace dart 10281 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | runtime/vm/parser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698