IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
MethodSignature.cs
Go to the documentation of this file.
1/*
2 Copyright (C) 2009-2011 Jeroen Frijters
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19
20 Jeroen Frijters
21 jeroen@frijters.net
22
23*/
24using System;
25using System.Collections.Generic;
26using System.Diagnostics;
27
31
32namespace IKVM.Reflection
33{
34
39 {
40
41 sealed class UnboundGenericMethodContext : IGenericContext
42 {
43
44 readonly IGenericContext original;
45
50 internal UnboundGenericMethodContext(IGenericContext original)
51 {
52 this.original = original;
53 }
54
55 public Type GetGenericTypeArgument(int index)
56 {
57 return original.GetGenericTypeArgument(index);
58 }
59
60 public Type GetGenericMethodArgument(int index)
61 {
62 return UnboundGenericMethodParameter.Make(index);
63 }
64
65 }
66
67 sealed class Binder : IGenericBinder
68 {
69
70 readonly Type declaringType;
71 readonly Type[] methodArgs;
72
78 internal Binder(Type declaringType, Type[] methodArgs)
79 {
80 this.declaringType = declaringType;
81 this.methodArgs = methodArgs;
82 }
83
84 public Type BindTypeParameter(Type type)
85 {
86 return declaringType.GetGenericTypeArgument(type.GenericParameterPosition);
87 }
88
89 public Type BindMethodParameter(Type type)
90 {
91 if (methodArgs == null)
92 return type;
93
94 return methodArgs[type.GenericParameterPosition];
95 }
96 }
97
98 sealed class Unbinder : IGenericBinder
99 {
100
101 internal static readonly Unbinder Instance = new Unbinder();
102
106 Unbinder()
107 {
108
109 }
110
111 public Type BindTypeParameter(Type type)
112 {
113 return type;
114 }
115
116 public Type BindMethodParameter(Type type)
117 {
118 return UnboundGenericMethodParameter.Make(type.GenericParameterPosition);
119 }
120
121 }
122
123 readonly Type returnType;
124 readonly Type[] parameterTypes;
125 readonly PackedCustomModifiers modifiers;
126 readonly CallingConventions callingConvention;
127 readonly int genericParamCount;
128
137 internal MethodSignature(Type returnType, Type[] parameterTypes, PackedCustomModifiers modifiers, CallingConventions callingConvention, int genericParamCount)
138 {
139 this.returnType = returnType;
140 this.parameterTypes = parameterTypes;
141 this.modifiers = modifiers;
142 this.callingConvention = callingConvention;
143 this.genericParamCount = genericParamCount;
144 }
145
146 public override bool Equals(object obj)
147 {
148 var other = obj as MethodSignature;
149 return other != null
150 && other.callingConvention == callingConvention
151 && other.genericParamCount == genericParamCount
152 && other.returnType.Equals(returnType)
153 && Util.ArrayEquals(other.parameterTypes, parameterTypes)
154 && other.modifiers.Equals(modifiers);
155 }
156
157 public override int GetHashCode()
158 {
159 return genericParamCount ^ 77 * (int)callingConvention
160 ^ 3 * returnType.GetHashCode()
161 ^ Util.GetHashCode(parameterTypes) * 5
162 ^ modifiers.GetHashCode() * 55;
163 }
164
165 internal static MethodSignature ReadSig(ModuleReader module, ByteReader br, IGenericContext context)
166 {
167 var flags = br.ReadByte();
168 var callingConvention = (flags & 7) switch
169 {
170 DEFAULT => CallingConventions.Standard,
171 VARARG => CallingConventions.VarArgs,
172 _ => throw new BadImageFormatException(),
173 };
174
175 if ((flags & HASTHIS) != 0)
176 callingConvention |= CallingConventions.HasThis;
177
178 if ((flags & EXPLICITTHIS) != 0)
179 callingConvention |= CallingConventions.ExplicitThis;
180
181 var genericParamCount = 0;
182 if ((flags & GENERIC) != 0)
183 {
184 genericParamCount = br.ReadCompressedUInt();
185 context = new UnboundGenericMethodContext(context);
186 }
187
188 var paramCount = br.ReadCompressedUInt();
189 CustomModifiers[] modifiers = null;
190 PackedCustomModifiers.Pack(ref modifiers, 0, CustomModifiers.Read(module, br, context), paramCount + 1);
191 var returnType = ReadRetType(module, br, context);
192
193 var parameterTypes = new Type[paramCount];
194 for (int i = 0; i < parameterTypes.Length; i++)
195 {
196 if ((callingConvention & CallingConventions.VarArgs) != 0 && br.PeekByte() == SENTINEL)
197 {
198 Array.Resize(ref parameterTypes, i);
199 if (modifiers != null)
200 Array.Resize(ref modifiers, i + 1);
201
202 break;
203 }
204
205 PackedCustomModifiers.Pack(ref modifiers, i + 1, CustomModifiers.Read(module, br, context), paramCount + 1);
206 parameterTypes[i] = ReadParam(module, br, context);
207 }
208
209 return new MethodSignature(returnType, parameterTypes, PackedCustomModifiers.Wrap(modifiers), callingConvention, genericParamCount);
210 }
211
212 internal static __StandAloneMethodSig ReadStandAloneMethodSig(ModuleReader module, ByteReader br, IGenericContext context)
213 {
214 CallingConventions callingConvention = 0;
215 System.Runtime.InteropServices.CallingConvention unmanagedCallingConvention = 0;
216 bool unmanaged;
217
218 var flags = br.ReadByte();
219 switch (flags & 7)
220 {
221 case DEFAULT:
222 callingConvention = CallingConventions.Standard;
223 unmanaged = false;
224 break;
225 case 0x01: // C
226 unmanagedCallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl;
227 unmanaged = true;
228 break;
229 case 0x02: // STDCALL
230 unmanagedCallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall;
231 unmanaged = true;
232 break;
233 case 0x03: // THISCALL
234 unmanagedCallingConvention = System.Runtime.InteropServices.CallingConvention.ThisCall;
235 unmanaged = true;
236 break;
237 case 0x04: // FASTCALL
238 unmanagedCallingConvention = System.Runtime.InteropServices.CallingConvention.FastCall;
239 unmanaged = true;
240 break;
241 case VARARG:
242 callingConvention = CallingConventions.VarArgs;
243 unmanaged = false;
244 break;
245 default:
246 throw new BadImageFormatException();
247 }
248
249 if ((flags & HASTHIS) != 0)
250 callingConvention |= CallingConventions.HasThis;
251 if ((flags & EXPLICITTHIS) != 0)
252 callingConvention |= CallingConventions.ExplicitThis;
253 if ((flags & GENERIC) != 0)
254 throw new BadImageFormatException();
255
256 var paramCount = br.ReadCompressedUInt();
257 CustomModifiers[] customModifiers = null;
258 PackedCustomModifiers.Pack(ref customModifiers, 0, CustomModifiers.Read(module, br, context), paramCount + 1);
259
260 var returnType = ReadRetType(module, br, context);
261
262 var parameterTypes = new List<Type>();
263 var optionalParameterTypes = new List<Type>();
264 var curr = parameterTypes;
265 for (int i = 0; i < paramCount; i++)
266 {
267 if (br.PeekByte() == SENTINEL)
268 {
269 br.ReadByte();
270 curr = optionalParameterTypes;
271 }
272
273 PackedCustomModifiers.Pack(ref customModifiers, i + 1, CustomModifiers.Read(module, br, context), paramCount + 1);
274 curr.Add(ReadParam(module, br, context));
275 }
276
277 return new __StandAloneMethodSig(unmanaged, unmanagedCallingConvention, callingConvention, returnType, parameterTypes.ToArray(), optionalParameterTypes.ToArray(), PackedCustomModifiers.Wrap(customModifiers));
278 }
279
280 internal int GetParameterCount()
281 {
282 return parameterTypes.Length;
283 }
284
285 internal Type GetParameterType(int index)
286 {
287 return parameterTypes[index];
288 }
289
290 internal Type GetReturnType(IGenericBinder binder)
291 {
292 return returnType.BindTypeParameters(binder);
293 }
294
295 internal CustomModifiers GetReturnTypeCustomModifiers(IGenericBinder binder)
296 {
297 return modifiers.GetReturnTypeCustomModifiers().Bind(binder);
298 }
299
300 internal Type GetParameterType(IGenericBinder binder, int index)
301 {
302 return parameterTypes[index].BindTypeParameters(binder);
303 }
304
305 internal CustomModifiers GetParameterCustomModifiers(IGenericBinder binder, int index)
306 {
307 return modifiers.GetParameterCustomModifiers(index).Bind(binder);
308 }
309
310 internal CallingConventions CallingConvention
311 {
312 get { return callingConvention; }
313 }
314
315 internal int GenericParameterCount
316 {
317 get { return genericParamCount; }
318 }
319
320 internal MethodSignature Bind(Type type, Type[] methodArgs)
321 {
322 var binder = new Binder(type, methodArgs);
323 return new MethodSignature(returnType.BindTypeParameters(binder), BindTypeParameters(binder, parameterTypes), modifiers.Bind(binder), callingConvention, genericParamCount);
324 }
325
326 internal static MethodSignature MakeFromBuilder(Type returnType, Type[] parameterTypes, PackedCustomModifiers modifiers, CallingConventions callingConvention, int genericParamCount)
327 {
328 if (genericParamCount > 0)
329 {
330 returnType = returnType.BindTypeParameters(Unbinder.Instance);
331 parameterTypes = BindTypeParameters(Unbinder.Instance, parameterTypes);
332 modifiers = modifiers.Bind(Unbinder.Instance);
333 }
334
335 return new MethodSignature(returnType, parameterTypes, modifiers, callingConvention, genericParamCount);
336 }
337
338 internal bool MatchParameterTypes(MethodSignature other)
339 {
340 return Util.ArrayEquals(other.parameterTypes, parameterTypes);
341 }
342
343 internal bool MatchParameterTypes(Type[] types)
344 {
345 return Util.ArrayEquals(types, parameterTypes);
346 }
347
348 internal override void Write(ModuleBuilder module, ByteBuffer bb)
349 {
350 WriteImpl(module, bb, parameterTypes.Length);
351 }
352
353 internal void WriteMethodRef(ModuleBuilder module, ByteBuffer bb, Type[] optionalParameterTypes, CustomModifiers[] customModifiers)
354 {
355 WriteImpl(module, bb, parameterTypes.Length + optionalParameterTypes.Length);
356
357 if (optionalParameterTypes.Length > 0)
358 {
359 bb.Write(SENTINEL);
360 for (int i = 0; i < optionalParameterTypes.Length; i++)
361 {
362 WriteCustomModifiers(module, bb, Util.NullSafeElementAt(customModifiers, i));
363 WriteType(module, bb, optionalParameterTypes[i]);
364 }
365 }
366 }
367
368 void WriteImpl(ModuleBuilder module, ByteBuffer bb, int parameterCount)
369 {
370 byte first;
371
372 if ((callingConvention & CallingConventions.Any) == CallingConventions.VarArgs)
373 {
374 Debug.Assert(genericParamCount == 0);
375 first = VARARG;
376 }
377 else if (genericParamCount > 0)
378 {
379 first = GENERIC;
380 }
381 else
382 {
383 first = DEFAULT;
384 }
385
386 if ((callingConvention & CallingConventions.HasThis) != 0)
387 first |= HASTHIS;
388
389 if ((callingConvention & CallingConventions.ExplicitThis) != 0)
390 first |= EXPLICITTHIS;
391
392 bb.Write(first);
393
394 if (genericParamCount > 0)
395 bb.WriteCompressedUInt(genericParamCount);
396
397 bb.WriteCompressedUInt(parameterCount);
398 // RetType
399 WriteCustomModifiers(module, bb, modifiers.GetReturnTypeCustomModifiers());
400 WriteType(module, bb, returnType);
401
402 // Param
403 for (int i = 0; i < parameterTypes.Length; i++)
404 {
405 WriteCustomModifiers(module, bb, modifiers.GetParameterCustomModifiers(i));
406 WriteType(module, bb, parameterTypes[i]);
407 }
408 }
409
410 }
411
412}
IKVM.Reflection.Type Type
System.Runtime.InteropServices.CallingConvention CallingConvention
Definition Signature.cs:35
Represents a method signature from IL metadadata.
override bool Equals(object obj)
static void WriteCustomModifiers(ModuleBuilder module, ByteBuffer bb, CustomModifiers modifiers)
Definition Signature.cs:419
static void WriteType(ModuleBuilder module, ByteBuffer bb, Type type)
Definition Signature.cs:339
static Type[] BindTypeParameters(IGenericBinder binder, Type[] types)
Definition Signature.cs:546
static Type ReadParam(ModuleReader module, ByteReader br, IGenericContext context)
Definition Signature.cs:327
static Type ReadRetType(ModuleReader module, ByteReader br, IGenericContext context)
Definition Signature.cs:312
Type GetGenericTypeArgument(int index)