IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
SignatureHelper.cs
Go to the documentation of this file.
1/*
2 Copyright (C) 2008-2012 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.Runtime.InteropServices;
27
29
31{
32
33 internal abstract class SignatureHelper
34 {
35
36 protected readonly byte type;
37 protected ushort argumentCount;
38
39 sealed class Lazy : SignatureHelper
40 {
41
42 readonly List<Type> args = new List<Type>();
43
48 internal Lazy(byte type) :
49 base(type)
50 {
51
52 }
53
54 internal override Type ReturnType
55 {
56 get { return args[0]; }
57 }
58
59 public override byte[] GetSignature()
60 {
61 throw new NotSupportedException();
62 }
63
64 internal override ByteBuffer GetSignature(ModuleBuilder module)
65 {
66 var bb = new ByteBuffer(16);
67 Signature.WriteSignatureHelper(module, bb, type, argumentCount, args);
68 return bb;
69 }
70
71 public override void AddSentinel()
72 {
73 args.Add(MarkerType.Sentinel);
74 }
75
76 public override void __AddArgument(Type argument, bool pinned, CustomModifiers customModifiers)
77 {
78 if (pinned)
79 args.Add(MarkerType.Pinned);
80
81 foreach (var mod in customModifiers)
82 {
83 args.Add(mod.IsRequired ? MarkerType.ModReq : MarkerType.ModOpt);
84 args.Add(mod.Type);
85 }
86
87 args.Add(argument);
88 argumentCount++;
89 }
90
91 }
92
93 sealed class Eager : SignatureHelper
94 {
95
96 readonly ModuleBuilder module;
97 readonly ByteBuffer bb = new ByteBuffer(16);
98 readonly Type returnType;
99
106 internal Eager(ModuleBuilder module, byte type, Type returnType) :
107 base(type)
108 {
109 this.module = module;
110 this.returnType = returnType;
111
112 bb.Write(type);
113 if (type != Signature.FIELD)
114 bb.Write((byte)0); // space for parameterCount
115 }
116
117 internal override Type ReturnType
118 {
119 get { return returnType; }
120 }
121
122 public override byte[] GetSignature()
123 {
124 return GetSignature(null).ToArray();
125 }
126
127 internal override ByteBuffer GetSignature(ModuleBuilder module)
128 {
129 if (type != Signature.FIELD)
130 {
131 bb.Position = 1;
132 bb.Insert(MetadataWriter.GetCompressedUIntLength(argumentCount) - bb.GetCompressedUIntLength());
133 bb.WriteCompressedUInt(argumentCount);
134 }
135
136 return bb;
137 }
138
139 public override void AddSentinel()
140 {
141 bb.Write(Signature.SENTINEL);
142 }
143
144 public override void __AddArgument(Type argument, bool pinned, CustomModifiers customModifiers)
145 {
146 if (pinned)
147 bb.Write(Signature.ELEMENT_TYPE_PINNED);
148
149 foreach (var mod in customModifiers)
150 {
151 bb.Write(mod.IsRequired ? Signature.ELEMENT_TYPE_CMOD_REQD : Signature.ELEMENT_TYPE_CMOD_OPT);
152 Signature.WriteTypeSpec(module, bb, mod.Type);
153 }
154
155 Signature.WriteTypeSpec(module, bb, argument ?? module.Universe.System_Void);
156 argumentCount++;
157 }
158 }
159
164 SignatureHelper(byte type)
165 {
166 this.type = type;
167 }
168
169 internal bool HasThis
170 {
171 get { return (type & Signature.HASTHIS) != 0; }
172 }
173
174 internal abstract Type ReturnType
175 {
176 get;
177 }
178
179 internal int ArgumentCount
180 {
181 get { return argumentCount; }
182 }
183
184 private static SignatureHelper Create(Module mod, byte type, Type returnType)
185 {
186 return mod is not ModuleBuilder mb ? new Lazy(type) : new Eager(mb, type, returnType);
187 }
188
189 public static SignatureHelper GetFieldSigHelper(Module mod)
190 {
191 return Create(mod, Signature.FIELD, null);
192 }
193
194 public static SignatureHelper GetLocalVarSigHelper()
195 {
196 return new Lazy(Signature.LOCAL_SIG);
197 }
198
199 public static SignatureHelper GetLocalVarSigHelper(Module mod)
200 {
201 return Create(mod, Signature.LOCAL_SIG, null);
202 }
203
204 public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] parameterTypes)
205 {
206 var sig = Create(mod, Signature.PROPERTY, returnType);
207 sig.AddArgument(returnType);
208 sig.argumentCount = 0;
209 sig.AddArguments(parameterTypes, null, null);
210 return sig;
211 }
212
213 public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
214 {
215 return GetPropertySigHelper(mod, CallingConventions.Standard, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
216 }
217
218 public static SignatureHelper GetPropertySigHelper(Module mod, CallingConventions callingConvention, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
219 {
220 var type = Signature.PROPERTY;
221 if ((callingConvention & CallingConventions.HasThis) != 0)
222 type |= Signature.HASTHIS;
223
224 var sig = Create(mod, type, returnType);
225 sig.AddArgument(returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers);
226 sig.argumentCount = 0;
227 sig.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
228 return sig;
229 }
230
231 public static SignatureHelper GetMethodSigHelper(CallingConvention unmanagedCallingConvention, Type returnType)
232 {
233 return GetMethodSigHelper(null, unmanagedCallingConvention, returnType);
234 }
235
236 public static SignatureHelper GetMethodSigHelper(CallingConventions callingConvention, Type returnType)
237 {
238 return GetMethodSigHelper(null, callingConvention, returnType);
239 }
240
241 public static SignatureHelper GetMethodSigHelper(Module mod, CallingConvention unmanagedCallConv, Type returnType)
242 {
243 var type = unmanagedCallConv switch
244 {
245 CallingConvention.Cdecl => (byte)0x01,// C
246 CallingConvention.StdCall or CallingConvention.Winapi => (byte)0x02,// STDCALL
247 CallingConvention.ThisCall => (byte)0x03,// THISCALL
248 CallingConvention.FastCall => (byte)0x04,// FASTCALL
249 _ => throw new ArgumentOutOfRangeException("unmanagedCallConv"),
250 };
251
252 var sig = Create(mod, type, returnType);
253 sig.AddArgument(returnType);
254 sig.argumentCount = 0;
255 return sig;
256 }
257
258 public static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType)
259 {
260 byte type = 0;
261
262 if ((callingConvention & CallingConventions.HasThis) != 0)
263 type |= Signature.HASTHIS;
264
265 if ((callingConvention & CallingConventions.ExplicitThis) != 0)
266 type |= Signature.EXPLICITTHIS;
267
268 if ((callingConvention & CallingConventions.VarArgs) != 0)
269 type |= Signature.VARARG;
270
271 var sig = Create(mod, type, returnType);
272 sig.AddArgument(returnType);
273 sig.argumentCount = 0;
274 return sig;
275 }
276
277 public static SignatureHelper GetMethodSigHelper(Module mod, Type returnType, Type[] parameterTypes)
278 {
279 var sig = Create(mod, 0, returnType);
280 sig.AddArgument(returnType);
281 sig.argumentCount = 0;
282 sig.AddArguments(parameterTypes, null, null);
283 return sig;
284 }
285
286 public abstract byte[] GetSignature();
287
288 internal abstract ByteBuffer GetSignature(ModuleBuilder module);
289
290 public abstract void AddSentinel();
291
292 public void AddArgument(Type clsArgument)
293 {
294 AddArgument(clsArgument, false);
295 }
296
297 public void AddArgument(Type argument, bool pinned)
298 {
299 __AddArgument(argument, pinned, new CustomModifiers());
300 }
301
302 public void AddArgument(Type argument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
303 {
304 __AddArgument(argument, false, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers));
305 }
306
307 public abstract void __AddArgument(Type argument, bool pinned, CustomModifiers customModifiers);
308
309 public void AddArguments(Type[] arguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
310 {
311 if (arguments != null)
312 for (int i = 0; i < arguments.Length; i++)
313 __AddArgument(arguments[i], false, CustomModifiers.FromReqOpt(Util.NullSafeElementAt(requiredCustomModifiers, i), Util.NullSafeElementAt(optionalCustomModifiers, i)));
314 }
315
316 }
317
318}
IKVM.Reflection.Module Module
IKVM.Reflection.Type Type
System.Runtime.InteropServices.CallingConvention CallingConvention
Definition Signature.cs:35