2 Copyright (C) 2008-2011 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 sealed class SignatureHelper
34 private readonly ModuleBuilder module;
35 private readonly byte type;
36 private readonly List<Type> args = new List<Type>();
37 private readonly List<LocalBuilder> locals = new List<LocalBuilder>();
38 private readonly List<CustomModifiers> customModifiers = new List<CustomModifiers>();
39 private readonly List<Type> optionalArgs = new List<Type>();
40 private Type returnType;
41 private CustomModifiers returnTypeCustomModifiers;
42 private CallingConventions callingConvention;
43 private CallingConvention unmanagedCallConv;
44 private bool unmanaged;
45 private bool optional;
47 private SignatureHelper(ModuleBuilder module, byte type)
55 get { return (callingConvention & CallingConventions.HasThis) != 0; }
58 internal Type ReturnType
60 get { return returnType; }
63 internal int ParameterCount
65 get { return args.Count + optionalArgs.Count; }
68 public static SignatureHelper GetFieldSigHelper(Module mod)
70 return new SignatureHelper(mod as ModuleBuilder, Signature.FIELD);
73 public static SignatureHelper GetLocalVarSigHelper()
75 return new SignatureHelper(null, Signature.LOCAL_SIG);
78 public static SignatureHelper GetLocalVarSigHelper(Module mod)
80 return new SignatureHelper(mod as ModuleBuilder, Signature.LOCAL_SIG);
83 public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] parameterTypes)
85 SignatureHelper sig = new SignatureHelper(mod as ModuleBuilder, Signature.PROPERTY);
86 sig.returnType = returnType;
87 foreach (Type type in parameterTypes)
89 sig.AddArgument(type);
94 public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
96 return GetPropertySigHelper(mod, CallingConventions.Standard, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
99 public static SignatureHelper GetPropertySigHelper(Module mod, CallingConventions callingConvention, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
101 SignatureHelper sig = new SignatureHelper(mod as ModuleBuilder, Signature.PROPERTY);
102 sig.callingConvention = callingConvention;
103 sig.returnType = returnType;
104 sig.returnTypeCustomModifiers = CustomModifiers.FromReqOpt(requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers);
105 sig.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
109 public static SignatureHelper GetMethodSigHelper(CallingConvention unmanagedCallingConvention, Type returnType)
111 return GetMethodSigHelper(null, unmanagedCallingConvention, returnType);
114 public static SignatureHelper GetMethodSigHelper(CallingConventions callingConvention, Type returnType)
116 return GetMethodSigHelper(null, callingConvention, returnType);
119 public static SignatureHelper GetMethodSigHelper(Module mod, CallingConvention unmanagedCallConv, Type returnType)
121 SignatureHelper sig = new SignatureHelper(mod as ModuleBuilder, 0);
122 sig.returnType = returnType;
123 sig.unmanaged = true;
124 sig.unmanagedCallConv = unmanagedCallConv;
128 public static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType)
130 SignatureHelper sig = new SignatureHelper(mod as ModuleBuilder, 0);
131 sig.returnType = returnType;
132 sig.callingConvention = callingConvention;
136 public static SignatureHelper GetMethodSigHelper(Module mod, Type returnType, Type[] parameterTypes)
138 SignatureHelper sig = new SignatureHelper(mod as ModuleBuilder, 0);
139 sig.returnType = returnType;
140 sig.callingConvention = CallingConventions.Standard;
141 foreach (Type type in parameterTypes)
143 sig.AddArgument(type);
148 public byte[] GetSignature()
152 throw new NotSupportedException();
154 return GetSignature(module).ToArray();
157 internal ByteBuffer GetSignature(ModuleBuilder module)
159 ByteBuffer bb = new ByteBuffer(16);
165 Signature.WriteStandAloneMethodSig(module, bb, module.universe.MakeStandAloneMethodSig(unmanagedCallConv, returnType, returnTypeCustomModifiers, args.ToArray(), customModifiers.ToArray()));
169 Signature.WriteStandAloneMethodSig(module, bb, module.universe.MakeStandAloneMethodSig(callingConvention, returnType, returnTypeCustomModifiers, args.ToArray(), optionalArgs.ToArray(), customModifiers.ToArray()));
172 case Signature.FIELD:
173 FieldSignature.Create(args[0], customModifiers[0]).WriteSig(module, bb);
175 case Signature.PROPERTY:
176 Signature.WritePropertySig(module, bb, callingConvention, returnType, returnTypeCustomModifiers, args.ToArray(), customModifiers.ToArray());
178 case Signature.LOCAL_SIG:
179 Signature.WriteLocalVarSig(module, bb, locals, customModifiers);
182 throw new InvalidOperationException();
187 public void AddSentinel()
190 callingConvention |= CallingConventions.VarArgs;
193 public void AddArgument(Type clsArgument)
195 AddArgument(clsArgument, false);
198 public void AddArgument(Type argument, bool pinned)
200 __AddArgument(argument, pinned, new CustomModifiers());
203 public void AddArgument(Type argument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
205 __AddArgument(argument, false, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
208 public void __AddArgument(Type argument, bool pinned, CustomModifiers customModifiers)
210 if (type == Signature.LOCAL_SIG)
212 locals.Add(new LocalBuilder(argument, 0, pinned));
216 this.optionalArgs.Add(argument);
220 this.args.Add(argument);
222 this.customModifiers.Add(customModifiers);
225 public void AddArguments(Type[] arguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
227 for (int i = 0; i < arguments.Length; i++)
229 __AddArgument(arguments[i], false, CustomModifiers.FromReqOpt(requiredCustomModifiers[i], optionalCustomModifiers[i]));