Chromium Code Reviews| 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/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |