5 // Marek Safar <marek.safar@gmail.com>
7 // Copyright (C) 2015 Xamarin Inc (http://www.xamarin.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.Reflection;
30 using System.Runtime.CompilerServices;
31 using System.Threading;
32 using System.Collections.Generic;
33 using System.Runtime.InteropServices;
34 using System.Globalization;
36 using System.Reflection.Emit;
38 using System.Diagnostics.Contracts;
39 using System.Security;
40 using System.Runtime.Serialization;
44 partial class RuntimeType
46 internal virtual MonoCMethod GetDefaultConstructor ()
48 // TODO: Requires MonoType
49 throw new NotSupportedException ();
52 string GetDefaultMemberName ()
54 object [] att = GetCustomAttributes (typeof (DefaultMemberAttribute), true);
55 return att.Length != 0 ? ((DefaultMemberAttribute) att [0]).MemberName : null;
58 RuntimeConstructorInfo m_serializationCtor;
59 internal RuntimeConstructorInfo GetSerializationCtor()
61 if (m_serializationCtor == null) {
62 var s_SICtorParamTypes = new Type[] { typeof(SerializationInfo), typeof(StreamingContext) };
64 m_serializationCtor = GetConstructor(
65 BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
67 CallingConventions.Any,
69 null) as RuntimeConstructorInfo;
72 return m_serializationCtor;
75 internal Object CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fillCache, ref StackCrawlMark stackMark)
77 bool bNeedSecurityCheck = true;
78 bool bCanBeCached = false;
79 bool bSecurityCheckOff = false;
82 CreateInstanceCheckThis();
85 bSecurityCheckOff = true;
87 return CreateInstanceMono (!publicOnly);
90 object CreateInstanceMono (bool nonPublic)
92 var ctor = GetDefaultConstructor ();
93 if (!nonPublic && ctor != null && !ctor.IsPublic) {
98 Type elementType = this.GetRootElementType();
99 if (ReferenceEquals (elementType, typeof (TypedReference)) || ReferenceEquals (elementType, typeof (RuntimeArgumentHandle)))
100 throw new NotSupportedException (Environment.GetResourceString ("NotSupported_ContainsStackPtr"));
103 return CreateInstanceInternal (this);
105 throw new MissingMethodException (Locale.GetText ("Default constructor not found for type " + FullName));
108 // TODO: .net does more checks in unmanaged land in RuntimeTypeHandle::CreateInstance
110 throw new MissingMethodException (Locale.GetText ("Cannot create an abstract class '{0}'.", FullName));
113 return ctor.InternalInvoke (null, null);
116 internal Object CheckValue (Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
119 var res = TryConvertToType (value, ref failed);
123 if ((invokeAttr & BindingFlags.ExactBinding) == BindingFlags.ExactBinding)
124 throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
126 if (binder != null && binder != Type.DefaultBinder)
127 return binder.ChangeType (value, this, culture);
129 throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
132 object TryConvertToType (object value, ref bool failed)
134 if (IsInstanceOfType (value)) {
139 var elementType = GetElementType ();
140 if (value == null || elementType.IsInstanceOfType (value)) {
149 var type = Enum.GetUnderlyingType (this);
150 if (type == value.GetType ())
152 var res = IsConvertibleToPrimitiveType (value, this);
155 } else if (IsPrimitive) {
156 var res = IsConvertibleToPrimitiveType (value, this);
159 } else if (IsPointer) {
160 var vtype = value.GetType ();
161 if (vtype == typeof (IntPtr) || vtype == typeof (UIntPtr))
169 // Binder uses some incompatible conversion rules. For example
170 // int value cannot be used with decimal parameter but in other
171 // ways it's more flexible than normal convertor, for example
172 // long value can be used with int based enum
173 static object IsConvertibleToPrimitiveType (object value, Type targetType)
175 var type = value.GetType ();
177 type = Enum.GetUnderlyingType (type);
178 if (type == targetType)
182 var from = Type.GetTypeCode (type);
183 var to = Type.GetTypeCode (targetType);
189 return (Char) (Byte) value;
190 case TypeCode.UInt16:
197 return (Int16) (Byte) value;
199 return (Int16) (SByte) value;
202 case TypeCode.UInt16:
205 return (UInt16) (Byte) value;
213 return (Int32) (Byte) value;
215 return (Int32) (SByte) value;
217 return (Int32) (Char) value;
219 return (Int32) (Int16) value;
220 case TypeCode.UInt16:
221 return (Int32) (UInt16) value;
224 case TypeCode.UInt32:
227 return (UInt32) (Byte) value;
229 return (UInt32) (Char) value;
230 case TypeCode.UInt16:
231 return (UInt32) (UInt16) value;
237 return (Int64) (Byte) value;
239 return (Int64) (SByte) value;
241 return (Int64) (Int16) value;
243 return (Int64) (Char) value;
244 case TypeCode.UInt16:
245 return (Int64) (UInt16) value;
247 return (Int64) (Int32) value;
248 case TypeCode.UInt32:
249 return (Int64) (UInt32) value;
252 case TypeCode.UInt64:
255 return (UInt64) (Byte) value;
257 return (UInt64) (Char) value;
258 case TypeCode.UInt16:
259 return (UInt64) (UInt16) value;
260 case TypeCode.UInt32:
261 return (UInt64) (UInt32) value;
264 case TypeCode.Single:
267 return (Single) (Byte) value;
269 return (Single) (SByte) value;
271 return (Single) (Int16) value;
273 return (Single) (Char) value;
274 case TypeCode.UInt16:
275 return (Single) (UInt16) value;
277 return (Single) (Int32) value;
278 case TypeCode.UInt32:
279 return (Single) (UInt32) value;
281 return (Single) (Int64) value;
282 case TypeCode.UInt64:
283 return (Single) (UInt64) value;
286 case TypeCode.Double:
289 return (Double) (Byte) value;
291 return (Double) (SByte) value;
293 return (Double) (Char) value;
295 return (Double) (Int16) value;
296 case TypeCode.UInt16:
297 return (Double) (UInt16) value;
299 return (Double) (Int32) value;
300 case TypeCode.UInt32:
301 return (Double) (UInt32) value;
303 return (Double) (Int64) value;
304 case TypeCode.UInt64:
305 return (Double) (UInt64) value;
306 case TypeCode.Single:
307 return (Double) (Single) value;
312 // Everything else is rejected
316 string GetCachedName (TypeNameKind kind)
319 case TypeNameKind.SerializationName:
322 throw new NotImplementedException ();
326 [MethodImplAttribute(MethodImplOptions.InternalCall)]
327 extern Type make_array_type (int rank);
329 public override Type MakeArrayType ()
331 return make_array_type (0);
334 public override Type MakeArrayType (int rank)
336 if (rank < 1 || rank > 255)
337 throw new IndexOutOfRangeException ();
338 return make_array_type (rank);
341 [MethodImplAttribute(MethodImplOptions.InternalCall)]
342 extern Type make_byref_type ();
344 public override Type MakeByRefType ()
347 throw new TypeLoadException ("Can not call MakeByRefType on a ByRef type");
348 return make_byref_type ();
351 [MethodImplAttribute(MethodImplOptions.InternalCall)]
352 static extern Type MakePointerType (Type type);
354 public override Type MakePointerType ()
356 return MakePointerType (this);
359 public override StructLayoutAttribute StructLayoutAttribute {
361 return GetStructLayoutAttribute ();
365 public override bool ContainsGenericParameters {
367 if (IsGenericParameter)
371 foreach (Type arg in GetGenericArguments ())
372 if (arg.ContainsGenericParameters)
377 return GetElementType ().ContainsGenericParameters;
383 public override Type[] GetGenericParameterConstraints()
385 if (!IsGenericParameter)
386 throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
387 Contract.EndContractBlock();
389 Type[] constraints = GetGenericParameterConstraints_impl ();
391 if (constraints == null)
392 constraints = EmptyArray<Type>.Value;
397 public override Type MakeGenericType (params Type[] typeArguments)
400 throw new NotSupportedException ();
401 if (!IsGenericTypeDefinition)
402 throw new InvalidOperationException ("not a generic type definition");
403 if (typeArguments == null)
404 throw new ArgumentNullException ("typeArguments");
405 if (GetGenericArguments().Length != typeArguments.Length)
406 throw new ArgumentException (String.Format ("The type or method has {0} generic parameter(s) but {1} generic argument(s) where provided. A generic argument must be provided for each generic parameter.", GetGenericArguments ().Length, typeArguments.Length), "typeArguments");
408 bool hasUserType = false;
410 Type[] systemTypes = new Type[typeArguments.Length];
411 for (int i = 0; i < typeArguments.Length; ++i) {
412 Type t = typeArguments [i];
414 throw new ArgumentNullException ("typeArguments");
416 if (!(t is MonoType))
423 throw new NotSupportedException ("User types are not supported under full aot");
425 return new MonoGenericClass (this, typeArguments);
429 Type res = MakeGenericType (this, systemTypes);
431 throw new TypeLoadException ();
435 [MethodImplAttribute(MethodImplOptions.InternalCall)]
436 static extern Type MakeGenericType (Type gt, Type [] types);
438 [MethodImplAttribute(MethodImplOptions.InternalCall)]
439 internal extern RuntimeMethodInfo[] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type);
441 [MethodImplAttribute(MethodImplOptions.InternalCall)]
442 extern RuntimePropertyInfo[] GetPropertiesByName (string name, BindingFlags bindingAttr, bool icase, Type reflected_type);
444 [MethodImplAttribute(MethodImplOptions.InternalCall)]
445 extern RuntimeConstructorInfo[] GetConstructors_internal (BindingFlags bindingAttr, Type reflected_type);
447 public override InterfaceMapping GetInterfaceMap (Type ifaceType)
449 if (IsGenericParameter)
450 throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
452 if ((object)ifaceType == null)
453 throw new ArgumentNullException("ifaceType");
454 Contract.EndContractBlock();
456 RuntimeType ifaceRtType = ifaceType as RuntimeType;
458 if (ifaceRtType == null)
459 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "ifaceType");
461 InterfaceMapping res;
462 if (!ifaceType.IsInterface)
463 throw new ArgumentException (Locale.GetText ("Argument must be an interface."), "ifaceType");
465 throw new ArgumentException ("'this' type cannot be an interface itself");
466 res.TargetType = this;
467 res.InterfaceType = ifaceType;
468 GetInterfaceMapData (this, ifaceType, out res.TargetMethods, out res.InterfaceMethods);
469 if (res.TargetMethods == null)
470 throw new ArgumentException (Locale.GetText ("Interface not found"), "ifaceType");
475 [MethodImplAttribute(MethodImplOptions.InternalCall)]
476 static extern void GetInterfaceMapData (Type t, Type iface, out MethodInfo[] targets, out MethodInfo[] methods);
478 public override Guid GUID {
480 object[] att = GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), true);
483 return new Guid(((System.Runtime.InteropServices.GuidAttribute)att[0]).Value);
487 StructLayoutAttribute GetStructLayoutAttribute ()
491 if (IsLayoutSequential)
492 kind = LayoutKind.Sequential;
493 else if (IsExplicitLayout)
494 kind = LayoutKind.Explicit;
496 kind = LayoutKind.Auto;
498 StructLayoutAttribute attr = new StructLayoutAttribute (kind);
501 attr.CharSet = CharSet.Unicode;
502 else if (IsAnsiClass)
503 attr.CharSet = CharSet.Ansi;
505 attr.CharSet = CharSet.Auto;
507 if (kind != LayoutKind.Auto) {
509 GetPacking (out packing, out attr.Size);
510 // 0 means no data provided, we end up with default value
518 [MethodImplAttribute(MethodImplOptions.InternalCall)]
519 extern void GetPacking (out int packing, out int size);
522 private static Dictionary<Guid, Type> clsid_types;
523 private static AssemblyBuilder clsid_assemblybuilder;
526 internal static Type GetTypeFromCLSIDImpl(Guid clsid, String server, bool throwOnError)
531 if (clsid_types == null)
533 Dictionary<Guid, Type> new_clsid_types = new Dictionary<Guid, Type> ();
534 Interlocked.CompareExchange<Dictionary<Guid, Type>>(
535 ref clsid_types, new_clsid_types, null);
539 if (clsid_types.TryGetValue(clsid, out result))
542 if (clsid_assemblybuilder == null)
544 AssemblyName assemblyname = new AssemblyName ();
545 assemblyname.Name = "GetTypeFromCLSIDDummyAssembly";
546 clsid_assemblybuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (
547 assemblyname, AssemblyBuilderAccess.Run);
549 ModuleBuilder modulebuilder = clsid_assemblybuilder.DefineDynamicModule (
552 TypeBuilder typebuilder = modulebuilder.DefineType ("System.__ComObject",
553 TypeAttributes.Public | TypeAttributes.Class, typeof(System.__ComObject));
555 Type[] guidattrtypes = new Type[] { typeof(string) };
557 CustomAttributeBuilder customattr = new CustomAttributeBuilder (
558 typeof(GuidAttribute).GetConstructor (guidattrtypes),
559 new object[] { clsid.ToString () });
561 typebuilder.SetCustomAttribute (customattr);
563 customattr = new CustomAttributeBuilder (
564 typeof(ComImportAttribute).GetConstructor (EmptyTypes),
567 typebuilder.SetCustomAttribute (customattr);
569 result = typebuilder.CreateType ();
571 clsid_types.Add(clsid, result);
576 throw new NotImplementedException ("Unmanaged activation removed");
580 protected override TypeCode GetTypeCodeImpl ()
582 return GetTypeCodeImplInternal (this);
585 [MethodImplAttribute(MethodImplOptions.InternalCall)]
586 extern static TypeCode GetTypeCodeImplInternal (Type type);
588 internal static Type GetTypeFromProgIDImpl(String progID, String server, bool throwOnError)
590 throw new NotImplementedException ("Unmanaged activation is not supported");
593 public override string ToString()
595 return getFullName (false, false);
598 bool IsGenericCOMObjectImpl ()
603 [MethodImplAttribute (MethodImplOptions.InternalCall)]
604 static extern object CreateInstanceInternal (Type type);
606 public extern override MethodBase DeclaringMethod {
607 [MethodImplAttribute(MethodImplOptions.InternalCall)]
611 [MethodImplAttribute(MethodImplOptions.InternalCall)]
612 internal extern string getFullName(bool full_name, bool assembly_qualified);
614 [MethodImplAttribute(MethodImplOptions.InternalCall)]
615 public extern override Type [] GetGenericArguments ();
617 [MethodImplAttribute(MethodImplOptions.InternalCall)]
618 extern GenericParameterAttributes GetGenericParameterAttributes ();
620 [MethodImplAttribute(MethodImplOptions.InternalCall)]
621 extern Type[] GetGenericParameterConstraints_impl ();
623 [MethodImplAttribute(MethodImplOptions.InternalCall)]
624 extern int GetGenericParameterPosition ();
626 [MethodImplAttribute(MethodImplOptions.InternalCall)]
627 extern RuntimeEventInfo[] GetEvents_internal (string name, BindingFlags bindingAttr, Type reflected_type);
629 [MethodImplAttribute(MethodImplOptions.InternalCall)]
630 extern RuntimeFieldInfo[] GetFields_internal (string name, BindingFlags bindingAttr, Type reflected_type);
632 [MethodImplAttribute(MethodImplOptions.InternalCall)]
633 public extern override Type[] GetInterfaces();
635 [MethodImplAttribute(MethodImplOptions.InternalCall)]
636 extern RuntimeType[] GetNestedTypes_internal (string name, BindingFlags bindingAttr);
638 public override string AssemblyQualifiedName {
640 return getFullName (true, true);
644 public extern override Type DeclaringType {
645 [MethodImplAttribute(MethodImplOptions.InternalCall)]
649 public override string FullName {
651 throw new NotImplementedException ();
655 public extern override string Name {
656 [MethodImplAttribute(MethodImplOptions.InternalCall)]
660 public extern override string Namespace {
661 [MethodImplAttribute(MethodImplOptions.InternalCall)]
665 //seclevel { transparent = 0, safe-critical = 1, critical = 2}
666 [MethodImplAttribute(MethodImplOptions.InternalCall)]
667 public extern int get_core_clr_security_level ();
669 public override bool IsSecurityTransparent {
670 get { return get_core_clr_security_level () == 0; }
673 public override bool IsSecurityCritical {
674 get { return get_core_clr_security_level () > 0; }
677 public override bool IsSecuritySafeCritical {
678 get { return get_core_clr_security_level () == 1; }