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

Side by Side Diff: runtime/lib/mirrors.cc

Issue 26344006: Substitution for type variables in mirrors on instantiated generics. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('j') | tests/lib/lib.status » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "lib/invocation_mirror.h" 5 #include "lib/invocation_mirror.h"
6 #include "vm/bootstrap_natives.h" 6 #include "vm/bootstrap_natives.h"
7 #include "vm/class_finalizer.h" 7 #include "vm/class_finalizer.h"
8 #include "vm/compiler.h" 8 #include "vm/compiler.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/exceptions.h" 10 #include "vm/exceptions.h"
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 const TypeArguments& args = TypeArguments::Handle(cls.type_parameters()); 217 const TypeArguments& args = TypeArguments::Handle(cls.type_parameters());
218 if (args.IsNull()) { 218 if (args.IsNull()) {
219 return Object::empty_array().raw(); 219 return Object::empty_array().raw();
220 } 220 }
221 const Array& result = Array::Handle(Array::New(args.Length() * 2)); 221 const Array& result = Array::Handle(Array::New(args.Length() * 2));
222 TypeParameter& type = TypeParameter::Handle(); 222 TypeParameter& type = TypeParameter::Handle();
223 String& name = String::Handle(); 223 String& name = String::Handle();
224 for (intptr_t i = 0; i < args.Length(); i++) { 224 for (intptr_t i = 0; i < args.Length(); i++) {
225 type ^= args.TypeAt(i); 225 type ^= args.TypeAt(i);
226 ASSERT(type.IsTypeParameter()); 226 ASSERT(type.IsTypeParameter());
227 ASSERT(!type.IsMalformed());
228 ASSERT(type.IsFinalized());
227 name ^= type.name(); 229 name ^= type.name();
228 result.SetAt(2 * i, name); 230 result.SetAt(2 * i, name);
229 result.SetAt(2 * i + 1, type); 231 result.SetAt(2 * i + 1, type);
230 } 232 }
231 return result.raw(); 233 return result.raw();
232 } 234 }
233 235
234 236
235 static RawInstance* CreateTypedefMirror(const Class& cls, 237 static RawInstance* CreateTypedefMirror(const Class& cls,
236 const Instance& owner_mirror) { 238 const Instance& owner_mirror) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 lookup_cls = lookup_cls.SuperClass(); 308 lookup_cls = lookup_cls.SuperClass();
307 } while (!lookup_cls.IsNull()); 309 } while (!lookup_cls.IsNull());
308 return Function::null(); 310 return Function::null();
309 } 311 }
310 312
311 static RawInstance* CreateClassMirror(const Class& cls, 313 static RawInstance* CreateClassMirror(const Class& cls,
312 const AbstractType& type, 314 const AbstractType& type,
313 const Bool& is_declaration, 315 const Bool& is_declaration,
314 const Instance& owner_mirror) { 316 const Instance& owner_mirror) {
315 ASSERT(!cls.IsDynamicClass() && !cls.IsVoidClass()); 317 ASSERT(!cls.IsDynamicClass() && !cls.IsVoidClass());
318 ASSERT(!type.IsNull());
319 ASSERT(type.IsFinalized());
316 320
317 if (cls.IsSignatureClass()) { 321 if (cls.IsSignatureClass()) {
318 if (cls.IsCanonicalSignatureClass()) { 322 if (cls.IsCanonicalSignatureClass()) {
319 // We represent function types as canonical signature classes. 323 // We represent function types as canonical signature classes.
320 return CreateFunctionTypeMirror(cls, type); 324 return CreateFunctionTypeMirror(cls, type);
321 } else { 325 } else {
322 // We represent typedefs as non-canonical signature classes. 326 // We represent typedefs as non-canonical signature classes.
323 return CreateTypedefMirror(cls, owner_mirror); 327 return CreateTypedefMirror(cls, owner_mirror);
324 } 328 }
325 } 329 }
326 330
327 ASSERT(!type.IsNull());
328
329 const Bool& is_generic = Bool::Get(cls.NumTypeParameters() != 0); 331 const Bool& is_generic = Bool::Get(cls.NumTypeParameters() != 0);
330 const Bool& is_mixin_typedef = Bool::Get(cls.is_mixin_typedef()); 332 const Bool& is_mixin_typedef = Bool::Get(cls.is_mixin_typedef());
331 333
332 const Array& args = Array::Handle(Array::New(6)); 334 const Array& args = Array::Handle(Array::New(6));
333 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls))); 335 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
334 args.SetAt(1, type); 336 args.SetAt(1, type);
335 // We do not set the names of anonymous mixin applications because the mirrors 337 // We do not set the names of anonymous mixin applications because the mirrors
336 // use a different naming convention than the VM (lib.S with lib.M and S&M 338 // use a different naming convention than the VM (lib.S with lib.M and S&M
337 // respectively). 339 // respectively).
338 if (!cls.IsMixinApplication() || cls.is_mixin_typedef()) { 340 if (!cls.IsMixinApplication() || cls.is_mixin_typedef()) {
(...skipping 12 matching lines...) Expand all
351 String& str = String::Handle(); 353 String& str = String::Handle();
352 str = lib.name(); 354 str = lib.name();
353 args.SetAt(1, str); 355 args.SetAt(1, str);
354 str = lib.url(); 356 str = lib.url();
355 args.SetAt(2, str); 357 args.SetAt(2, str);
356 return CreateMirror(Symbols::_LocalLibraryMirrorImpl(), args); 358 return CreateMirror(Symbols::_LocalLibraryMirrorImpl(), args);
357 } 359 }
358 360
359 361
360 static RawInstance* CreateTypeMirror(const AbstractType& type) { 362 static RawInstance* CreateTypeMirror(const AbstractType& type) {
363 ASSERT(type.IsFinalized());
361 ASSERT(!type.IsMalformed()); 364 ASSERT(!type.IsMalformed());
362 if (type.HasResolvedTypeClass()) { 365 if (type.HasResolvedTypeClass()) {
363 const Class& cls = Class::Handle(type.type_class()); 366 const Class& cls = Class::Handle(type.type_class());
364 // Handle void and dynamic types. 367 // Handle void and dynamic types.
365 if (cls.IsVoidClass()) { 368 if (cls.IsVoidClass()) {
366 Array& args = Array::Handle(Array::New(1)); 369 Array& args = Array::Handle(Array::New(1));
367 args.SetAt(0, Symbols::Void()); 370 args.SetAt(0, Symbols::Void());
368 // TODO(mlippautz): Create once in the VM isolate and retrieve from there. 371 // TODO(mlippautz): Create once in the VM isolate and retrieve from there.
369 return CreateMirror(Symbols::_SpecialTypeMirrorImpl(), args); 372 return CreateMirror(Symbols::_SpecialTypeMirrorImpl(), args);
370 } else if (cls.IsDynamicClass()) { 373 } else if (cls.IsDynamicClass()) {
371 Array& args = Array::Handle(Array::New(1)); 374 Array& args = Array::Handle(Array::New(1));
372 args.SetAt(0, Symbols::Dynamic()); 375 args.SetAt(0, Symbols::Dynamic());
373 // TODO(mlippautz): Create once in the VM isolate and retrieve from there. 376 // TODO(mlippautz): Create once in the VM isolate and retrieve from there.
374 return CreateMirror(Symbols::_SpecialTypeMirrorImpl(), args); 377 return CreateMirror(Symbols::_SpecialTypeMirrorImpl(), args);
375 } 378 }
376 return CreateClassMirror(cls, type, Bool::False(), Object::null_instance()); 379 return CreateClassMirror(cls, type, Bool::False(), Object::null_instance());
377 } else if (type.IsTypeParameter()) { 380 } else if (type.IsTypeParameter()) {
378 return CreateTypeVariableMirror(TypeParameter::Cast(type), 381 return CreateTypeVariableMirror(TypeParameter::Cast(type),
379 Object::null_instance()); 382 Object::null_instance());
383 } else if (type.IsBoundedType()) {
384 AbstractType& actual_type =
385 AbstractType::Handle(BoundedType::Cast(type).type());
386 return CreateTypeMirror(actual_type);
380 } 387 }
381 UNREACHABLE(); 388 UNREACHABLE();
382 return Instance::null(); 389 return Instance::null();
383 } 390 }
384 391
385 392
386 static RawInstance* CreateIsolateMirror() { 393 static RawInstance* CreateIsolateMirror() {
387 Isolate* isolate = Isolate::Current(); 394 Isolate* isolate = Isolate::Current();
388 const String& debug_name = String::Handle(String::New(isolate->name())); 395 const String& debug_name = String::Handle(String::New(isolate->name()));
389 const Library& root_library = 396 const Library& root_library =
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 return Object::sentinel().raw(); 762 return Object::sentinel().raw();
756 } 763 }
757 764
758 765
759 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalMirrorSystem, 0) { 766 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalMirrorSystem, 0) {
760 return CreateMirrorSystem(); 767 return CreateMirrorSystem();
761 } 768 }
762 769
763 770
764 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) { 771 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) {
765 GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0)); 772 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
773 ASSERT(!type.IsMalformed());
774 ASSERT(type.IsFinalized());
775 ASSERT(type.HasResolvedTypeClass());
766 const Class& cls = Class::Handle(type.type_class()); 776 const Class& cls = Class::Handle(type.type_class());
767 ASSERT(!cls.IsNull());
768 if (cls.IsDynamicClass() || cls.IsVoidClass()) { 777 if (cls.IsDynamicClass() || cls.IsVoidClass()) {
769 Exceptions::ThrowArgumentError(type); 778 Exceptions::ThrowArgumentError(type);
770 UNREACHABLE(); 779 UNREACHABLE();
771 } 780 }
772 const Type& stripped_type = Type::Handle(cls.RareType()); 781 const AbstractType& stripped_type = AbstractType::Handle(cls.RareType());
773 return CreateClassMirror(cls, 782 return CreateClassMirror(cls,
774 stripped_type, 783 stripped_type,
775 Bool::True(), // is_declaration 784 Bool::True(), // is_declaration
776 Object::null_instance()); 785 Object::null_instance());
777 } 786 }
778 787
779 788
780 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalTypeMirror, 1) { 789 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalTypeMirror, 1) {
781 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); 790 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
782 return CreateTypeMirror(type); 791 return CreateTypeMirror(type);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 DEFINE_NATIVE_ENTRY(ClassMirror_library, 1) { 873 DEFINE_NATIVE_ENTRY(ClassMirror_library, 1) {
865 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); 874 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
866 const Class& klass = Class::Handle(ref.GetClassReferent()); 875 const Class& klass = Class::Handle(ref.GetClassReferent());
867 const Library& library = Library::Handle(klass.library()); 876 const Library& library = Library::Handle(klass.library());
868 ASSERT(!library.IsNull()); 877 ASSERT(!library.IsNull());
869 return CreateLibraryMirror(library); 878 return CreateLibraryMirror(library);
870 } 879 }
871 880
872 881
873 DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 1) { 882 DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 1) {
874 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); 883 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
875 const Class& klass = Class::Handle(ref.GetClassReferent()); 884 ASSERT(!type.IsMalformed());
876 return klass.super_type(); 885 ASSERT(type.IsFinalized());
886 const Class& cls = Class::Handle(type.type_class());
887 const AbstractType& super_type = AbstractType::Handle(cls.super_type());
888 if (super_type.IsType()) {
889 ASSERT(super_type.IsFinalized());
regis 2013/10/11 01:28:59 You could write ASSERT(!super_type.IsType() || sup
rmacnak 2013/10/11 01:48:02 Yep, that holds. Also explains why I had trouble p
890 }
891 return super_type.raw();
892 }
893
894 DEFINE_NATIVE_ENTRY(ClassMirror_supertype_instantiated, 1) {
895 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
896 ASSERT(!type.IsMalformed());
897 ASSERT(type.IsFinalized());
898 const Class& cls = Class::Handle(type.type_class());
899 AbstractType& super_type = AbstractType::Handle(cls.super_type());
900 AbstractType& result = AbstractType::Handle(super_type.raw());
901
902 ASSERT(super_type.IsType());
903 if (!super_type.IsInstantiated()) {
904 AbstractTypeArguments& type_args =
905 AbstractTypeArguments::Handle(type.arguments());
906 Error& bound_error = Error::Handle();
907 result ^= super_type.InstantiateFrom(type_args, &bound_error);
908 result ^= result.Canonicalize();
regis 2013/10/11 01:28:59 I would canonicalize after checking for a bound er
rmacnak 2013/10/11 01:48:02 Done.
909 if (!bound_error.IsNull()) {
910 ThrowInvokeError(bound_error);
911 UNREACHABLE();
912 }
913 ASSERT(result.IsType());
914 }
915
916 ASSERT(result.IsFinalized());
917 return result.raw();
877 } 918 }
878 919
879 920
880 DEFINE_NATIVE_ENTRY(ClassMirror_interfaces, 1) { 921 DEFINE_NATIVE_ENTRY(ClassMirror_interfaces, 1) {
881 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); 922 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
882 const Class& klass = Class::Handle(ref.GetClassReferent()); 923 const Class& klass = Class::Handle(ref.GetClassReferent());
883 924
884 const Error& error = Error::Handle(klass.EnsureIsFinalized(isolate)); 925 const Error& error = Error::Handle(klass.EnsureIsFinalized(isolate));
885 if (!error.IsNull()) { 926 if (!error.IsNull()) {
886 ThrowInvokeError(error); 927 ThrowInvokeError(error);
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 type_mirror = CreateTypeMirror(arg_type); 1108 type_mirror = CreateTypeMirror(arg_type);
1068 result.SetAt(i, type_mirror); 1109 result.SetAt(i, type_mirror);
1069 } 1110 }
1070 return result.raw(); 1111 return result.raw();
1071 } 1112 }
1072 1113
1073 1114
1074 DEFINE_NATIVE_ENTRY(TypeVariableMirror_owner, 1) { 1115 DEFINE_NATIVE_ENTRY(TypeVariableMirror_owner, 1) {
1075 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0)); 1116 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0));
1076 const Class& owner = Class::Handle(param.parameterized_class()); 1117 const Class& owner = Class::Handle(param.parameterized_class());
1077 const Type& type = Type::Handle(owner.RareType()); 1118 const AbstractType& type = AbstractType::Handle(owner.RareType());
1078 return CreateClassMirror(owner, 1119 return CreateClassMirror(owner,
1079 type, 1120 type,
1080 Bool::True(), // is_declaration 1121 Bool::True(), // is_declaration
1081 Instance::null_instance()); 1122 Instance::null_instance());
1082 } 1123 }
1083 1124
1084 1125
1085 DEFINE_NATIVE_ENTRY(TypeVariableMirror_upper_bound, 1) { 1126 DEFINE_NATIVE_ENTRY(TypeVariableMirror_upper_bound, 1) {
1086 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0)); 1127 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0));
1087 return param.bound(); 1128 return param.bound();
1088 } 1129 }
1089 1130
1090 1131
1132 DEFINE_NATIVE_ENTRY(TypeVariableMirror_instantiate_from, 2) {
1133 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0));
1134 GET_NON_NULL_NATIVE_ARGUMENT(Type, instantiator, arguments->NativeArgAt(1));
1135
1136 ASSERT(param.parameterized_class() == instantiator.type_class());
1137
1138 AbstractTypeArguments& type_args =
1139 AbstractTypeArguments::Handle(instantiator.arguments());
1140 Error& bound_error = Error::Handle();
1141 AbstractType& result =
1142 AbstractType::Handle(param.InstantiateFrom(type_args, &bound_error));
1143 ASSERT(bound_error.IsNull());
1144 ASSERT(result.IsFinalized());
1145 return result.raw();
1146 }
1147
1148
1091 DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 5) { 1149 DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 5) {
1092 // Argument 0 is the mirror, which is unused by the native. It exists 1150 // Argument 0 is the mirror, which is unused by the native. It exists
1093 // because this native is an instance method in order to be polymorphic 1151 // because this native is an instance method in order to be polymorphic
1094 // with its cousins. 1152 // with its cousins.
1095 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); 1153 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1));
1096 GET_NON_NULL_NATIVE_ARGUMENT( 1154 GET_NON_NULL_NATIVE_ARGUMENT(
1097 String, function_name, arguments->NativeArgAt(2)); 1155 String, function_name, arguments->NativeArgAt(2));
1098 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3)); 1156 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3));
1099 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4)); 1157 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4));
1100 1158
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
1641 const Function& func = Function::Handle(ref.GetFunctionReferent()); 1699 const Function& func = Function::Handle(ref.GetFunctionReferent());
1642 if (func.IsNonImplicitClosureFunction()) { 1700 if (func.IsNonImplicitClosureFunction()) {
1643 return CreateMethodMirror(Function::Handle( 1701 return CreateMethodMirror(Function::Handle(
1644 func.parent_function()), Object::null_instance()); 1702 func.parent_function()), Object::null_instance());
1645 } 1703 }
1646 const Class& owner = Class::Handle(func.Owner()); 1704 const Class& owner = Class::Handle(func.Owner());
1647 if (owner.IsTopLevel()) { 1705 if (owner.IsTopLevel()) {
1648 return CreateLibraryMirror(Library::Handle(owner.library())); 1706 return CreateLibraryMirror(Library::Handle(owner.library()));
1649 } 1707 }
1650 1708
1651 Type& type = Type::Handle(owner.RareType()); 1709 AbstractType& type = AbstractType::Handle(owner.RareType());
1652 return CreateClassMirror(owner, type, Bool::True(), Object::null_instance()); 1710 return CreateClassMirror(owner, type, Bool::True(), Object::null_instance());
1653 } 1711 }
1654 1712
1655 1713
1656 DEFINE_NATIVE_ENTRY(MethodMirror_parameters, 2) { 1714 DEFINE_NATIVE_ENTRY(MethodMirror_parameters, 2) {
1657 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0)); 1715 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0));
1658 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); 1716 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
1659 const Function& func = Function::Handle(ref.GetFunctionReferent()); 1717 const Function& func = Function::Handle(ref.GetFunctionReferent());
1660 return CreateParameterMirrorList(func, owner); 1718 return CreateParameterMirrorList(func, owner);
1661 } 1719 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1716 } 1774 }
1717 1775
1718 1776
1719 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { 1777 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) {
1720 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); 1778 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
1721 const Field& field = Field::Handle(ref.GetFieldReferent()); 1779 const Field& field = Field::Handle(ref.GetFieldReferent());
1722 return field.type(); 1780 return field.type();
1723 } 1781 }
1724 1782
1725 } // namespace dart 1783 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('j') | tests/lib/lib.status » ('J')

Powered by Google App Engine
This is Rietveld 408576698