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

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

Issue 23983026: Fill in type arguments when creating an object from the mirrors or embedding API. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 3 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') | runtime/vm/object.h » ('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/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/exceptions.h" 9 #include "vm/exceptions.h"
10 #include "vm/object_store.h" 10 #include "vm/object_store.h"
(...skipping 11 matching lines...) Expand all
22 const Object& result = Object::Handle( 22 const Object& result = Object::Handle(
23 DartLibraryCalls::InstanceCreate(mirrors_lib, 23 DartLibraryCalls::InstanceCreate(mirrors_lib,
24 mirror_class_name, 24 mirror_class_name,
25 constructor_name, 25 constructor_name,
26 constructor_arguments)); 26 constructor_arguments));
27 ASSERT(!result.IsError()); 27 ASSERT(!result.IsError());
28 return Instance::Cast(result).raw(); 28 return Instance::Cast(result).raw();
29 } 29 }
30 30
31 31
32 // Note a "raw type" is not the same as a RawType.
33 static RawAbstractType* RawTypeOfClass(const Class& cls) {
rmacnak 2013/09/11 21:10:21 Moved to a method on Class because it is also need
34 Type& type = Type::Handle(Type::New(cls,
35 Object::null_abstract_type_arguments(),
36 Scanner::kDummyTokenIndex));
37 return ClassFinalizer::FinalizeType(cls, type, ClassFinalizer::kCanonicalize);
38 }
39
40
41 static void ThrowMirroredCompilationError(const String& message) { 32 static void ThrowMirroredCompilationError(const String& message) {
42 Array& args = Array::Handle(Array::New(1)); 33 Array& args = Array::Handle(Array::New(1));
43 args.SetAt(0, message); 34 args.SetAt(0, message);
44 35
45 Exceptions::ThrowByType(Exceptions::kMirroredCompilationError, args); 36 Exceptions::ThrowByType(Exceptions::kMirroredCompilationError, args);
46 UNREACHABLE(); 37 UNREACHABLE();
47 } 38 }
48 39
49 40
50 static void ThrowInvokeError(const Error& error) { 41 static void ThrowInvokeError(const Error& error) {
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 entry = entries.GetNext(); 647 entry = entries.GetNext();
657 if (entry.IsClass()) { 648 if (entry.IsClass()) {
658 const Class& klass = Class::Cast(entry); 649 const Class& klass = Class::Cast(entry);
659 // We filter out implementation classes like Smi, Mint, Bignum, 650 // We filter out implementation classes like Smi, Mint, Bignum,
660 // OneByteString; function signature classes; and dynamic. 651 // OneByteString; function signature classes; and dynamic.
661 if (!klass.IsCanonicalSignatureClass() && 652 if (!klass.IsCanonicalSignatureClass() &&
662 !klass.IsDynamicClass() && 653 !klass.IsDynamicClass() &&
663 !RawObject::IsImplementationClassId(klass.id())) { 654 !RawObject::IsImplementationClassId(klass.id())) {
664 if (klass.NumTypeParameters() == 0) { 655 if (klass.NumTypeParameters() == 0) {
665 // Include runtime type for non-generics only. 656 // Include runtime type for non-generics only.
666 type = RawTypeOfClass(klass); 657 type = klass.BasicType();
667 } else { 658 } else {
668 type = AbstractType::null(); 659 type = AbstractType::null();
669 } 660 }
670 member_mirror = CreateClassMirror(klass, type, owner_mirror); 661 member_mirror = CreateClassMirror(klass, type, owner_mirror);
671 member_mirrors.Add(member_mirror); 662 member_mirrors.Add(member_mirror);
672 } 663 }
673 } else if (entry.IsField()) { 664 } else if (entry.IsField()) {
674 const Field& field = Field::Cast(entry); 665 const Field& field = Field::Cast(entry);
675 member_mirror = CreateVariableMirror(field, owner_mirror); 666 member_mirror = CreateVariableMirror(field, owner_mirror);
676 member_mirrors.Add(member_mirror); 667 member_mirrors.Add(member_mirror);
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); 951 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names));
961 952
962 const Function& function = Function::Handle( 953 const Function& function = Function::Handle(
963 klass.LookupStaticFunctionAllowPrivate(function_name)); 954 klass.LookupStaticFunctionAllowPrivate(function_name));
964 955
965 956
966 ArgumentsDescriptor args_descriptor(args_descriptor_array); 957 ArgumentsDescriptor args_descriptor(args_descriptor_array);
967 if (function.IsNull() || 958 if (function.IsNull() ||
968 !function.AreValidArguments(args_descriptor, NULL) || 959 !function.AreValidArguments(args_descriptor, NULL) ||
969 !function.is_visible()) { 960 !function.is_visible()) {
970 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), 961 ThrowNoSuchMethod(AbstractType::Handle(klass.BasicType()),
971 function_name, 962 function_name,
972 function, 963 function,
973 InvocationMirror::kStatic, 964 InvocationMirror::kStatic,
974 InvocationMirror::kMethod); 965 InvocationMirror::kMethod);
975 UNREACHABLE(); 966 UNREACHABLE();
976 } 967 }
977 968
978 Object& result = Object::Handle( 969 Object& result = Object::Handle(
979 DartEntry::InvokeFunction(function, args, args_descriptor_array)); 970 DartEntry::InvokeFunction(function, args, args_descriptor_array));
980 if (result.IsError()) { 971 if (result.IsError()) {
(...skipping 14 matching lines...) Expand all
995 986
996 // Note static fields do not have implicit getters. 987 // Note static fields do not have implicit getters.
997 const Field& field = Field::Handle(klass.LookupStaticField(getter_name)); 988 const Field& field = Field::Handle(klass.LookupStaticField(getter_name));
998 if (field.IsNull() || FieldIsUninitialized(field)) { 989 if (field.IsNull() || FieldIsUninitialized(field)) {
999 const String& internal_getter_name = String::Handle( 990 const String& internal_getter_name = String::Handle(
1000 Field::GetterName(getter_name)); 991 Field::GetterName(getter_name));
1001 const Function& getter = Function::Handle( 992 const Function& getter = Function::Handle(
1002 klass.LookupStaticFunctionAllowPrivate(internal_getter_name)); 993 klass.LookupStaticFunctionAllowPrivate(internal_getter_name));
1003 994
1004 if (getter.IsNull() || !getter.is_visible()) { 995 if (getter.IsNull() || !getter.is_visible()) {
1005 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), 996 ThrowNoSuchMethod(AbstractType::Handle(klass.BasicType()),
1006 getter_name, 997 getter_name,
1007 getter, 998 getter,
1008 InvocationMirror::kStatic, 999 InvocationMirror::kStatic,
1009 InvocationMirror::kGetter); 1000 InvocationMirror::kGetter);
1010 UNREACHABLE(); 1001 UNREACHABLE();
1011 } 1002 }
1012 1003
1013 // Invoke the getter and return the result. 1004 // Invoke the getter and return the result.
1014 Object& result = Object::Handle( 1005 Object& result = Object::Handle(
1015 DartEntry::InvokeFunction(getter, Object::empty_array())); 1006 DartEntry::InvokeFunction(getter, Object::empty_array()));
(...skipping 18 matching lines...) Expand all
1034 1025
1035 // Check for real fields and user-defined setters. 1026 // Check for real fields and user-defined setters.
1036 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); 1027 const Field& field = Field::Handle(klass.LookupStaticField(setter_name));
1037 if (field.IsNull()) { 1028 if (field.IsNull()) {
1038 const String& internal_setter_name = String::Handle( 1029 const String& internal_setter_name = String::Handle(
1039 Field::SetterName(setter_name)); 1030 Field::SetterName(setter_name));
1040 const Function& setter = Function::Handle( 1031 const Function& setter = Function::Handle(
1041 klass.LookupStaticFunctionAllowPrivate(internal_setter_name)); 1032 klass.LookupStaticFunctionAllowPrivate(internal_setter_name));
1042 1033
1043 if (setter.IsNull() || !setter.is_visible()) { 1034 if (setter.IsNull() || !setter.is_visible()) {
1044 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), 1035 ThrowNoSuchMethod(AbstractType::Handle(klass.BasicType()),
1045 setter_name, 1036 setter_name,
1046 setter, 1037 setter,
1047 InvocationMirror::kStatic, 1038 InvocationMirror::kStatic,
1048 InvocationMirror::kSetter); 1039 InvocationMirror::kSetter);
1049 UNREACHABLE(); 1040 UNREACHABLE();
1050 } 1041 }
1051 1042
1052 // Invoke the setter and return the result. 1043 // Invoke the setter and return the result.
1053 const int kNumArgs = 1; 1044 const int kNumArgs = 1;
1054 const Array& args = Array::Handle(Array::New(kNumArgs)); 1045 const Array& args = Array::Handle(Array::New(kNumArgs));
(...skipping 15 matching lines...) Expand all
1070 setter_name.ToCString())); 1061 setter_name.ToCString()));
1071 ThrowMirroredCompilationError(message); 1062 ThrowMirroredCompilationError(message);
1072 UNREACHABLE(); 1063 UNREACHABLE();
1073 } 1064 }
1074 1065
1075 field.set_value(value); 1066 field.set_value(value);
1076 return value.raw(); 1067 return value.raw();
1077 } 1068 }
1078 1069
1079 1070
1080 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 4) { 1071 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 5) {
1081 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); 1072 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
1082 const Class& klass = Class::Handle(ref.GetClassReferent()); 1073 const Class& klass = Class::Handle(ref.GetClassReferent());
1074 GET_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(1));
1083 GET_NON_NULL_NATIVE_ARGUMENT( 1075 GET_NON_NULL_NATIVE_ARGUMENT(
1084 String, constructor_name, arguments->NativeArgAt(1)); 1076 String, constructor_name, arguments->NativeArgAt(2));
1085 GET_NON_NULL_NATIVE_ARGUMENT(Array, explicit_args, arguments->NativeArgAt(2)); 1077 GET_NON_NULL_NATIVE_ARGUMENT(Array, explicit_args, arguments->NativeArgAt(3));
1086 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(3)); 1078 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4));
1087 1079
1088 // By convention, the static function implementing a named constructor 'C' 1080 // By convention, the static function implementing a named constructor 'C'
1089 // for class 'A' is labeled 'A.C', and the static function implementing the 1081 // for class 'A' is labeled 'A.C', and the static function implementing the
1090 // unnamed constructor for class 'A' is labeled 'A.'. 1082 // unnamed constructor for class 'A' is labeled 'A.'.
1091 // This convention prevents users from explicitly calling constructors. 1083 // This convention prevents users from explicitly calling constructors.
1092 const String& klass_name = String::Handle(klass.Name()); 1084 const String& klass_name = String::Handle(klass.Name());
1093 String& internal_constructor_name = 1085 String& internal_constructor_name =
1094 String::Handle(String::Concat(klass_name, Symbols::Dot())); 1086 String::Handle(String::Concat(klass_name, Symbols::Dot()));
1095 if (!constructor_name.IsNull()) { 1087 if (!constructor_name.IsNull()) {
1096 internal_constructor_name = 1088 internal_constructor_name =
1097 String::Concat(internal_constructor_name, constructor_name); 1089 String::Concat(internal_constructor_name, constructor_name);
1098 } 1090 }
1099 1091
1100 Function& lookup_constructor = Function::Handle( 1092 Function& lookup_constructor = Function::Handle(
1101 klass.LookupFunctionAllowPrivate(internal_constructor_name)); 1093 klass.LookupFunctionAllowPrivate(internal_constructor_name));
1102 1094
1103 if (lookup_constructor.IsNull() || 1095 if (lookup_constructor.IsNull() ||
1104 !(lookup_constructor.IsConstructor() || lookup_constructor.IsFactory()) || 1096 !(lookup_constructor.IsConstructor() || lookup_constructor.IsFactory()) ||
1105 !lookup_constructor.is_visible()) { 1097 !lookup_constructor.is_visible()) {
1106 // Pretend we didn't find the constructor at all when the arity is wrong 1098 // Pretend we didn't find the constructor at all when the arity is wrong
1107 // so as to produce the same NoSuchMethodError as the non-reflective case. 1099 // so as to produce the same NoSuchMethodError as the non-reflective case.
1108 lookup_constructor = Function::null(); 1100 lookup_constructor = Function::null();
1109 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), 1101 ThrowNoSuchMethod(AbstractType::Handle(klass.BasicType()),
1110 internal_constructor_name, 1102 internal_constructor_name,
1111 lookup_constructor, 1103 lookup_constructor,
1112 InvocationMirror::kConstructor, 1104 InvocationMirror::kConstructor,
1113 InvocationMirror::kMethod); 1105 InvocationMirror::kMethod);
1114 UNREACHABLE(); 1106 UNREACHABLE();
1115 } 1107 }
1116 1108
1117 Class& redirected_klass = Class::Handle(klass.raw()); 1109 Class& redirected_klass = Class::Handle(klass.raw());
1118 Function& redirected_constructor = Function::Handle(lookup_constructor.raw()); 1110 Function& redirected_constructor = Function::Handle(lookup_constructor.raw());
1119 if (lookup_constructor.IsRedirectingFactory()) { 1111 if (lookup_constructor.IsRedirectingFactory()) {
(...skipping 20 matching lines...) Expand all
1140 const Array& args_descriptor_array = 1132 const Array& args_descriptor_array =
1141 Array::Handle(ArgumentsDescriptor::New(args.Length(), 1133 Array::Handle(ArgumentsDescriptor::New(args.Length(),
1142 arg_names)); 1134 arg_names));
1143 1135
1144 ArgumentsDescriptor args_descriptor(args_descriptor_array); 1136 ArgumentsDescriptor args_descriptor(args_descriptor_array);
1145 if (!redirected_constructor.AreValidArguments(args_descriptor, NULL) || 1137 if (!redirected_constructor.AreValidArguments(args_descriptor, NULL) ||
1146 !redirected_constructor.is_visible()) { 1138 !redirected_constructor.is_visible()) {
1147 // Pretend we didn't find the constructor at all when the arity is wrong 1139 // Pretend we didn't find the constructor at all when the arity is wrong
1148 // so as to produce the same NoSuchMethodError as the non-reflective case. 1140 // so as to produce the same NoSuchMethodError as the non-reflective case.
1149 redirected_constructor = Function::null(); 1141 redirected_constructor = Function::null();
1150 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), 1142 ThrowNoSuchMethod(AbstractType::Handle(klass.BasicType()),
1151 internal_constructor_name, 1143 internal_constructor_name,
1152 redirected_constructor, 1144 redirected_constructor,
1153 InvocationMirror::kConstructor, 1145 InvocationMirror::kConstructor,
1154 InvocationMirror::kMethod); 1146 InvocationMirror::kMethod);
1155 UNREACHABLE(); 1147 UNREACHABLE();
1156 } 1148 }
1157 1149
1150 if (type.IsNull()) {
1151 // If the ClassMirror is on the declaration of a generic class.
1152 type ^= klass.BasicType();
1153 }
1154 const AbstractTypeArguments& type_arguments =
1155 AbstractTypeArguments::Handle(type.arguments());
1156
1158 Instance& new_object = Instance::Handle(); 1157 Instance& new_object = Instance::Handle();
1159 if (redirected_constructor.IsConstructor()) { 1158 if (redirected_constructor.IsConstructor()) {
1160 // Constructors get the uninitialized object and a constructor phase. Note 1159 // Constructors get the uninitialized object and a constructor phase. Note
1161 // we have delayed allocation until after the function type and argument 1160 // we have delayed allocation until after the function type and argument
1162 // matching checks. 1161 // matching checks.
1163 new_object = Instance::New(redirected_klass); 1162 new_object = Instance::New(redirected_klass);
1163 if (!type_arguments.IsNull()) {
1164 // The type arguments will be null if the class has no type parameters, in
1165 // which case the following call would fail because there is no slot
1166 // reserved in the object for the type vector.
1167 new_object.SetTypeArguments(type_arguments);
regis 2013/09/11 21:37:40 Who is checking that this type_argument vector has
1168 }
1164 args.SetAt(0, new_object); 1169 args.SetAt(0, new_object);
1165 args.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); 1170 args.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
1166 } else { 1171 } else {
1167 // Factories get type arguments. 1172 // Factories get type arguments.
1168 // TODO(12921): Should we allow the user to specify type arguments? Use type 1173 args.SetAt(0, type_arguments);
1169 // arguments from the mirror?
1170 args.SetAt(0, Object::null_abstract_type_arguments());
1171 } 1174 }
1172 1175
1173 // Invoke the constructor and return the new object. 1176 // Invoke the constructor and return the new object.
1174 const Object& result = 1177 const Object& result =
1175 Object::Handle(DartEntry::InvokeFunction(redirected_constructor, 1178 Object::Handle(DartEntry::InvokeFunction(redirected_constructor,
1176 args, 1179 args,
1177 args_descriptor_array)); 1180 args_descriptor_array));
1178 if (result.IsError()) { 1181 if (result.IsError()) {
1179 return result.raw(); 1182 return result.raw();
1180 } 1183 }
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1343 func.parent_function()), Object::null_instance()); 1346 func.parent_function()), Object::null_instance());
1344 } 1347 }
1345 const Class& owner = Class::Handle(func.Owner()); 1348 const Class& owner = Class::Handle(func.Owner());
1346 if (owner.IsTopLevel()) { 1349 if (owner.IsTopLevel()) {
1347 return CreateLibraryMirror(Library::Handle(owner.library())); 1350 return CreateLibraryMirror(Library::Handle(owner.library()));
1348 } 1351 }
1349 1352
1350 AbstractType& type = AbstractType::Handle(); 1353 AbstractType& type = AbstractType::Handle();
1351 if (owner.NumTypeParameters() == 0) { 1354 if (owner.NumTypeParameters() == 0) {
1352 // Include runtime type for non-generics only. 1355 // Include runtime type for non-generics only.
1353 type = RawTypeOfClass(owner); 1356 type = owner.BasicType();
1354 } 1357 }
1355 return CreateClassMirror(owner, type, Object::null_instance()); 1358 return CreateClassMirror(owner, type, Object::null_instance());
1356 } 1359 }
1357 1360
1358 1361
1359 DEFINE_NATIVE_ENTRY(MethodMirror_parameters, 2) { 1362 DEFINE_NATIVE_ENTRY(MethodMirror_parameters, 2) {
1360 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0)); 1363 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0));
1361 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); 1364 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
1362 const Function& func = Function::Handle(ref.GetFunctionReferent()); 1365 const Function& func = Function::Handle(ref.GetFunctionReferent());
1363 return CreateParameterMirrorList(func, owner); 1366 return CreateParameterMirrorList(func, owner);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 } 1422 }
1420 1423
1421 1424
1422 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { 1425 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) {
1423 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); 1426 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
1424 const Field& field = Field::Handle(ref.GetFieldReferent()); 1427 const Field& field = Field::Handle(ref.GetFieldReferent());
1425 return field.type(); 1428 return field.type();
1426 } 1429 }
1427 1430
1428 } // namespace dart 1431 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('j') | runtime/vm/object.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698