// // Wrapper handles for Mono Runtime internal structs // // Authors: // Aleksey Kliger // Rodrigo Kumpera // // Copyright 2016 Dot net foundation. // Licensed under the MIT license. See LICENSE file in the project root for full license information. // using System; using System.Reflection; using System.Runtime.CompilerServices; namespace Mono { internal struct RuntimeClassHandle { unsafe RuntimeStructs.MonoClass* value; internal unsafe RuntimeClassHandle (RuntimeStructs.MonoClass* value) { this.value = value; } internal unsafe RuntimeClassHandle (IntPtr ptr) { this.value = (RuntimeStructs.MonoClass*) ptr; } internal unsafe RuntimeStructs.MonoClass* Value { get { return value; } } public override bool Equals (object obj) { if (obj == null || GetType () != obj.GetType ()) return false; unsafe { return value == ((RuntimeClassHandle)obj).Value; } } public override int GetHashCode () { unsafe { return ((IntPtr)value).GetHashCode (); } } public bool Equals (RuntimeClassHandle handle) { unsafe { return value == handle.Value; } } public static bool operator == (RuntimeClassHandle left, Object right) { return (right != null) && (right is RuntimeClassHandle) && left.Equals ((RuntimeClassHandle)right); } public static bool operator != (RuntimeClassHandle left, Object right) { return (right == null) || !(right is RuntimeClassHandle) || !left.Equals ((RuntimeClassHandle)right); } public static bool operator == (Object left, RuntimeClassHandle right) { return (left != null) && (left is RuntimeClassHandle) && ((RuntimeClassHandle)left).Equals (right); } public static bool operator != (Object left, RuntimeClassHandle right) { return (left == null) || !(left is RuntimeClassHandle) || !((RuntimeClassHandle)left).Equals (right); } [MethodImpl(MethodImplOptions.InternalCall)] internal unsafe extern static IntPtr GetTypeFromClass (RuntimeStructs.MonoClass *klass); internal RuntimeTypeHandle GetTypeHandle () { unsafe { return new RuntimeTypeHandle (GetTypeFromClass (value)); } } } internal struct RuntimeRemoteClassHandle { unsafe RuntimeStructs.RemoteClass* value; internal unsafe RuntimeRemoteClassHandle (RuntimeStructs.RemoteClass* value) { this.value = value; } internal RuntimeClassHandle ProxyClass { get { unsafe { return new RuntimeClassHandle (value->proxy_class); } } } } internal struct RuntimeGenericParamInfoHandle { unsafe RuntimeStructs.GenericParamInfo* value; internal unsafe RuntimeGenericParamInfoHandle (RuntimeStructs.GenericParamInfo* value) { this.value = value; } internal unsafe RuntimeGenericParamInfoHandle (IntPtr ptr) { this.value = (RuntimeStructs.GenericParamInfo*) ptr; } internal Type[] Constraints { get { return GetConstraints (); } } internal GenericParameterAttributes Attributes { get { unsafe { return (GenericParameterAttributes) value->flags; } } } Type[] GetConstraints () { int n = GetConstraintsCount (); var a = new Type[n]; for (int i = 0; i < n; i++) { unsafe { RuntimeClassHandle c = new RuntimeClassHandle (value->constraints[i]); a[i] = Type.GetTypeFromHandle (c.GetTypeHandle ()); } } return a; } int GetConstraintsCount () { int i = 0; unsafe { RuntimeStructs.MonoClass** p = value->constraints; while (p != null && *p != null) { p++; i++; } } return i; } } internal struct RuntimeEventHandle { IntPtr value; internal RuntimeEventHandle (IntPtr v) { value = v; } public IntPtr Value { get { return value; } } public override bool Equals (object obj) { if (obj == null || GetType () != obj.GetType ()) return false; return value == ((RuntimeEventHandle)obj).Value; } public bool Equals (RuntimeEventHandle handle) { return value == handle.Value; } public override int GetHashCode () { return value.GetHashCode (); } public static bool operator == (RuntimeEventHandle left, RuntimeEventHandle right) { return left.Equals (right); } public static bool operator != (RuntimeEventHandle left, RuntimeEventHandle right) { return !left.Equals (right); } } internal struct RuntimePropertyHandle { IntPtr value; internal RuntimePropertyHandle (IntPtr v) { value = v; } public IntPtr Value { get { return value; } } public override bool Equals (object obj) { if (obj == null || GetType () != obj.GetType ()) return false; return value == ((RuntimePropertyHandle)obj).Value; } public bool Equals (RuntimePropertyHandle handle) { return value == handle.Value; } public override int GetHashCode () { return value.GetHashCode (); } public static bool operator == (RuntimePropertyHandle left, RuntimePropertyHandle right) { return left.Equals (right); } public static bool operator != (RuntimePropertyHandle left, RuntimePropertyHandle right) { return !left.Equals (right); } } internal struct RuntimeGPtrArrayHandle { unsafe RuntimeStructs.GPtrArray* value; internal unsafe RuntimeGPtrArrayHandle (RuntimeStructs.GPtrArray* value) { this.value = value; } internal unsafe RuntimeGPtrArrayHandle (IntPtr ptr) { this.value = (RuntimeStructs.GPtrArray*) ptr; } internal int Length { get { unsafe { return value->len; } } } internal IntPtr this[int i] => Lookup (i); internal IntPtr Lookup (int i) { if (i >= 0 && i < Length) { unsafe { return value->data[i]; } } else throw new IndexOutOfRangeException (); } [MethodImpl(MethodImplOptions.InternalCall)] unsafe extern static void GPtrArrayFree (RuntimeStructs.GPtrArray* value); internal static void DestroyAndFree (ref RuntimeGPtrArrayHandle h) { unsafe { GPtrArrayFree (h.value); h.value = null; } } } }