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 StructLayoutAttribute.GetCustomAttribute (this);
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 internal static object CreateInstanceForAnotherGenericParameter (Type genericType, RuntimeType genericArgument)
399 var gt = (RuntimeType) MakeGenericType (genericType, new Type [] { genericArgument });
400 var ctor = gt.GetDefaultConstructor ();
401 return ctor.InternalInvoke (null, null);
404 [MethodImplAttribute(MethodImplOptions.InternalCall)]
405 static extern Type MakeGenericType (Type gt, Type [] types);
407 [MethodImplAttribute(MethodImplOptions.InternalCall)]
408 internal extern RuntimeMethodInfo[] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type);
410 [MethodImplAttribute(MethodImplOptions.InternalCall)]
411 extern RuntimePropertyInfo[] GetPropertiesByName (string name, BindingFlags bindingAttr, bool icase, Type reflected_type);
413 [MethodImplAttribute(MethodImplOptions.InternalCall)]
414 extern RuntimeConstructorInfo[] GetConstructors_internal (BindingFlags bindingAttr, Type reflected_type);
416 public override InterfaceMapping GetInterfaceMap (Type ifaceType)
418 if (IsGenericParameter)
419 throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
421 if ((object)ifaceType == null)
422 throw new ArgumentNullException("ifaceType");
423 Contract.EndContractBlock();
425 RuntimeType ifaceRtType = ifaceType as RuntimeType;
427 if (ifaceRtType == null)
428 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "ifaceType");
430 InterfaceMapping res;
431 if (!ifaceType.IsInterface)
432 throw new ArgumentException (Locale.GetText ("Argument must be an interface."), "ifaceType");
434 throw new ArgumentException ("'this' type cannot be an interface itself");
435 res.TargetType = this;
436 res.InterfaceType = ifaceType;
437 GetInterfaceMapData (this, ifaceType, out res.TargetMethods, out res.InterfaceMethods);
438 if (res.TargetMethods == null)
439 throw new ArgumentException (Locale.GetText ("Interface not found"), "ifaceType");
444 [MethodImplAttribute(MethodImplOptions.InternalCall)]
445 static extern void GetInterfaceMapData (Type t, Type iface, out MethodInfo[] targets, out MethodInfo[] methods);
447 public override Guid GUID {
449 object[] att = GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), true);
452 return new Guid(((System.Runtime.InteropServices.GuidAttribute)att[0]).Value);
456 [MethodImplAttribute(MethodImplOptions.InternalCall)]
457 internal extern void GetPacking (out int packing, out int size);
460 private static Dictionary<Guid, Type> clsid_types;
461 private static AssemblyBuilder clsid_assemblybuilder;
464 internal static Type GetTypeFromCLSIDImpl(Guid clsid, String server, bool throwOnError)
469 if (clsid_types == null)
471 Dictionary<Guid, Type> new_clsid_types = new Dictionary<Guid, Type> ();
472 Interlocked.CompareExchange<Dictionary<Guid, Type>>(
473 ref clsid_types, new_clsid_types, null);
477 if (clsid_types.TryGetValue(clsid, out result))
480 if (clsid_assemblybuilder == null)
482 AssemblyName assemblyname = new AssemblyName ();
483 assemblyname.Name = "GetTypeFromCLSIDDummyAssembly";
484 clsid_assemblybuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (
485 assemblyname, AssemblyBuilderAccess.Run);
487 ModuleBuilder modulebuilder = clsid_assemblybuilder.DefineDynamicModule (
490 TypeBuilder typebuilder = modulebuilder.DefineType ("System.__ComObject",
491 TypeAttributes.Public | TypeAttributes.Class, typeof(System.__ComObject));
493 Type[] guidattrtypes = new Type[] { typeof(string) };
495 CustomAttributeBuilder customattr = new CustomAttributeBuilder (
496 typeof(GuidAttribute).GetConstructor (guidattrtypes),
497 new object[] { clsid.ToString () });
499 typebuilder.SetCustomAttribute (customattr);
501 customattr = new CustomAttributeBuilder (
502 typeof(ComImportAttribute).GetConstructor (EmptyTypes),
505 typebuilder.SetCustomAttribute (customattr);
507 result = typebuilder.CreateType ();
509 clsid_types.Add(clsid, result);
514 throw new NotImplementedException ("Unmanaged activation removed");
518 protected override TypeCode GetTypeCodeImpl ()
520 return GetTypeCodeImplInternal (this);
523 [MethodImplAttribute(MethodImplOptions.InternalCall)]
524 extern static TypeCode GetTypeCodeImplInternal (Type type);
526 internal static Type GetTypeFromProgIDImpl(String progID, String server, bool throwOnError)
528 throw new NotImplementedException ("Unmanaged activation is not supported");
531 public override string ToString()
533 return getFullName (false, false);
536 bool IsGenericCOMObjectImpl ()
541 [MethodImplAttribute (MethodImplOptions.InternalCall)]
542 static extern object CreateInstanceInternal (Type type);
544 public extern override MethodBase DeclaringMethod {
545 [MethodImplAttribute(MethodImplOptions.InternalCall)]
549 [MethodImplAttribute(MethodImplOptions.InternalCall)]
550 internal extern string getFullName(bool full_name, bool assembly_qualified);
552 [MethodImplAttribute(MethodImplOptions.InternalCall)]
553 extern Type[] GetGenericArgumentsInternal (bool runtimeArray);
555 [MethodImplAttribute(MethodImplOptions.InternalCall)]
556 extern GenericParameterAttributes GetGenericParameterAttributes ();
558 [MethodImplAttribute(MethodImplOptions.InternalCall)]
559 extern Type[] GetGenericParameterConstraints_impl ();
561 [MethodImplAttribute(MethodImplOptions.InternalCall)]
562 extern int GetGenericParameterPosition ();
564 [MethodImplAttribute(MethodImplOptions.InternalCall)]
565 extern RuntimeEventInfo[] GetEvents_internal (string name, BindingFlags bindingAttr, Type reflected_type);
567 [MethodImplAttribute(MethodImplOptions.InternalCall)]
568 extern RuntimeFieldInfo[] GetFields_internal (string name, BindingFlags bindingAttr, Type reflected_type);
570 [MethodImplAttribute(MethodImplOptions.InternalCall)]
571 public extern override Type[] GetInterfaces();
573 [MethodImplAttribute(MethodImplOptions.InternalCall)]
574 extern RuntimeType[] GetNestedTypes_internal (string name, BindingFlags bindingAttr);
576 public override string AssemblyQualifiedName {
578 return getFullName (true, true);
582 public extern override Type DeclaringType {
583 [MethodImplAttribute(MethodImplOptions.InternalCall)]
587 public override string FullName {
589 throw new NotImplementedException ();
593 public extern override string Name {
594 [MethodImplAttribute(MethodImplOptions.InternalCall)]
598 public extern override string Namespace {
599 [MethodImplAttribute(MethodImplOptions.InternalCall)]
603 //seclevel { transparent = 0, safe-critical = 1, critical = 2}
604 [MethodImplAttribute(MethodImplOptions.InternalCall)]
605 public extern int get_core_clr_security_level ();
607 public override bool IsSecurityTransparent {
608 get { return get_core_clr_security_level () == 0; }
611 public override bool IsSecurityCritical {
612 get { return get_core_clr_security_level () > 0; }
615 public override bool IsSecuritySafeCritical {
616 get { return get_core_clr_security_level () == 1; }