~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ikvm/reflect/Emit/SignatureHelper.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

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