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

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

Issue 10280007: Check upper bounds of type arguments when allocating objects of a generic type (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 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
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2184 matching lines...) Expand 10 before | Expand all | Expand 10 after
2195 return false; 2195 return false;
2196 } 2196 }
2197 if (other.IsMalformed()) { 2197 if (other.IsMalformed()) {
2198 ASSERT(FLAG_enable_type_checks); 2198 ASSERT(FLAG_enable_type_checks);
2199 if (malformed_error->IsNull()) { 2199 if (malformed_error->IsNull()) {
2200 *malformed_error = other.malformed_error(); 2200 *malformed_error = other.malformed_error();
2201 } 2201 }
2202 return false; 2202 return false;
2203 } 2203 }
2204 // AbstractType parameters cannot be handled by Class::IsSubtypeOf(). 2204 // AbstractType parameters cannot be handled by Class::IsSubtypeOf().
2205 // When comparing two uninstantiated function types, one returning type
2206 // parameter K, the other returning type parameter V, we cannot assume that K
2207 // is a subtype of V, or vice versa. We only return true if K == V, i.e. if
2208 // they have the same index (both are finalized, so their indices are
2209 // comparable).
2210 // The same rule applies When checking the upper bound of a still
2211 // uninstantiated type at compile time. Returning false will defer the test
2212 // to run time. But there are cases where it can be decided at compile time.
2213 // For example, with class A<K, V extends K>, new A<T, T> called from within
2214 // a class B<T> will never require a run time bounds check, even it T is
2215 // uninstantiated at compile time.
2205 if (IsTypeParameter() || other.IsTypeParameter()) { 2216 if (IsTypeParameter() || other.IsTypeParameter()) {
2206 // An uninstantiated type parameter is equivalent to Dynamic. 2217 return IsTypeParameter() && other.IsTypeParameter() &&
2207 return true; 2218 (Index() == other.Index());
2208 } 2219 }
2209 const Class& cls = Class::Handle(type_class()); 2220 const Class& cls = Class::Handle(type_class());
2210 return cls.IsSubtypeOf(AbstractTypeArguments::Handle(arguments()), 2221 return cls.IsSubtypeOf(AbstractTypeArguments::Handle(arguments()),
2211 Class::Handle(other.type_class()), 2222 Class::Handle(other.type_class()),
2212 AbstractTypeArguments::Handle(other.arguments()), 2223 AbstractTypeArguments::Handle(other.arguments()),
2213 malformed_error); 2224 malformed_error);
2214 } 2225 }
2215 2226
2216 RawAbstractType* AbstractType::NewTypeParameter(const Class& clazz, 2227 RawAbstractType* AbstractType::NewTypeParameter(const Class& clazz,
2217 intptr_t index, 2228 intptr_t index,
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
2622 2633
2623 bool TypeParameter::IsIdentical(const AbstractType& other) const { 2634 bool TypeParameter::IsIdentical(const AbstractType& other) const {
2624 if (raw() == other.raw()) { 2635 if (raw() == other.raw()) {
2625 return true; 2636 return true;
2626 } 2637 }
2627 if (!other.IsTypeParameter()) { 2638 if (!other.IsTypeParameter()) {
2628 return false; 2639 return false;
2629 } 2640 }
2630 TypeParameter& other_type_param = TypeParameter::Handle(); 2641 TypeParameter& other_type_param = TypeParameter::Handle();
2631 other_type_param ^= other.raw(); 2642 other_type_param ^= other.raw();
2632 // Both type parameters may have different type_class and their index may be 2643 // IsIdentical may be called on type parameters belonging to different
2633 // different after finalization, which is OK. Do not check. 2644 // classes, e.g. to an interface and to its default factory class.
2645 // Therefore, both type parameters may have different parameterized classes
2646 // and different indices. Compare the type parameter names only.
2634 String& name = String::Handle(Name()); 2647 String& name = String::Handle(Name());
2635 String& other_name = String::Handle(other_type_param.Name()); 2648 String& other_name = String::Handle(other_type_param.Name());
2636 return name.Equals(other_name); 2649 return name.Equals(other_name);
2637 } 2650 }
2638 2651
2639 2652
2640 void TypeParameter::set_parameterized_class(const Class& value) const { 2653 void TypeParameter::set_parameterized_class(const Class& value) const {
2641 // Set value may be null. 2654 // Set value may be null.
2642 StorePointer(&raw_ptr()->parameterized_class_, value.raw()); 2655 StorePointer(&raw_ptr()->parameterized_class_, value.raw());
2643 } 2656 }
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
2952 "Error", format, args); 2965 "Error", format, args);
2953 } 2966 }
2954 } 2967 }
2955 2968
2956 2969
2957 bool AbstractTypeArguments::IsWithinBoundsOf( 2970 bool AbstractTypeArguments::IsWithinBoundsOf(
2958 const Class& cls, 2971 const Class& cls,
2959 const AbstractTypeArguments& bounds_instantiator, 2972 const AbstractTypeArguments& bounds_instantiator,
2960 Error* malformed_error) const { 2973 Error* malformed_error) const {
2961 ASSERT(FLAG_enable_type_checks); 2974 ASSERT(FLAG_enable_type_checks);
2962 ASSERT(IsInstantiated()); 2975 // This function may be called at compile time on (partially) uninstantiated
2976 // type arguments and may return true, in which case a run time bounds check
2977 // can be avoided.
2963 ASSERT(Length() >= cls.NumTypeArguments()); 2978 ASSERT(Length() >= cls.NumTypeArguments());
2964 const intptr_t num_type_params = cls.NumTypeParameters(); 2979 const intptr_t num_type_params = cls.NumTypeParameters();
2965 const intptr_t offset = cls.NumTypeArguments() - num_type_params; 2980 const intptr_t offset = cls.NumTypeArguments() - num_type_params;
2966 AbstractType& type = AbstractType::Handle(); 2981 AbstractType& type = AbstractType::Handle();
2967 AbstractType& bound = AbstractType::Handle(); 2982 AbstractType& bound = AbstractType::Handle();
2968 const TypeArguments& bounds = 2983 const TypeArguments& bounds =
2969 TypeArguments::Handle(cls.type_parameter_bounds()); 2984 TypeArguments::Handle(cls.type_parameter_bounds());
2970 ASSERT((bounds.IsNull() && (num_type_params == 0)) || 2985 ASSERT((bounds.IsNull() && (num_type_params == 0)) ||
2971 (bounds.Length() == num_type_params)); 2986 (bounds.Length() == num_type_params));
2972 for (intptr_t i = 0; i < num_type_params; i++) { 2987 for (intptr_t i = 0; i < num_type_params; i++) {
(...skipping 6316 matching lines...) Expand 10 before | Expand all | Expand 10 after
9289 const String& str = String::Handle(pattern()); 9304 const String& str = String::Handle(pattern());
9290 const char* format = "JSRegExp: pattern=%s flags=%s"; 9305 const char* format = "JSRegExp: pattern=%s flags=%s";
9291 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); 9306 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags());
9292 char* chars = reinterpret_cast<char*>( 9307 char* chars = reinterpret_cast<char*>(
9293 Isolate::Current()->current_zone()->Allocate(len + 1)); 9308 Isolate::Current()->current_zone()->Allocate(len + 1));
9294 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); 9309 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags());
9295 return chars; 9310 return chars;
9296 } 9311 }
9297 9312
9298 } // namespace dart 9313 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698