Merge pull request #3290 from BrzVlad/fix-finalizer-tests
[mono.git] / mcs / class / corlib / Mono / RuntimeHandles.cs
1 //
2 // Wrapper handles for Mono Runtime internal structs
3 //
4 // Authors:
5 //   Aleksey Kliger <aleksey@xamarin.com>
6 //   Rodrigo Kumpera <kumpera@xamarin.com>
7 //
8 // Copyright 2016 Dot net foundation.
9 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
10 //
11
12 using System;
13 using System.Reflection;
14 using System.Runtime.CompilerServices;
15
16 namespace Mono {
17
18         internal struct RuntimeClassHandle {
19                 unsafe RuntimeStructs.MonoClass* value;
20
21                 internal unsafe RuntimeClassHandle (RuntimeStructs.MonoClass* value) {
22                         this.value = value;
23                 }
24
25                 internal unsafe RuntimeClassHandle (IntPtr ptr) {
26                         this.value = (RuntimeStructs.MonoClass*) ptr;
27                 }
28
29                 internal unsafe RuntimeStructs.MonoClass* Value {
30                         get { return value; }
31                 }
32
33                 public override bool Equals (object obj)
34                 {
35                         if (obj == null || GetType () != obj.GetType ())
36                                 return false;
37
38                         unsafe { return value == ((RuntimeClassHandle)obj).Value; }
39                 }
40
41                 public override int GetHashCode ()
42                 {
43                         unsafe { return ((IntPtr)value).GetHashCode (); }
44                 }
45
46                 public bool Equals (RuntimeClassHandle handle)
47                 {
48                         unsafe { return value == handle.Value; }
49                 }
50
51                 public static bool operator == (RuntimeClassHandle left, Object right)
52                 {
53                         return (right != null) && (right is RuntimeClassHandle) && left.Equals ((RuntimeClassHandle)right);
54                 }
55
56                 public static bool operator != (RuntimeClassHandle left, Object right)
57                 {
58                         return (right == null) || !(right is RuntimeClassHandle) || !left.Equals ((RuntimeClassHandle)right);
59                 }
60
61                 public static bool operator == (Object left, RuntimeClassHandle right)
62                 {
63                         return (left != null) && (left is RuntimeClassHandle) && ((RuntimeClassHandle)left).Equals (right);
64                 }
65
66                 public static bool operator != (Object left, RuntimeClassHandle right)
67                 {
68                         return (left == null) || !(left is RuntimeClassHandle) || !((RuntimeClassHandle)left).Equals (right);
69                 }
70
71                 [MethodImpl(MethodImplOptions.InternalCall)]
72                 internal unsafe extern static IntPtr GetTypeFromClass (RuntimeStructs.MonoClass *klass);
73
74                 internal RuntimeTypeHandle GetTypeHandle ()
75                 {
76                         unsafe { return new RuntimeTypeHandle (GetTypeFromClass (value)); }
77                 }
78         }
79
80         internal struct RuntimeRemoteClassHandle {
81                 unsafe RuntimeStructs.RemoteClass* value;
82
83                 internal unsafe RuntimeRemoteClassHandle (RuntimeStructs.RemoteClass* value)
84                 {
85                         this.value = value;
86                 }
87
88                 internal RuntimeClassHandle ProxyClass {
89                         get {
90                                 unsafe {
91                                         return new RuntimeClassHandle (value->proxy_class);
92                                 }
93                         }
94                 }
95         }
96
97         internal struct RuntimeGenericParamInfoHandle {
98                 unsafe RuntimeStructs.GenericParamInfo* value;
99
100                 internal unsafe RuntimeGenericParamInfoHandle (RuntimeStructs.GenericParamInfo* value)
101                 {
102                         this.value = value;
103                 }
104
105                 internal unsafe RuntimeGenericParamInfoHandle (IntPtr ptr)
106                 {
107                         this.value = (RuntimeStructs.GenericParamInfo*) ptr;
108                 }
109
110
111                 internal Type[] Constraints { get { return GetConstraints (); } }
112
113                 internal GenericParameterAttributes Attributes {
114                         get {
115                                 unsafe {
116                                         return (GenericParameterAttributes) value->flags;
117                                 }
118                         }
119                 }
120
121                 Type[] GetConstraints () {
122                         int n = GetConstraintsCount ();
123                         var a = new Type[n];
124                         for (int i = 0; i < n; i++) {
125                                 unsafe {
126                                         RuntimeClassHandle c = new RuntimeClassHandle (value->constraints[i]);
127                                         a[i] = Type.GetTypeFromHandle (c.GetTypeHandle ());
128                                 }
129                         }
130                         return a;
131                 }
132
133                 int GetConstraintsCount () {
134                         int i = 0;
135                         unsafe {
136                                 RuntimeStructs.MonoClass** p = value->constraints;
137                                 while (p != null && *p != null)  {
138                                         p++; i++;
139                                 }
140                         }
141                         return i;
142                 }
143         }
144
145         internal struct RuntimeEventHandle {
146                 IntPtr value;
147
148                 internal RuntimeEventHandle (IntPtr v)
149                 {
150                         value = v;
151                 }
152
153                 public IntPtr Value {
154                         get {
155                                 return value;
156                         }
157                 }
158
159                 public override bool Equals (object obj)
160                 {
161                         if (obj == null || GetType () != obj.GetType ())
162                                 return false;
163
164                         return value == ((RuntimeEventHandle)obj).Value;
165                 }
166
167                 public bool Equals (RuntimeEventHandle handle)
168                 {
169                         return value == handle.Value;
170                 }
171
172                 public override int GetHashCode ()
173                 {
174                         return value.GetHashCode ();
175                 }
176
177                 public static bool operator == (RuntimeEventHandle left, RuntimeEventHandle right)
178                 {
179                         return left.Equals (right);
180                 }
181
182                 public static bool operator != (RuntimeEventHandle left, RuntimeEventHandle right)
183                 {
184                         return !left.Equals (right);
185                 }
186         }
187
188         internal struct RuntimePropertyHandle {
189                 IntPtr value;
190
191                 internal RuntimePropertyHandle (IntPtr v)
192                 {
193                         value = v;
194                 }
195
196                 public IntPtr Value {
197                         get {
198                                 return value;
199                         }
200                 }
201
202                 public override bool Equals (object obj)
203                 {
204                         if (obj == null || GetType () != obj.GetType ())
205                                 return false;
206
207                         return value == ((RuntimePropertyHandle)obj).Value;
208                 }
209
210                 public bool Equals (RuntimePropertyHandle handle)
211                 {
212                         return value == handle.Value;
213                 }
214
215                 public override int GetHashCode ()
216                 {
217                         return value.GetHashCode ();
218                 }
219
220                 public static bool operator == (RuntimePropertyHandle left, RuntimePropertyHandle right)
221                 {
222                         return left.Equals (right);
223                 }
224
225                 public static bool operator != (RuntimePropertyHandle left, RuntimePropertyHandle right)
226                 {
227                         return !left.Equals (right);
228                 }
229         }
230
231         internal struct RuntimeGPtrArrayHandle {
232                 unsafe RuntimeStructs.GPtrArray* value;
233
234                 internal unsafe RuntimeGPtrArrayHandle (RuntimeStructs.GPtrArray* value)
235                 {
236                         this.value = value;
237                 }
238
239                 internal unsafe RuntimeGPtrArrayHandle (IntPtr ptr)
240                 {
241                         this.value = (RuntimeStructs.GPtrArray*) ptr;
242                 }
243
244                 internal int Length {
245                         get {
246                                 unsafe {
247                                         return value->len;
248                                 }
249                         }
250                 }
251
252                 internal IntPtr this[int i] => Lookup (i);
253
254                 internal IntPtr Lookup (int i)
255                 {
256                         if (i >= 0 && i < Length) {
257                                 unsafe {
258                                         return value->data[i];
259                                 }
260                         } else
261                                 throw new IndexOutOfRangeException ();
262                 }
263
264                 [MethodImpl(MethodImplOptions.InternalCall)]
265                 unsafe extern static void GPtrArrayFree (RuntimeStructs.GPtrArray* value, bool freeSeg);
266
267                 internal static void DestroyAndFree (ref RuntimeGPtrArrayHandle h, bool freeSeg) {
268                         unsafe {
269                                 GPtrArrayFree (h.value, freeSeg);
270                                 h.value = null;
271                         }
272                 }
273         }
274 }