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

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

Issue 23190035: Distinguish between malformed and malbounded types (fix issues 12552 and 12554). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 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 "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/cpu.h" 10 #include "vm/cpu.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000, 54 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000,
55 "Huge method cutoff in unoptimized code size (in bytes)."); 55 "Huge method cutoff in unoptimized code size (in bytes).");
56 DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false, 56 DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false,
57 "Throw an exception when the result of an integer calculation will not " 57 "Throw an exception when the result of an integer calculation will not "
58 "fit into a javascript integer."); 58 "fit into a javascript integer.");
59 DECLARE_FLAG(bool, trace_compiler); 59 DECLARE_FLAG(bool, trace_compiler);
60 DECLARE_FLAG(bool, eliminate_type_checks); 60 DECLARE_FLAG(bool, eliminate_type_checks);
61 DECLARE_FLAG(bool, enable_type_checks); 61 DECLARE_FLAG(bool, enable_type_checks);
62 DECLARE_FLAG(bool, trace_deoptimization); 62 DECLARE_FLAG(bool, trace_deoptimization);
63 DECLARE_FLAG(bool, trace_deoptimization_verbose); 63 DECLARE_FLAG(bool, trace_deoptimization_verbose);
64 DECLARE_FLAG(bool, error_on_malformed_type);
64 DECLARE_FLAG(bool, error_on_bad_override); 65 DECLARE_FLAG(bool, error_on_bad_override);
65 66
66 static const char* kGetterPrefix = "get:"; 67 static const char* kGetterPrefix = "get:";
67 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); 68 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix);
68 static const char* kSetterPrefix = "set:"; 69 static const char* kSetterPrefix = "set:";
69 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); 70 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix);
70 71
71 cpp_vtable Object::handle_vtable_ = 0; 72 cpp_vtable Object::handle_vtable_ = 0;
72 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = { 0 }; 73 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = { 0 };
73 cpp_vtable Smi::handle_vtable_ = 0; 74 cpp_vtable Smi::handle_vtable_ = 0;
(...skipping 1670 matching lines...) Expand 10 before | Expand all | Expand 10 after
1744 // Return null otherwise. 1745 // Return null otherwise.
1745 RawTypeParameter* Class::LookupTypeParameter(const String& type_name) const { 1746 RawTypeParameter* Class::LookupTypeParameter(const String& type_name) const {
1746 ASSERT(!type_name.IsNull()); 1747 ASSERT(!type_name.IsNull());
1747 Isolate* isolate = Isolate::Current(); 1748 Isolate* isolate = Isolate::Current();
1748 ReusableHandleScope reused_handles(isolate); 1749 ReusableHandleScope reused_handles(isolate);
1749 TypeArguments& type_params = reused_handles.TypeArgumentsHandle(); 1750 TypeArguments& type_params = reused_handles.TypeArgumentsHandle();
1750 type_params ^= type_parameters(); 1751 type_params ^= type_parameters();
1751 TypeParameter& type_param = reused_handles.TypeParameterHandle(); 1752 TypeParameter& type_param = reused_handles.TypeParameterHandle();
1752 String& type_param_name = reused_handles.StringHandle(); 1753 String& type_param_name = reused_handles.StringHandle();
1753 if (!type_params.IsNull()) { 1754 if (!type_params.IsNull()) {
1754 intptr_t num_type_params = type_params.Length(); 1755 const intptr_t num_type_params = type_params.Length();
1755 for (intptr_t i = 0; i < num_type_params; i++) { 1756 for (intptr_t i = 0; i < num_type_params; i++) {
1756 type_param ^= type_params.TypeAt(i); 1757 type_param ^= type_params.TypeAt(i);
1757 type_param_name = type_param.name(); 1758 type_param_name = type_param.name();
1758 if (type_param_name.Equals(type_name)) { 1759 if (type_param_name.Equals(type_name)) {
1759 return type_param.raw(); 1760 return type_param.raw();
1760 } 1761 }
1761 } 1762 }
1762 } 1763 }
1763 return TypeParameter::null(); 1764 return TypeParameter::null();
1764 } 1765 }
(...skipping 1262 matching lines...) Expand 10 before | Expand all | Expand 10 after
3027 hash += hash << 3; 3028 hash += hash << 3;
3028 hash ^= hash >> 11; 3029 hash ^= hash >> 11;
3029 hash += hash << 15; 3030 hash += hash << 15;
3030 return hash; 3031 return hash;
3031 } 3032 }
3032 3033
3033 3034
3034 intptr_t AbstractTypeArguments::Hash() const { 3035 intptr_t AbstractTypeArguments::Hash() const {
3035 if (IsNull()) return 0; 3036 if (IsNull()) return 0;
3036 uword result = 0; 3037 uword result = 0;
3037 intptr_t num_types = Length(); 3038 const intptr_t num_types = Length();
3038 AbstractType& type = AbstractType::Handle(); 3039 AbstractType& type = AbstractType::Handle();
3039 for (intptr_t i = 0; i < num_types; i++) { 3040 for (intptr_t i = 0; i < num_types; i++) {
3040 type = TypeAt(i); 3041 type = TypeAt(i);
3041 result += type.Hash(); 3042 result += type.Hash();
3042 result += result << 10; 3043 result += result << 10;
3043 result ^= result >> 6; 3044 result ^= result >> 6;
3044 } 3045 }
3045 return FinalizeHash(result); 3046 return FinalizeHash(result);
3046 } 3047 }
3047 3048
(...skipping 25 matching lines...) Expand all
3073 3074
3074 3075
3075 bool AbstractTypeArguments::Equals(const AbstractTypeArguments& other) const { 3076 bool AbstractTypeArguments::Equals(const AbstractTypeArguments& other) const {
3076 ASSERT(!IsNull()); // Use AbstractTypeArguments::AreEqual(). 3077 ASSERT(!IsNull()); // Use AbstractTypeArguments::AreEqual().
3077 if (this->raw() == other.raw()) { 3078 if (this->raw() == other.raw()) {
3078 return true; 3079 return true;
3079 } 3080 }
3080 if (other.IsNull()) { 3081 if (other.IsNull()) {
3081 return false; 3082 return false;
3082 } 3083 }
3083 intptr_t num_types = Length(); 3084 const intptr_t num_types = Length();
3084 if (num_types != other.Length()) { 3085 if (num_types != other.Length()) {
3085 return false; 3086 return false;
3086 } 3087 }
3087 AbstractType& type = AbstractType::Handle(); 3088 AbstractType& type = AbstractType::Handle();
3088 AbstractType& other_type = AbstractType::Handle(); 3089 AbstractType& other_type = AbstractType::Handle();
3089 for (intptr_t i = 0; i < num_types; i++) { 3090 for (intptr_t i = 0; i < num_types; i++) {
3090 type = TypeAt(i); 3091 type = TypeAt(i);
3091 other_type = other.TypeAt(i); 3092 other_type = other.TypeAt(i);
3092 if (!type.Equals(other_type)) { 3093 if (!type.Equals(other_type)) {
3093 return false; 3094 return false;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
3202 3203
3203 3204
3204 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const { 3205 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const {
3205 ASSERT(!IsCanonical()); 3206 ASSERT(!IsCanonical());
3206 StorePointer(TypeAddr(index), value.raw()); 3207 StorePointer(TypeAddr(index), value.raw());
3207 } 3208 }
3208 3209
3209 3210
3210 bool TypeArguments::IsResolved() const { 3211 bool TypeArguments::IsResolved() const {
3211 AbstractType& type = AbstractType::Handle(); 3212 AbstractType& type = AbstractType::Handle();
3212 intptr_t num_types = Length(); 3213 const intptr_t num_types = Length();
3213 for (intptr_t i = 0; i < num_types; i++) { 3214 for (intptr_t i = 0; i < num_types; i++) {
3214 type = TypeAt(i); 3215 type = TypeAt(i);
3215 if (!type.IsResolved()) { 3216 if (!type.IsResolved()) {
3216 return false; 3217 return false;
3217 } 3218 }
3218 } 3219 }
3219 return true; 3220 return true;
3220 } 3221 }
3221 3222
3222 3223
3223 bool TypeArguments::IsInstantiated() const { 3224 bool TypeArguments::IsInstantiated() const {
3224 AbstractType& type = AbstractType::Handle(); 3225 AbstractType& type = AbstractType::Handle();
3225 intptr_t num_types = Length(); 3226 const intptr_t num_types = Length();
3226 for (intptr_t i = 0; i < num_types; i++) { 3227 for (intptr_t i = 0; i < num_types; i++) {
3227 type = TypeAt(i); 3228 type = TypeAt(i);
3228 ASSERT(!type.IsNull()); 3229 ASSERT(!type.IsNull());
3229 if (!type.IsInstantiated()) { 3230 if (!type.IsInstantiated()) {
3230 return false; 3231 return false;
3231 } 3232 }
3232 } 3233 }
3233 return true; 3234 return true;
3234 } 3235 }
3235 3236
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3313 if (!type_arg.Equals(super_type_arg)) { 3314 if (!type_arg.Equals(super_type_arg)) {
3314 return false; 3315 return false;
3315 } 3316 }
3316 } 3317 }
3317 return true; 3318 return true;
3318 } 3319 }
3319 3320
3320 3321
3321 bool TypeArguments::IsBounded() const { 3322 bool TypeArguments::IsBounded() const {
3322 AbstractType& type = AbstractType::Handle(); 3323 AbstractType& type = AbstractType::Handle();
3323 intptr_t num_types = Length(); 3324 const intptr_t num_types = Length();
3324 for (intptr_t i = 0; i < num_types; i++) { 3325 for (intptr_t i = 0; i < num_types; i++) {
3325 type = TypeAt(i); 3326 type = TypeAt(i);
3326 if (type.IsBoundedType()) { 3327 if (type.IsBoundedType()) {
3327 return true; 3328 return true;
3328 } 3329 }
3329 if (type.IsTypeParameter()) { 3330 if (type.IsTypeParameter()) {
3330 const AbstractType& bound = AbstractType::Handle( 3331 const AbstractType& bound = AbstractType::Handle(
3331 TypeParameter::Cast(type).bound()); 3332 TypeParameter::Cast(type).bound());
3332 if (!bound.IsObjectType() && !bound.IsDynamicType()) { 3333 if (!bound.IsObjectType() && !bound.IsDynamicType()) {
3333 return true; 3334 return true;
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after
4759 // (e.g. "Map<K, V>(K) => bool"). In case of a function type alias, the 4760 // (e.g. "Map<K, V>(K) => bool"). In case of a function type alias, the
4760 // signature class name is the alias name. 4761 // signature class name is the alias name.
4761 // The signature of static functions cannot be type parameterized. 4762 // The signature of static functions cannot be type parameterized.
4762 const Class& function_class = Class::Handle(Owner()); 4763 const Class& function_class = Class::Handle(Owner());
4763 ASSERT(!function_class.IsNull()); 4764 ASSERT(!function_class.IsNull());
4764 const TypeArguments& type_parameters = TypeArguments::Handle( 4765 const TypeArguments& type_parameters = TypeArguments::Handle(
4765 function_class.type_parameters()); 4766 function_class.type_parameters());
4766 if (!type_parameters.IsNull()) { 4767 if (!type_parameters.IsNull()) {
4767 const String& function_class_name = String::Handle(function_class.Name()); 4768 const String& function_class_name = String::Handle(function_class.Name());
4768 pieces.Add(function_class_name); 4769 pieces.Add(function_class_name);
4769 intptr_t num_type_parameters = type_parameters.Length(); 4770 const intptr_t num_type_parameters = type_parameters.Length();
4770 pieces.Add(Symbols::LAngleBracket()); 4771 pieces.Add(Symbols::LAngleBracket());
4771 TypeParameter& type_parameter = TypeParameter::Handle(); 4772 TypeParameter& type_parameter = TypeParameter::Handle();
4772 AbstractType& bound = AbstractType::Handle(); 4773 AbstractType& bound = AbstractType::Handle();
4773 for (intptr_t i = 0; i < num_type_parameters; i++) { 4774 for (intptr_t i = 0; i < num_type_parameters; i++) {
4774 type_parameter ^= type_parameters.TypeAt(i); 4775 type_parameter ^= type_parameters.TypeAt(i);
4775 name = type_parameter.name(); 4776 name = type_parameter.name();
4776 pieces.Add(name); 4777 pieces.Add(name);
4777 bound = type_parameter.bound(); 4778 bound = type_parameter.bound();
4778 if (!bound.IsNull() && !bound.IsObjectType()) { 4779 if (!bound.IsNull() && !bound.IsObjectType()) {
4779 pieces.Add(Symbols::SpaceExtendsSpace()); 4780 pieces.Add(Symbols::SpaceExtendsSpace());
(...skipping 3543 matching lines...) Expand 10 before | Expand all | Expand 10 after
8323 RawExceptionHandlers::HandlerInfo info; 8324 RawExceptionHandlers::HandlerInfo info;
8324 // First compute the buffer size required. 8325 // First compute the buffer size required.
8325 const char* kFormat = "%" Pd " => %#" Px " (%" Pd 8326 const char* kFormat = "%" Pd " => %#" Px " (%" Pd
8326 " types) (outer %" Pd ")\n"; 8327 " types) (outer %" Pd ")\n";
8327 const char* kFormat2 = " %d. %s\n"; 8328 const char* kFormat2 = " %d. %s\n";
8328 intptr_t len = 1; // Trailing '\0'. 8329 intptr_t len = 1; // Trailing '\0'.
8329 for (intptr_t i = 0; i < Length(); i++) { 8330 for (intptr_t i = 0; i < Length(); i++) {
8330 GetHandlerInfo(i, &info); 8331 GetHandlerInfo(i, &info);
8331 handled_types = GetHandledTypes(i); 8332 handled_types = GetHandledTypes(i);
8332 ASSERT(!handled_types.IsNull()); 8333 ASSERT(!handled_types.IsNull());
8333 intptr_t num_types = handled_types.Length(); 8334 const intptr_t num_types = handled_types.Length();
8334 len += OS::SNPrint(NULL, 0, kFormat, 8335 len += OS::SNPrint(NULL, 0, kFormat,
8335 i, 8336 i,
8336 info.handler_pc, 8337 info.handler_pc,
8337 num_types, 8338 num_types,
8338 info.outer_try_index); 8339 info.outer_try_index);
8339 for (int k = 0; k < num_types; k++) { 8340 for (int k = 0; k < num_types; k++) {
8340 type ^= handled_types.At(k); 8341 type ^= handled_types.At(k);
8341 ASSERT(!type.IsNull()); 8342 ASSERT(!type.IsNull());
8342 len += OS::SNPrint(NULL, 0, kFormat2, k, type.ToCString()); 8343 len += OS::SNPrint(NULL, 0, kFormat2, k, type.ToCString());
8343 } 8344 }
8344 } 8345 }
8345 // Allocate the buffer. 8346 // Allocate the buffer.
8346 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len); 8347 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len);
8347 // Layout the fields in the buffer. 8348 // Layout the fields in the buffer.
8348 intptr_t num_chars = 0; 8349 intptr_t num_chars = 0;
8349 for (intptr_t i = 0; i < Length(); i++) { 8350 for (intptr_t i = 0; i < Length(); i++) {
8350 GetHandlerInfo(i, &info); 8351 GetHandlerInfo(i, &info);
8351 handled_types = GetHandledTypes(i); 8352 handled_types = GetHandledTypes(i);
8352 intptr_t num_types = handled_types.Length(); 8353 const intptr_t num_types = handled_types.Length();
8353 num_chars += OS::SNPrint((buffer + num_chars), 8354 num_chars += OS::SNPrint((buffer + num_chars),
8354 (len - num_chars), 8355 (len - num_chars),
8355 kFormat, 8356 kFormat,
8356 i, 8357 i,
8357 info.handler_pc, 8358 info.handler_pc,
8358 num_types, 8359 num_types,
8359 info.outer_try_index); 8360 info.outer_try_index);
8360 for (int k = 0; k < num_types; k++) { 8361 for (int k = 0; k < num_types; k++) {
8361 type ^= handled_types.At(k); 8362 type ^= handled_types.At(k);
8362 num_chars += OS::SNPrint((buffer + num_chars), 8363 num_chars += OS::SNPrint((buffer + num_chars),
(...skipping 1858 matching lines...) Expand 10 before | Expand all | Expand 10 after
10221 10222
10222 10223
10223 void Instance::SetTypeArguments(const AbstractTypeArguments& value) const { 10224 void Instance::SetTypeArguments(const AbstractTypeArguments& value) const {
10224 const Class& cls = Class::Handle(clazz()); 10225 const Class& cls = Class::Handle(clazz());
10225 intptr_t field_offset = cls.type_arguments_field_offset(); 10226 intptr_t field_offset = cls.type_arguments_field_offset();
10226 ASSERT(field_offset != Class::kNoTypeArguments); 10227 ASSERT(field_offset != Class::kNoTypeArguments);
10227 SetFieldAtOffset(field_offset, value); 10228 SetFieldAtOffset(field_offset, value);
10228 } 10229 }
10229 10230
10230 10231
10232 // TODO(regis): Rename malformed_error to bound_error.
10231 bool Instance::IsInstanceOf(const AbstractType& other, 10233 bool Instance::IsInstanceOf(const AbstractType& other,
10232 const AbstractTypeArguments& other_instantiator, 10234 const AbstractTypeArguments& other_instantiator,
10233 Error* malformed_error) const { 10235 Error* malformed_error) const {
10234 ASSERT(other.IsFinalized()); 10236 ASSERT(other.IsFinalized());
10235 ASSERT(!other.IsDynamicType()); 10237 ASSERT(!other.IsDynamicType());
10236 ASSERT(!other.IsMalformed()); 10238 ASSERT(!other.IsMalformed());
10239 ASSERT(!other.IsMalbounded(NULL));
10237 if (other.IsVoidType()) { 10240 if (other.IsVoidType()) {
10238 return false; 10241 return false;
10239 } 10242 }
10240 const Class& cls = Class::Handle(clazz()); 10243 const Class& cls = Class::Handle(clazz());
10241 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); 10244 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle();
10242 const intptr_t num_type_arguments = cls.NumTypeArguments(); 10245 const intptr_t num_type_arguments = cls.NumTypeArguments();
10243 if (num_type_arguments > 0) { 10246 if (num_type_arguments > 0) {
10244 type_arguments = GetTypeArguments(); 10247 type_arguments = GetTypeArguments();
10245 if (!type_arguments.IsNull() && !type_arguments.IsCanonical()) { 10248 if (!type_arguments.IsNull() && !type_arguments.IsCanonical()) {
10246 type_arguments = type_arguments.Canonicalize(); 10249 type_arguments = type_arguments.Canonicalize();
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
10453 } 10456 }
10454 10457
10455 10458
10456 bool AbstractType::IsMalformed() const { 10459 bool AbstractType::IsMalformed() const {
10457 // AbstractType is an abstract class. 10460 // AbstractType is an abstract class.
10458 UNREACHABLE(); 10461 UNREACHABLE();
10459 return false; 10462 return false;
10460 } 10463 }
10461 10464
10462 10465
10466 bool AbstractType::IsMalbounded(Error* error) const {
10467 // AbstractType is an abstract class.
10468 UNREACHABLE();
10469 return false;
10470 }
10471
10472
10463 RawError* AbstractType::malformed_error() const { 10473 RawError* AbstractType::malformed_error() const {
10464 // AbstractType is an abstract class. 10474 // AbstractType is an abstract class.
10465 UNREACHABLE(); 10475 UNREACHABLE();
10466 return Error::null(); 10476 return Error::null();
10467 } 10477 }
10468 10478
10469 10479
10470 void AbstractType::set_malformed_error(const Error& value) const { 10480 void AbstractType::set_malformed_error(const Error& value) const {
10471 // AbstractType is an abstract class. 10481 // AbstractType is an abstract class.
10472 UNREACHABLE(); 10482 UNREACHABLE();
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
10850 ASSERT(!IsFinalized() && !IsBeingFinalized()); 10860 ASSERT(!IsFinalized() && !IsBeingFinalized());
10851 set_type_state(RawType::kBeingFinalized); 10861 set_type_state(RawType::kBeingFinalized);
10852 } 10862 }
10853 10863
10854 10864
10855 bool Type::IsMalformed() const { 10865 bool Type::IsMalformed() const {
10856 return raw_ptr()->malformed_error_ != Error::null(); 10866 return raw_ptr()->malformed_error_ != Error::null();
10857 } 10867 }
10858 10868
10859 10869
10870 bool Type::IsMalbounded(Error* bound_error) const {
10871 if (!FLAG_enable_type_checks && !FLAG_error_on_malformed_type) {
10872 return false;
10873 }
10874 ASSERT(IsFinalized());
10875 ASSERT(!IsMalformed()); // Must be checked first.
10876 AbstractTypeArguments& type_arguments =
10877 AbstractTypeArguments::Handle(arguments());
10878 if (type_arguments.IsNull()) {
hausner 2013/08/23 16:55:23 You could avoid this handle allocation by comparin
regis 2013/08/26 17:44:57 Done.
10879 return false;
10880 }
10881 const intptr_t num_type_args = type_arguments.Length();
10882 AbstractType& type_arg = AbstractType::Handle();
10883 for (intptr_t i = 0; i < num_type_args; i++) {
10884 type_arg = type_arguments.TypeAt(i);
10885 ASSERT(!type_arg.IsNull());
10886 if (type_arg.IsMalbounded(bound_error)) {
10887 return true;
10888 }
10889 }
10890 return false;
10891 }
10892
10893
10860 void Type::set_malformed_error(const Error& value) const { 10894 void Type::set_malformed_error(const Error& value) const {
10861 StorePointer(&raw_ptr()->malformed_error_, value.raw()); 10895 StorePointer(&raw_ptr()->malformed_error_, value.raw());
10862 } 10896 }
10863 10897
10864 10898
10865 RawError* Type::malformed_error() const { 10899 RawError* Type::malformed_error() const {
10866 ASSERT(IsMalformed()); 10900 ASSERT(IsMalformed());
10867 return raw_ptr()->malformed_error_; 10901 return raw_ptr()->malformed_error_;
10868 } 10902 }
10869 10903
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
11223 if (instantiator_type_arguments.IsNull()) { 11257 if (instantiator_type_arguments.IsNull()) {
11224 return Type::DynamicType(); 11258 return Type::DynamicType();
11225 } 11259 }
11226 // Bound checks may appear in the instantiator type arguments, as is the case 11260 // Bound checks may appear in the instantiator type arguments, as is the case
11227 // with a pair of type parameters of the same class referring to each other 11261 // with a pair of type parameters of the same class referring to each other
11228 // via their bounds. 11262 // via their bounds.
11229 AbstractType& type_arg = AbstractType::Handle( 11263 AbstractType& type_arg = AbstractType::Handle(
11230 instantiator_type_arguments.TypeAt(index())); 11264 instantiator_type_arguments.TypeAt(index()));
11231 if (type_arg.IsBoundedType()) { 11265 if (type_arg.IsBoundedType()) {
11232 const BoundedType& bounded_type = BoundedType::Cast(type_arg); 11266 const BoundedType& bounded_type = BoundedType::Cast(type_arg);
11233 ASSERT(!bounded_type.IsInstantiated()); 11267 // Bounds checking of a type is postponed to run time if the type is still
11234 ASSERT(AbstractType::Handle(bounded_type.bound()).IsInstantiated()); 11268 // uninstantiated at compile time, or if the bound and the type are mutually
11235 type_arg = bounded_type.InstantiateFrom(AbstractTypeArguments::Handle(), 11269 // recursive. In the latter case, the type may already be instantiated.
11236 malformed_error); 11270 if (!bounded_type.IsInstantiated()) {
11271 ASSERT(AbstractType::Handle(bounded_type.bound()).IsInstantiated());
11272 type_arg = bounded_type.InstantiateFrom(AbstractTypeArguments::Handle(),
11273 malformed_error);
11274 }
11237 } 11275 }
11238 return type_arg.raw(); 11276 return type_arg.raw();
11239 } 11277 }
11240 11278
11241 11279
11242 bool TypeParameter::CheckBound(const AbstractType& bounded_type, 11280 bool TypeParameter::CheckBound(const AbstractType& bounded_type,
11243 const AbstractType& upper_bound, 11281 const AbstractType& upper_bound,
11244 Error* malformed_error) const { 11282 Error* malformed_error) const {
11245 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); 11283 ASSERT((malformed_error == NULL) || malformed_error->IsNull());
11246 ASSERT(bounded_type.IsFinalized()); 11284 ASSERT(bounded_type.IsFinalized());
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
11343 } 11381 }
11344 11382
11345 11383
11346 void TypeParameter::PrintToJSONStream(JSONStream* stream, bool ref) const { 11384 void TypeParameter::PrintToJSONStream(JSONStream* stream, bool ref) const {
11347 stream->OpenObject(); 11385 stream->OpenObject();
11348 stream->CloseObject(); 11386 stream->CloseObject();
11349 } 11387 }
11350 11388
11351 11389
11352 bool BoundedType::IsMalformed() const { 11390 bool BoundedType::IsMalformed() const {
11353 return FLAG_enable_type_checks && AbstractType::Handle(bound()).IsMalformed(); 11391 return AbstractType::Handle(type()).IsMalformed();
11392 }
11393
11394
11395 bool BoundedType::IsMalbounded(Error* bound_error) const {
11396 if (!FLAG_enable_type_checks && !FLAG_error_on_malformed_type) {
11397 return false;
11398 }
11399 const AbstractType& upper_bound = AbstractType::Handle(bound());
11400 if (upper_bound.IsMalformed()) {
11401 if (bound_error != NULL) {
11402 *bound_error = upper_bound.malformed_error();
11403 ASSERT(!bound_error->IsNull());
11404 }
11405 return true;
11406 }
11407 return false;
11354 } 11408 }
11355 11409
11356 11410
11357 RawError* BoundedType::malformed_error() const { 11411 RawError* BoundedType::malformed_error() const {
11358 ASSERT(FLAG_enable_type_checks); 11412 return AbstractType::Handle(type()).malformed_error();
11359 return AbstractType::Handle(bound()).malformed_error();
11360 } 11413 }
11361 11414
11362 11415
11363 bool BoundedType::Equals(const Instance& other) const { 11416 bool BoundedType::Equals(const Instance& other) const {
11364 // BoundedType are not canonicalized, because their bound may get finalized 11417 // BoundedType are not canonicalized, because their bound may get finalized
11365 // after the BoundedType is created and initialized. 11418 // after the BoundedType is created and initialized.
11366 if (raw() == other.raw()) { 11419 if (raw() == other.raw()) {
11367 return true; 11420 return true;
11368 } 11421 }
11369 if (!other.IsBoundedType()) { 11422 if (!other.IsBoundedType()) {
(...skipping 3404 matching lines...) Expand 10 before | Expand all | Expand 10 after
14774 } 14827 }
14775 14828
14776 14829
14777 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 14830 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
14778 stream->OpenObject(); 14831 stream->OpenObject();
14779 stream->CloseObject(); 14832 stream->CloseObject();
14780 } 14833 }
14781 14834
14782 14835
14783 } // namespace dart 14836 } // namespace dart
OLDNEW
« runtime/vm/object.h ('K') | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698