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 4825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4836 const char* Function::ToFullyQualifiedCString() const { | 4836 const char* Function::ToFullyQualifiedCString() const { |
4837 char* chars = NULL; | 4837 char* chars = NULL; |
4838 ConstructFunctionFullyQualifiedCString(*this, &chars, 0); | 4838 ConstructFunctionFullyQualifiedCString(*this, &chars, 0); |
4839 return chars; | 4839 return chars; |
4840 } | 4840 } |
4841 | 4841 |
4842 | 4842 |
4843 bool Function::HasCompatibleParametersWith(const Function& other, | 4843 bool Function::HasCompatibleParametersWith(const Function& other, |
4844 Error* bound_error) const { | 4844 Error* bound_error) const { |
4845 ASSERT(FLAG_error_on_bad_override); | 4845 ASSERT(FLAG_error_on_bad_override); |
| 4846 ASSERT((bound_error != NULL) && bound_error->IsNull()); |
4846 // Check that this function's signature type is a subtype of the other | 4847 // Check that this function's signature type is a subtype of the other |
4847 // function's signature type. | 4848 // function's signature type. |
4848 if (!TypeTest(kIsSubtypeOf, Object::null_abstract_type_arguments(), | 4849 if (!TypeTest(kIsSubtypeOf, Object::null_abstract_type_arguments(), |
4849 other, Object::null_abstract_type_arguments(), bound_error)) { | 4850 other, Object::null_abstract_type_arguments(), bound_error)) { |
4850 // For more informative error reporting, use the location of the other | 4851 // For more informative error reporting, use the location of the other |
4851 // function here, since the caller will use the location of this function. | 4852 // function here, since the caller will use the location of this function. |
4852 *bound_error = FormatError( | 4853 *bound_error = FormatError( |
4853 *bound_error, // A bound error if non null. | 4854 *bound_error, // A bound error if non null. |
4854 Script::Handle(other.script()), | 4855 Script::Handle(other.script()), |
4855 other.token_pos(), | 4856 other.token_pos(), |
(...skipping 6444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11300 | 11301 |
11301 RawAbstractType* AbstractType::Canonicalize() const { | 11302 RawAbstractType* AbstractType::Canonicalize() const { |
11302 // AbstractType is an abstract class. | 11303 // AbstractType is an abstract class. |
11303 UNREACHABLE(); | 11304 UNREACHABLE(); |
11304 return NULL; | 11305 return NULL; |
11305 } | 11306 } |
11306 | 11307 |
11307 | 11308 |
11308 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { | 11309 RawString* AbstractType::BuildName(NameVisibility name_visibility) const { |
11309 if (IsBoundedType()) { | 11310 if (IsBoundedType()) { |
11310 // TODO(regis): Should the bound be visible in the name for debug purposes | |
11311 // if name_visibility is kInternalName? | |
11312 const AbstractType& type = AbstractType::Handle( | 11311 const AbstractType& type = AbstractType::Handle( |
11313 BoundedType::Cast(*this).type()); | 11312 BoundedType::Cast(*this).type()); |
11314 return type.BuildName(name_visibility); | 11313 if (name_visibility == kUserVisibleName) { |
| 11314 return type.BuildName(kUserVisibleName); |
| 11315 } |
| 11316 String& type_name = String::Handle(type.BuildName(kInternalName)); |
| 11317 type_name = String::Concat(type_name, Symbols::SpaceExtendsSpace()); |
| 11318 // Building the bound name may lead into cycles. |
| 11319 const AbstractType& bound = AbstractType::Handle( |
| 11320 BoundedType::Cast(*this).bound()); |
| 11321 String& bound_name = String::Handle(); |
| 11322 if (bound.IsTypeParameter()) { |
| 11323 bound_name = TypeParameter::Cast(bound).name(); |
| 11324 } else if (bound.IsType()) { |
| 11325 const Class& cls = Class::Handle(Type::Cast(bound).type_class()); |
| 11326 bound_name = cls.Name(); |
| 11327 if (Type::Cast(bound).arguments() != AbstractTypeArguments::null()) { |
| 11328 bound_name = String::Concat(bound_name, Symbols::OptimizedOut()); |
| 11329 } |
| 11330 } else { |
| 11331 bound_name = String::New(Symbols::OptimizedOut()); |
| 11332 } |
| 11333 type_name = String::Concat(type_name, bound_name); |
| 11334 return Symbols::New(type_name); |
11315 } | 11335 } |
11316 if (IsTypeParameter()) { | 11336 if (IsTypeParameter()) { |
11317 return TypeParameter::Cast(*this).name(); | 11337 return TypeParameter::Cast(*this).name(); |
11318 } | 11338 } |
11319 // If the type is still being finalized, we may be reporting an error about | 11339 // If the type is still being finalized, we may be reporting an error about |
11320 // a malformed type, so proceed with caution. | 11340 // a malformed type, so proceed with caution. |
11321 const AbstractTypeArguments& args = | 11341 const AbstractTypeArguments& args = |
11322 AbstractTypeArguments::Handle(arguments()); | 11342 AbstractTypeArguments::Handle(arguments()); |
11323 const intptr_t num_args = args.IsNull() ? 0 : args.Length(); | 11343 const intptr_t num_args = args.IsNull() ? 0 : args.Length(); |
11324 String& class_name = String::Handle(); | 11344 String& class_name = String::Handle(); |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12063 } | 12083 } |
12064 | 12084 |
12065 | 12085 |
12066 RawAbstractType* TypeParameter::InstantiateFrom( | 12086 RawAbstractType* TypeParameter::InstantiateFrom( |
12067 const AbstractTypeArguments& instantiator_type_arguments, | 12087 const AbstractTypeArguments& instantiator_type_arguments, |
12068 Error* bound_error) const { | 12088 Error* bound_error) const { |
12069 ASSERT(IsFinalized()); | 12089 ASSERT(IsFinalized()); |
12070 if (instantiator_type_arguments.IsNull()) { | 12090 if (instantiator_type_arguments.IsNull()) { |
12071 return Type::DynamicType(); | 12091 return Type::DynamicType(); |
12072 } | 12092 } |
12073 // Bound checks may appear in the instantiator type arguments, as is the case | 12093 return instantiator_type_arguments.TypeAt(index()); |
12074 // with a pair of type parameters of the same class referring to each other | |
12075 // via their bounds. | |
12076 AbstractType& type_arg = AbstractType::Handle( | |
12077 instantiator_type_arguments.TypeAt(index())); | |
12078 if (type_arg.IsBoundedType()) { | |
12079 const BoundedType& bounded_type = BoundedType::Cast(type_arg); | |
12080 // Bounds checking of a type is postponed to run time if the type is still | |
12081 // uninstantiated at compile time, or if the bound and the type are mutually | |
12082 // recursive. In the latter case, the type may already be instantiated. | |
12083 if (!bounded_type.IsInstantiated()) { | |
12084 ASSERT(AbstractType::Handle(bounded_type.bound()).IsInstantiated()); | |
12085 type_arg = bounded_type.InstantiateFrom(AbstractTypeArguments::Handle(), | |
12086 bound_error); | |
12087 } | |
12088 } | |
12089 return type_arg.raw(); | |
12090 } | 12094 } |
12091 | 12095 |
12092 | 12096 |
12093 bool TypeParameter::CheckBound(const AbstractType& bounded_type, | 12097 bool TypeParameter::CheckBound(const AbstractType& bounded_type, |
12094 const AbstractType& upper_bound, | 12098 const AbstractType& upper_bound, |
12095 Error* bound_error) const { | 12099 Error* bound_error) const { |
12096 ASSERT((bound_error == NULL) || bound_error->IsNull()); | 12100 ASSERT((bound_error != NULL) && bound_error->IsNull()); |
12097 ASSERT(bounded_type.IsFinalized()); | 12101 ASSERT(bounded_type.IsFinalized()); |
12098 ASSERT(upper_bound.IsFinalized()); | 12102 ASSERT(upper_bound.IsFinalized()); |
12099 ASSERT(!bounded_type.IsMalformed()); | 12103 ASSERT(!bounded_type.IsMalformed()); |
12100 if (bounded_type.IsSubtypeOf(upper_bound, bound_error)) { | 12104 if (bounded_type.IsSubtypeOf(upper_bound, bound_error)) { |
12101 return true; | 12105 return true; |
12102 } | 12106 } |
12103 if ((bound_error != NULL) && bound_error->IsNull()) { | 12107 if (bound_error->IsNull()) { |
12104 // Report the bound error. | 12108 // Report the bound error only if both the bounded type and the upper bound |
12105 const String& bounded_type_name = String::Handle( | 12109 // are instantiated. Otherwise, we cannot tell yet it is a bound error. |
12106 bounded_type.UserVisibleName()); | 12110 if (bounded_type.IsInstantiated() && upper_bound.IsInstantiated()) { |
12107 const String& upper_bound_name = String::Handle( | 12111 const String& bounded_type_name = String::Handle( |
12108 upper_bound.UserVisibleName()); | 12112 bounded_type.UserVisibleName()); |
12109 const AbstractType& declared_bound = AbstractType::Handle(bound()); | 12113 const String& upper_bound_name = String::Handle( |
12110 const String& declared_bound_name = String::Handle( | 12114 upper_bound.UserVisibleName()); |
12111 declared_bound.UserVisibleName()); | 12115 const AbstractType& declared_bound = AbstractType::Handle(bound()); |
12112 const String& type_param_name = String::Handle(UserVisibleName()); | 12116 const String& declared_bound_name = String::Handle( |
12113 const Class& cls = Class::Handle(parameterized_class()); | 12117 declared_bound.UserVisibleName()); |
12114 const String& class_name = String::Handle(cls.Name()); | 12118 const String& type_param_name = String::Handle(UserVisibleName()); |
12115 const Script& script = Script::Handle(cls.script()); | 12119 const Class& cls = Class::Handle(parameterized_class()); |
12116 // Since the bound may have been canonicalized, its token index is | 12120 const String& class_name = String::Handle(cls.Name()); |
12117 // meaningless, therefore use the token index of this type parameter. | 12121 const Script& script = Script::Handle(cls.script()); |
12118 *bound_error = FormatError( | 12122 // Since the bound may have been canonicalized, its token index is |
12119 *bound_error, | 12123 // meaningless, therefore use the token index of this type parameter. |
12120 script, | 12124 *bound_error = FormatError( |
12121 token_pos(), | 12125 *bound_error, |
12122 "type parameter '%s' of class '%s' must extend bound '%s', " | 12126 script, |
12123 "but type argument '%s' is not a subtype of '%s'\n", | 12127 token_pos(), |
12124 type_param_name.ToCString(), | 12128 "type parameter '%s' of class '%s' must extend bound '%s', " |
12125 class_name.ToCString(), | 12129 "but type argument '%s' is not a subtype of '%s'\n", |
12126 declared_bound_name.ToCString(), | 12130 type_param_name.ToCString(), |
12127 bounded_type_name.ToCString(), | 12131 class_name.ToCString(), |
12128 upper_bound_name.ToCString()); | 12132 declared_bound_name.ToCString(), |
| 12133 bounded_type_name.ToCString(), |
| 12134 upper_bound_name.ToCString()); |
| 12135 } |
12129 } | 12136 } |
12130 return false; | 12137 return false; |
12131 } | 12138 } |
12132 | 12139 |
12133 | 12140 |
12134 RawAbstractType* TypeParameter::CloneUnfinalized() const { | 12141 RawAbstractType* TypeParameter::CloneUnfinalized() const { |
12135 if (IsFinalized()) { | 12142 if (IsFinalized()) { |
12136 return raw(); | 12143 return raw(); |
12137 } | 12144 } |
12138 // No need to clone bound, as it is not part of the finalization state. | 12145 // No need to clone bound, as it is not part of the finalization state. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12211 JSONObject jsobj(stream); | 12218 JSONObject jsobj(stream); |
12212 } | 12219 } |
12213 | 12220 |
12214 | 12221 |
12215 bool BoundedType::IsMalformed() const { | 12222 bool BoundedType::IsMalformed() const { |
12216 return AbstractType::Handle(type()).IsMalformed(); | 12223 return AbstractType::Handle(type()).IsMalformed(); |
12217 } | 12224 } |
12218 | 12225 |
12219 | 12226 |
12220 bool BoundedType::IsMalboundedWithError(Error* bound_error) const { | 12227 bool BoundedType::IsMalboundedWithError(Error* bound_error) const { |
12221 if (!FLAG_enable_type_checks && !FLAG_error_on_bad_type) { | 12228 if (FLAG_enable_type_checks || FLAG_error_on_bad_type) { |
12222 return false; | 12229 const AbstractType& upper_bound = AbstractType::Handle(bound()); |
| 12230 if (upper_bound.IsMalformed()) { |
| 12231 if (bound_error != NULL) { |
| 12232 *bound_error = upper_bound.malformed_error(); |
| 12233 ASSERT(!bound_error->IsNull()); |
| 12234 } |
| 12235 return true; |
| 12236 } |
12223 } | 12237 } |
12224 const AbstractType& upper_bound = AbstractType::Handle(bound()); | 12238 return AbstractType::Handle(type()).IsMalboundedWithError(bound_error); |
12225 if (upper_bound.IsMalformed()) { | |
12226 if (bound_error != NULL) { | |
12227 *bound_error = upper_bound.malformed_error(); | |
12228 ASSERT(!bound_error->IsNull()); | |
12229 } | |
12230 return true; | |
12231 } | |
12232 return false; | |
12233 } | 12239 } |
12234 | 12240 |
12235 | 12241 |
12236 RawError* BoundedType::malformed_error() const { | 12242 RawError* BoundedType::malformed_error() const { |
12237 return AbstractType::Handle(type()).malformed_error(); | 12243 return AbstractType::Handle(type()).malformed_error(); |
12238 } | 12244 } |
12239 | 12245 |
12240 | 12246 |
12241 bool BoundedType::Equals(const Instance& other) const { | 12247 bool BoundedType::Equals(const Instance& other) const { |
12242 // BoundedType are not canonicalized, because their bound may get finalized | 12248 // BoundedType are not canonicalized, because their bound may get finalized |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12308 // Avoid endless recursion while checking and instantiating bound. | 12314 // Avoid endless recursion while checking and instantiating bound. |
12309 set_is_being_checked(true); | 12315 set_is_being_checked(true); |
12310 AbstractType& upper_bound = AbstractType::Handle(bound()); | 12316 AbstractType& upper_bound = AbstractType::Handle(bound()); |
12311 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); | 12317 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); |
12312 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); | 12318 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); |
12313 if (!upper_bound.IsInstantiated()) { | 12319 if (!upper_bound.IsInstantiated()) { |
12314 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, | 12320 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, |
12315 bound_error); | 12321 bound_error); |
12316 } | 12322 } |
12317 if (bound_error->IsNull()) { | 12323 if (bound_error->IsNull()) { |
12318 type_param.CheckBound(bounded_type, upper_bound, bound_error); | 12324 if (!type_param.CheckBound(bounded_type, upper_bound, bound_error) && |
| 12325 bound_error->IsNull()) { |
| 12326 // We cannot determine yet whether the bounded_type is below the |
| 12327 // upper_bound, because one or both of them is still uninstantiated. |
| 12328 ASSERT(!bounded_type.IsInstantiated() || !upper_bound.IsInstantiated()); |
| 12329 // Postpone bound check by returning a new BoundedType with partially |
| 12330 // instantiated bounded_type and upper_bound, but keeping type_param. |
| 12331 bounded_type = BoundedType::New(bounded_type, upper_bound, type_param); |
| 12332 } |
12319 } | 12333 } |
12320 set_is_being_checked(false); | 12334 set_is_being_checked(false); |
12321 } | 12335 } |
12322 return bounded_type.raw(); | 12336 return bounded_type.raw(); |
12323 } | 12337 } |
12324 | 12338 |
12325 | 12339 |
12326 RawAbstractType* BoundedType::CloneUnfinalized() const { | 12340 RawAbstractType* BoundedType::CloneUnfinalized() const { |
12327 if (IsFinalized()) { | 12341 if (IsFinalized()) { |
12328 return raw(); | 12342 return raw(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12366 const BoundedType& result = BoundedType::Handle(BoundedType::New()); | 12380 const BoundedType& result = BoundedType::Handle(BoundedType::New()); |
12367 result.set_type(type); | 12381 result.set_type(type); |
12368 result.set_bound(bound); | 12382 result.set_bound(bound); |
12369 result.set_type_parameter(type_parameter); | 12383 result.set_type_parameter(type_parameter); |
12370 result.set_is_being_checked(false); | 12384 result.set_is_being_checked(false); |
12371 return result.raw(); | 12385 return result.raw(); |
12372 } | 12386 } |
12373 | 12387 |
12374 | 12388 |
12375 const char* BoundedType::ToCString() const { | 12389 const char* BoundedType::ToCString() const { |
12376 const char* format = "BoundedType: type %s; bound: %s; class: %s"; | 12390 const char* format = "BoundedType: type %s; bound: %s; type param: %s of %s"; |
12377 const char* type_cstr = String::Handle(AbstractType::Handle( | 12391 const char* type_cstr = String::Handle(AbstractType::Handle( |
12378 type()).Name()).ToCString(); | 12392 type()).Name()).ToCString(); |
12379 const char* bound_cstr = String::Handle(AbstractType::Handle( | 12393 const char* bound_cstr = String::Handle(AbstractType::Handle( |
12380 bound()).Name()).ToCString(); | 12394 bound()).Name()).ToCString(); |
| 12395 const char* type_param_cstr = String::Handle(TypeParameter::Handle( |
| 12396 type_parameter()).name()).ToCString(); |
12381 const Class& cls = Class::Handle(TypeParameter::Handle( | 12397 const Class& cls = Class::Handle(TypeParameter::Handle( |
12382 type_parameter()).parameterized_class()); | 12398 type_parameter()).parameterized_class()); |
12383 const char* cls_cstr = | 12399 const char* cls_cstr = |
12384 cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString(); | 12400 cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString(); |
12385 intptr_t len = OS::SNPrint( | 12401 intptr_t len = OS::SNPrint( |
12386 NULL, 0, format, type_cstr, bound_cstr, cls_cstr) + 1; | 12402 NULL, 0, format, type_cstr, bound_cstr, type_param_cstr, cls_cstr) + 1; |
12387 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 12403 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
12388 OS::SNPrint(chars, len, format, type_cstr, bound_cstr, cls_cstr); | 12404 OS::SNPrint( |
| 12405 chars, len, format, type_cstr, bound_cstr, type_param_cstr, cls_cstr); |
12389 return chars; | 12406 return chars; |
12390 } | 12407 } |
12391 | 12408 |
12392 | 12409 |
12393 void BoundedType::PrintToJSONStream(JSONStream* stream, bool ref) const { | 12410 void BoundedType::PrintToJSONStream(JSONStream* stream, bool ref) const { |
12394 JSONObject jsobj(stream); | 12411 JSONObject jsobj(stream); |
12395 } | 12412 } |
12396 | 12413 |
12397 | 12414 |
12398 intptr_t MixinAppType::token_pos() const { | 12415 intptr_t MixinAppType::token_pos() const { |
(...skipping 3348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15747 return "_MirrorReference"; | 15764 return "_MirrorReference"; |
15748 } | 15765 } |
15749 | 15766 |
15750 | 15767 |
15751 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 15768 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
15752 JSONObject jsobj(stream); | 15769 JSONObject jsobj(stream); |
15753 } | 15770 } |
15754 | 15771 |
15755 | 15772 |
15756 } // namespace dart | 15773 } // namespace dart |
OLD | NEW |