2
Copyright (C) 2008-2012 Jeroen Frijters
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.
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:
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.
25
using System.Collections.Generic;
26
using System.Runtime.InteropServices;
27
using IKVM.Reflection;
28
using IKVM.Reflection.Writer;
30
namespace IKVM.Reflection.Emit
32
public abstract class SignatureHelper
34
protected readonly byte type;
35
protected ushort paramCount;
37
sealed class Lazy : SignatureHelper
39
private readonly List<Type> args = new List<Type>();
41
internal Lazy(byte type)
46
internal override Type ReturnType
48
get { return args[0]; }
51
public override byte[] GetSignature()
53
throw new NotSupportedException();
56
internal override ByteBuffer GetSignature(ModuleBuilder module)
58
ByteBuffer bb = new ByteBuffer(16);
59
Signature.WriteSignatureHelper(module, bb, type, paramCount, args);
63
public override void AddSentinel()
65
args.Add(MarkerType.Sentinel);
68
public override void __AddArgument(Type argument, bool pinned, CustomModifiers customModifiers)
72
args.Add(MarkerType.Pinned);
74
foreach (CustomModifiers.Entry mod in customModifiers)
76
args.Add(mod.IsRequired ? MarkerType.ModReq : MarkerType.ModOpt);
84
sealed class Eager : SignatureHelper
86
private readonly ModuleBuilder module;
87
private readonly ByteBuffer bb = new ByteBuffer(16);
88
private readonly Type returnType;
90
internal Eager(ModuleBuilder module, byte type, Type returnType)
94
this.returnType = returnType;
96
if (type != Signature.FIELD)
98
// space for parameterCount
103
internal override Type ReturnType
105
get { return returnType; }
108
public override byte[] GetSignature()
110
return GetSignature(null).ToArray();
113
internal override ByteBuffer GetSignature(ModuleBuilder module)
115
if (type != Signature.FIELD)
118
bb.Insert(MetadataWriter.GetCompressedUIntLength(paramCount) - bb.GetCompressedUIntLength());
119
bb.WriteCompressedUInt(paramCount);
124
public override void AddSentinel()
126
bb.Write(Signature.SENTINEL);
129
public override void __AddArgument(Type argument, bool pinned, CustomModifiers customModifiers)
133
bb.Write(Signature.ELEMENT_TYPE_PINNED);
135
foreach (CustomModifiers.Entry mod in customModifiers)
137
bb.Write(mod.IsRequired ? Signature.ELEMENT_TYPE_CMOD_REQD : Signature.ELEMENT_TYPE_CMOD_OPT);
138
Signature.WriteTypeSpec(module, bb, mod.Type);
140
Signature.WriteTypeSpec(module, bb, argument ?? module.universe.System_Void);
145
private SignatureHelper(byte type)
150
internal bool HasThis
152
get { return (type & Signature.HASTHIS) != 0; }
155
internal abstract Type ReturnType
160
internal int ParameterCount
162
get { return paramCount; }
165
private static SignatureHelper Create(Module mod, byte type, Type returnType)
167
ModuleBuilder mb = mod as ModuleBuilder;
169
? (SignatureHelper)new Lazy(type)
170
: new Eager(mb, type, returnType);
173
public static SignatureHelper GetFieldSigHelper(Module mod)
175
return Create(mod, Signature.FIELD, null);
178
public static SignatureHelper GetLocalVarSigHelper()
180
return new Lazy(Signature.LOCAL_SIG);
183
public static SignatureHelper GetLocalVarSigHelper(Module mod)
185
return Create(mod, Signature.LOCAL_SIG, null);
188
public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] parameterTypes)
190
SignatureHelper sig = Create(mod, Signature.PROPERTY, returnType);
191
sig.AddArgument(returnType);
193
sig.AddArguments(parameterTypes, null, null);
197
public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
199
return GetPropertySigHelper(mod, CallingConventions.Standard, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
202
public static SignatureHelper GetPropertySigHelper(Module mod, CallingConventions callingConvention, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
204
byte type = Signature.PROPERTY;
205
if ((callingConvention & CallingConventions.HasThis) != 0)
207
type |= Signature.HASTHIS;
209
SignatureHelper sig = Create(mod, type, returnType);
210
sig.AddArgument(returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers);
212
sig.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
216
public static SignatureHelper GetMethodSigHelper(CallingConvention unmanagedCallingConvention, Type returnType)
218
return GetMethodSigHelper(null, unmanagedCallingConvention, returnType);
221
public static SignatureHelper GetMethodSigHelper(CallingConventions callingConvention, Type returnType)
223
return GetMethodSigHelper(null, callingConvention, returnType);
226
public static SignatureHelper GetMethodSigHelper(Module mod, CallingConvention unmanagedCallConv, Type returnType)
229
switch (unmanagedCallConv)
231
case CallingConvention.Cdecl:
234
case CallingConvention.StdCall:
235
case CallingConvention.Winapi:
236
type = 0x02; // STDCALL
238
case CallingConvention.ThisCall:
239
type = 0x03; // THISCALL
241
case CallingConvention.FastCall:
242
type = 0x04; // FASTCALL
245
throw new ArgumentOutOfRangeException("unmanagedCallConv");
247
SignatureHelper sig = Create(mod, type, returnType);
248
sig.AddArgument(returnType);
253
public static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType)
256
if ((callingConvention & CallingConventions.HasThis) != 0)
258
type |= Signature.HASTHIS;
260
if ((callingConvention & CallingConventions.ExplicitThis) != 0)
262
type |= Signature.EXPLICITTHIS;
264
if ((callingConvention & CallingConventions.VarArgs) != 0)
266
type |= Signature.VARARG;
268
SignatureHelper sig = Create(mod, type, returnType);
269
sig.AddArgument(returnType);
274
public static SignatureHelper GetMethodSigHelper(Module mod, Type returnType, Type[] parameterTypes)
276
SignatureHelper sig = Create(mod, 0, returnType);
277
sig.AddArgument(returnType);
279
sig.AddArguments(parameterTypes, null, null);
283
public abstract byte[] GetSignature();
285
internal abstract ByteBuffer GetSignature(ModuleBuilder module);
287
public abstract void AddSentinel();
289
public void AddArgument(Type clsArgument)
291
AddArgument(clsArgument, false);
294
public void AddArgument(Type argument, bool pinned)
296
__AddArgument(argument, pinned, new CustomModifiers());
299
public void AddArgument(Type argument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
301
__AddArgument(argument, false, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
304
public abstract void __AddArgument(Type argument, bool pinned, CustomModifiers customModifiers);
306
public void AddArguments(Type[] arguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
308
if (arguments != null)
310
for (int i = 0; i < arguments.Length; i++)
312
__AddArgument(arguments[i], false, CustomModifiers.FromReqOpt(Util.NullSafeElementAt(requiredCustomModifiers, i), Util.NullSafeElementAt(optionalCustomModifiers, i)));