| 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 |