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 Object GenericCache;
48 internal virtual MonoCMethod GetDefaultConstructor ()
50 // TODO: Requires MonoType
51 throw new NotSupportedException ();
54 string GetDefaultMemberName ()
56 object [] att = GetCustomAttributes (typeof (DefaultMemberAttribute), true);
57 return att.Length != 0 ? ((DefaultMemberAttribute) att [0]).MemberName : null;
60 RuntimeConstructorInfo m_serializationCtor;
61 internal RuntimeConstructorInfo GetSerializationCtor()
63 if (m_serializationCtor == null) {
64 var s_SICtorParamTypes = new Type[] { typeof(SerializationInfo), typeof(StreamingContext) };
66 m_serializationCtor = GetConstructor(
67 BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
69 CallingConventions.Any,
71 null) as RuntimeConstructorInfo;
74 return m_serializationCtor;
77 internal Object CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fillCache, ref StackCrawlMark stackMark)
79 bool bNeedSecurityCheck = true;
80 bool bCanBeCached = false;
81 bool bSecurityCheckOff = false;
84 CreateInstanceCheckThis();
87 bSecurityCheckOff = true;
89 return CreateInstanceMono (!publicOnly);
92 object CreateInstanceMono (bool nonPublic)
94 var ctor = GetDefaultConstructor ();
95 if (!nonPublic && ctor != null && !ctor.IsPublic) {
100 Type elementType = this.GetRootElementType();
101 if (ReferenceEquals (elementType, typeof (TypedReference)) || ReferenceEquals (elementType, typeof (RuntimeArgumentHandle)))
102 throw new NotSupportedException (Environment.GetResourceString ("NotSupported_ContainsStackPtr"));
105 return CreateInstanceInternal (this);
107 throw new MissingMethodException (Locale.GetText ("Default constructor not found for type " + FullName));
110 // TODO: .net does more checks in unmanaged land in RuntimeTypeHandle::CreateInstance
112 throw new MissingMethodException (Locale.GetText ("Cannot create an abstract class '{0}'.", FullName));
115 return ctor.InternalInvoke (null, null);
118 internal Object CheckValue (Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
121 var res = TryConvertToType (value, ref failed);
125 if ((invokeAttr & BindingFlags.ExactBinding) == BindingFlags.ExactBinding)
126 throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
128 if (binder != null && binder != Type.DefaultBinder)
129 return binder.ChangeType (value, this, culture);
131 throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
134 object TryConvertToType (object value, ref bool failed)
136 if (IsInstanceOfType (value)) {
141 var elementType = GetElementType ();
142 if (value == null || elementType.IsInstanceOfType (value)) {
151 var type = Enum.GetUnderlyingType (this);
152 if (type == value.GetType ())
154 var res = IsConvertibleToPrimitiveType (value, this);
157 } else if (IsPrimitive) {
158 var res = IsConvertibleToPrimitiveType (value, this);
161 } else if (IsPointer) {
162 var vtype = value.GetType ();
163 if (vtype == typeof (IntPtr) || vtype == typeof (UIntPtr))
171 // Binder uses some incompatible conversion rules. For example
172 // int value cannot be used with decimal parameter but in other
173 // ways it's more flexible than normal convertor, for example
174 // long value can be used with int based enum
175 static object IsConvertibleToPrimitiveType (object value, Type targetType)
177 var type = value.GetType ();
179 type = Enum.GetUnderlyingType (type);
180 if (type == targetType)
184 var from = Type.GetTypeCode (type);
185 var to = Type.GetTypeCode (targetType);
191 return (Char) (Byte) value;
192 case TypeCode.UInt16:
199 return (Int16) (Byte) value;
201 return (Int16) (SByte) value;
204 case TypeCode.UInt16:
207 return (UInt16) (Byte) value;
215 return (Int32) (Byte) value;
217 return (Int32) (SByte) value;
219 return (Int32) (Char) value;
221 return (Int32) (Int16) value;
222 case TypeCode.UInt16:
223 return (Int32) (UInt16) value;
226 case TypeCode.UInt32:
229 return (UInt32) (Byte) value;
231 return (UInt32) (Char) value;
232 case TypeCode.UInt16:
233 return (UInt32) (UInt16) value;
239 return (Int64) (Byte) value;
241 return (Int64) (SByte) value;
243 return (Int64) (Int16) value;
245 return (Int64) (Char) value;
246 case TypeCode.UInt16:
247 return (Int64) (UInt16) value;
249 return (Int64) (Int32) value;
250 case TypeCode.UInt32:
251 return (Int64) (UInt32) value;
254 case TypeCode.UInt64:
257 return (UInt64) (Byte) value;
259 return (UInt64) (Char) value;
260 case TypeCode.UInt16:
261 return (UInt64) (UInt16) value;
262 case TypeCode.UInt32:
263 return (UInt64) (UInt32) value;
266 case TypeCode.Single:
269 return (Single) (Byte) value;
271 return (Single) (SByte) value;
273 return (Single) (Int16) value;
275 return (Single) (Char) value;
276 case TypeCode.UInt16:
277 return (Single) (UInt16) value;
279 return (Single) (Int32) value;
280 case TypeCode.UInt32:
281 return (Single) (UInt32) value;
283 return (Single) (Int64) value;
284 case TypeCode.UInt64:
285 return (Single) (UInt64) value;
288 case TypeCode.Double:
291 return (Double) (Byte) value;
293 return (Double) (SByte) value;
295 return (Double) (Char) value;
297 return (Double) (Int16) value;
298 case TypeCode.UInt16:
299 return (Double) (UInt16) value;
301 return (Double) (Int32) value;
302 case TypeCode.UInt32:
303 return (Double) (UInt32) value;
305 return (Double) (Int64) value;
306 case TypeCode.UInt64:
307 return (Double) (UInt64) value;
308 case TypeCode.Single:
309 return (Double) (Single) value;
314 // Everything else is rejected
318 string GetCachedName (TypeNameKind kind)
321 case TypeNameKind.SerializationName:
324 throw new NotImplementedException ();
328 [MethodImplAttribute(MethodImplOptions.InternalCall)]
329 extern Type make_array_type (int rank);
331 public override Type MakeArrayType ()
333 return make_array_type (0);
336 public override Type MakeArrayType (int rank)
338 if (rank < 1 || rank > 255)
339 throw new IndexOutOfRangeException ();
340 return make_array_type (rank);
343 [MethodImplAttribute(MethodImplOptions.InternalCall)]
344 extern Type make_byref_type ();
346 public override Type MakeByRefType ()
349 throw new TypeLoadException ("Can not call MakeByRefType on a ByRef type");
350 return make_byref_type ();
353 [MethodImplAttribute(MethodImplOptions.InternalCall)]
354 static extern Type MakePointerType (Type type);
356 public override Type MakePointerType ()
358 return MakePointerType (this);
361 public override StructLayoutAttribute StructLayoutAttribute {
363 return StructLayoutAttribute.GetCustomAttribute (this);
367 public override bool ContainsGenericParameters {
369 if (IsGenericParameter)
373 foreach (Type arg in GetGenericArguments ())
374 if (arg.ContainsGenericParameters)
379 return GetElementType ().ContainsGenericParameters;
385 public override Type[] GetGenericParameterConstraints()
387 if (!IsGenericParameter)
388 throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
389 Contract.EndContractBlock();
391 Type[] constraints = GetGenericParameterConstraints_impl ();
393 if (constraints == null)
394 constraints = EmptyArray<Type>.Value;
399 internal static object CreateInstanceForAnotherGenericParameter (Type genericType, RuntimeType genericArgument)
401 var gt = (RuntimeType) MakeGenericType (genericType, new Type [] { genericArgument });
402 var ctor = gt.GetDefaultConstructor ();
403 return ctor.InternalInvoke (null, null);
406 [MethodImplAttribute(MethodImplOptions.InternalCall)]
407 static extern Type MakeGenericType (Type gt, Type [] types);
409 [MethodImplAttribute(MethodImplOptions.InternalCall)]
410 internal extern RuntimeMethodInfo[] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type);
412 [MethodImplAttribute(MethodImplOptions.InternalCall)]
413 extern RuntimePropertyInfo[] GetPropertiesByName (string name, BindingFlags bindingAttr, bool icase, Type reflected_type);
415 [MethodImplAttribute(MethodImplOptions.InternalCall)]
416 extern RuntimeConstructorInfo[] GetConstructors_internal (BindingFlags bindingAttr, Type reflected_type);
418 public override InterfaceMapping GetInterfaceMap (Type ifaceType)
420 if (IsGenericParameter)
421 throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
423 if ((object)ifaceType == null)
424 throw new ArgumentNullException("ifaceType");
425 Contract.EndContractBlock();
427 RuntimeType ifaceRtType = ifaceType as RuntimeType;
429 if (ifaceRtType == null)
430 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "ifaceType");
432 InterfaceMapping res;
433 if (!ifaceType.IsInterface)
434 throw new ArgumentException (Locale.GetText ("Argument must be an interface."), "ifaceType");
436 throw new ArgumentException ("'this' type cannot be an interface itself");
437 res.TargetType = this;
438 res.InterfaceType = ifaceType;
439 GetInterfaceMapData (this, ifaceType, out res.TargetMethods, out res.InterfaceMethods);
440 if (res.TargetMethods == null)
441 throw new ArgumentException (Locale.GetText ("Interface not found"), "ifaceType");
446 [MethodImplAttribute(MethodImplOptions.InternalCall)]
447 static extern void GetInterfaceMapData (Type t, Type iface, out MethodInfo[] targets, out MethodInfo[] methods);
449 public override Guid GUID {
451 object[] att = GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), true);
454 return new Guid(((System.Runtime.InteropServices.GuidAttribute)att[0]).Value);
458 [MethodImplAttribute(MethodImplOptions.InternalCall)]
459 internal extern void GetPacking (out int packing, out int size);
462 private static Dictionary<Guid, Type> clsid_types;
463 private static AssemblyBuilder clsid_assemblybuilder;
466 internal static Type GetTypeFromCLSIDImpl(Guid clsid, String server, bool throwOnError)
471 if (clsid_types == null)
473 Dictionary<Guid, Type> new_clsid_types = new Dictionary<Guid, Type> ();
474 Interlocked.CompareExchange<Dictionary<Guid, Type>>(
475 ref clsid_types, new_clsid_types, null);
479 if (clsid_types.TryGetValue(clsid, out result))
482 if (clsid_assemblybuilder == null)
484 AssemblyName assemblyname = new AssemblyName ();
485 assemblyname.Name = "GetTypeFromCLSIDDummyAssembly";
486 clsid_assemblybuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (
487 assemblyname, AssemblyBuilderAccess.Run);
489 ModuleBuilder modulebuilder = clsid_assemblybuilder.DefineDynamicModule (
492 TypeBuilder typebuilder = modulebuilder.DefineType ("System.__ComObject",
493 TypeAttributes.Public | TypeAttributes.Class, typeof(System.__ComObject));
495 Type[] guidattrtypes = new Type[] { typeof(string) };
497 CustomAttributeBuilder customattr = new CustomAttributeBuilder (
498 typeof(GuidAttribute).GetConstructor (guidattrtypes),
499 new object[] { clsid.ToString () });
501 typebuilder.SetCustomAttribute (customattr);
503 customattr = new CustomAttributeBuilder (
504 typeof(ComImportAttribute).GetConstructor (EmptyTypes),
507 typebuilder.SetCustomAttribute (customattr);
509 result = typebuilder.CreateType ();
511 clsid_types.Add(clsid, result);
516 throw new NotImplementedException ("Unmanaged activation removed");
520 protected override TypeCode GetTypeCodeImpl ()
522 return GetTypeCodeImplInternal (this);
525 [MethodImplAttribute(MethodImplOptions.InternalCall)]
526 extern static TypeCode GetTypeCodeImplInternal (Type type);
528 internal static Type GetTypeFromProgIDImpl(String progID, String server, bool throwOnError)
530 throw new NotImplementedException ("Unmanaged activation is not supported");
533 public override string ToString()
535 return getFullName (false, false);
538 bool IsGenericCOMObjectImpl ()
543 [MethodImplAttribute (MethodImplOptions.InternalCall)]
544 static extern object CreateInstanceInternal (Type type);
546 public extern override MethodBase DeclaringMethod {
547 [MethodImplAttribute(MethodImplOptions.InternalCall)]
551 [MethodImplAttribute(MethodImplOptions.InternalCall)]
552 internal extern string getFullName(bool full_name, bool assembly_qualified);
554 [MethodImplAttribute(MethodImplOptions.InternalCall)]
555 extern Type[] GetGenericArgumentsInternal (bool runtimeArray);
557 [MethodImplAttribute(MethodImplOptions.InternalCall)]
558 extern GenericParameterAttributes GetGenericParameterAttributes ();
560 [MethodImplAttribute(MethodImplOptions.InternalCall)]
561 extern Type[] GetGenericParameterConstraints_impl ();
563 [MethodImplAttribute(MethodImplOptions.InternalCall)]
564 extern int GetGenericParameterPosition ();
566 [MethodImplAttribute(MethodImplOptions.InternalCall)]
567 extern RuntimeEventInfo[] GetEvents_internal (string name, BindingFlags bindingAttr, Type reflected_type);
569 [MethodImplAttribute(MethodImplOptions.InternalCall)]
570 extern RuntimeFieldInfo[] GetFields_internal (string name, BindingFlags bindingAttr, Type reflected_type);
572 [MethodImplAttribute(MethodImplOptions.InternalCall)]
573 public extern override Type[] GetInterfaces();
575 [MethodImplAttribute(MethodImplOptions.InternalCall)]
576 extern RuntimeType[] GetNestedTypes_internal (string name, BindingFlags bindingAttr);
578 public override string AssemblyQualifiedName {
580 return getFullName (true, true);
584 public extern override Type DeclaringType {
585 [MethodImplAttribute(MethodImplOptions.InternalCall)]
589 public override string FullName {
591 throw new NotImplementedException ();
595 public extern override string Name {
596 [MethodImplAttribute(MethodImplOptions.InternalCall)]
600 public extern override string Namespace {
601 [MethodImplAttribute(MethodImplOptions.InternalCall)]
606 static int get_core_clr_security_level ()
611 //seclevel { transparent = 0, safe-critical = 1, critical = 2}
612 [MethodImplAttribute(MethodImplOptions.InternalCall)]
613 public extern int get_core_clr_security_level ();
615 public override bool IsSecurityTransparent {
616 get { return get_core_clr_security_level () == 0; }
619 public override bool IsSecurityCritical {
620 get { return get_core_clr_security_level () > 0; }
623 public override bool IsSecuritySafeCritical {
624 get { return get_core_clr_security_level () == 1; }