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

« back to all changes in this revision

Viewing changes to external/ikvm/reflect/Emit/MethodBuilder.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.IO;
 
26
using System.Diagnostics;
 
27
using System.Collections.Generic;
 
28
using System.Runtime.InteropServices;
 
29
using System.Runtime.CompilerServices;
 
30
using System.Diagnostics.SymbolStore;
 
31
using IKVM.Reflection.Metadata;
 
32
using IKVM.Reflection.Writer;
 
33
 
 
34
namespace IKVM.Reflection.Emit
 
35
{
 
36
        public sealed class MethodBuilder : MethodInfo
 
37
        {
 
38
                private readonly TypeBuilder typeBuilder;
 
39
                private readonly string name;
 
40
                private readonly int pseudoToken;
 
41
                private int nameIndex;
 
42
                private int signature;
 
43
                private Type returnType;
 
44
                private Type[] parameterTypes;
 
45
                private PackedCustomModifiers customModifiers;
 
46
                private MethodAttributes attributes;
 
47
                private MethodImplAttributes implFlags;
 
48
                private ILGenerator ilgen;
 
49
                private int rva = -1;
 
50
                private CallingConventions callingConvention;
 
51
                private List<ParameterBuilder> parameters;
 
52
                private GenericTypeParameterBuilder[] gtpb;
 
53
                private List<CustomAttributeBuilder> declarativeSecurity;
 
54
                private MethodSignature methodSignature;
 
55
                private bool initLocals = true;
 
56
 
 
57
                internal MethodBuilder(TypeBuilder typeBuilder, string name, MethodAttributes attributes, CallingConventions callingConvention)
 
58
                {
 
59
                        this.typeBuilder = typeBuilder;
 
60
                        this.name = name;
 
61
                        this.pseudoToken = typeBuilder.ModuleBuilder.AllocPseudoToken();
 
62
                        this.attributes = attributes;
 
63
                        if ((attributes & MethodAttributes.Static) == 0)
 
64
                        {
 
65
                                callingConvention |= CallingConventions.HasThis;
 
66
                        }
 
67
                        this.callingConvention = callingConvention;
 
68
                }
 
69
 
 
70
                public ILGenerator GetILGenerator()
 
71
                {
 
72
                        return GetILGenerator(16);
 
73
                }
 
74
 
 
75
                public ILGenerator GetILGenerator(int streamSize)
 
76
                {
 
77
                        if (rva != -1)
 
78
                        {
 
79
                                throw new InvalidOperationException();
 
80
                        }
 
81
                        if (ilgen == null)
 
82
                        {
 
83
                                ilgen = new ILGenerator(typeBuilder.ModuleBuilder, streamSize);
 
84
                        }
 
85
                        return ilgen;
 
86
                }
 
87
 
 
88
                public void __ReleaseILGenerator()
 
89
                {
 
90
                        if (ilgen != null)
 
91
                        {
 
92
                                if (this.ModuleBuilder.symbolWriter != null)
 
93
                                {
 
94
                                        this.ModuleBuilder.symbolWriter.OpenMethod(new SymbolToken(-pseudoToken | 0x06000000), this);
 
95
                                }
 
96
                                rva = ilgen.WriteBody(initLocals);
 
97
                                if (this.ModuleBuilder.symbolWriter != null)
 
98
                                {
 
99
                                        this.ModuleBuilder.symbolWriter.CloseMethod();
 
100
                                }
 
101
                                ilgen = null;
 
102
                        }
 
103
                }
 
104
 
 
105
                public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
 
106
                {
 
107
                        SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
 
108
                }
 
109
 
 
110
                private void SetDllImportPseudoCustomAttribute(CustomAttributeBuilder customBuilder)
 
111
                {
 
112
                        CallingConvention? callingConvention = customBuilder.GetFieldValue<CallingConvention>("CallingConvention");
 
113
                        CharSet? charSet = customBuilder.GetFieldValue<CharSet>("CharSet");
 
114
                        SetDllImportPseudoCustomAttribute((string)customBuilder.GetConstructorArgument(0),
 
115
                                (string)customBuilder.GetFieldValue("EntryPoint"),
 
116
                                callingConvention,
 
117
                                charSet,
 
118
                                (bool?)customBuilder.GetFieldValue("BestFitMapping"),
 
119
                                (bool?)customBuilder.GetFieldValue("ThrowOnUnmappableChar"),
 
120
                                (bool?)customBuilder.GetFieldValue("SetLastError"),
 
121
                                (bool?)customBuilder.GetFieldValue("PreserveSig"),
 
122
                                (bool?)customBuilder.GetFieldValue("ExactSpelling"));
 
123
                }
 
124
 
 
125
                internal void SetDllImportPseudoCustomAttribute(string dllName, string entryName, CallingConvention? nativeCallConv, CharSet? nativeCharSet,
 
126
                        bool? bestFitMapping, bool? throwOnUnmappableChar, bool? setLastError, bool? preserveSig, bool? exactSpelling)
 
127
                {
 
128
                        const short NoMangle = 0x0001;
 
129
                        const short CharSetMask = 0x0006;
 
130
                        const short CharSetNotSpec = 0x0000;
 
131
                        const short CharSetAnsi = 0x0002;
 
132
                        const short CharSetUnicode = 0x0004;
 
133
                        const short CharSetAuto = 0x0006;
 
134
                        const short SupportsLastError = 0x0040;
 
135
                        const short CallConvMask = 0x0700;
 
136
                        const short CallConvWinapi = 0x0100;
 
137
                        const short CallConvCdecl = 0x0200;
 
138
                        const short CallConvStdcall = 0x0300;
 
139
                        const short CallConvThiscall = 0x0400;
 
140
                        const short CallConvFastcall = 0x0500;
 
141
                        // non-standard flags
 
142
                        const short BestFitOn = 0x0010;
 
143
                        const short BestFitOff = 0x0020;
 
144
                        const short CharMapErrorOn = 0x1000;
 
145
                        const short CharMapErrorOff = 0x2000;
 
146
                        short flags = CharSetNotSpec | CallConvWinapi;
 
147
                        if (bestFitMapping.HasValue)
 
148
                        {
 
149
                                flags |= bestFitMapping.Value ? BestFitOn : BestFitOff;
 
150
                        }
 
151
                        if (throwOnUnmappableChar.HasValue)
 
152
                        {
 
153
                                flags |= throwOnUnmappableChar.Value ? CharMapErrorOn : CharMapErrorOff;
 
154
                        }
 
155
                        if (nativeCallConv.HasValue)
 
156
                        {
 
157
                                flags &= ~CallConvMask;
 
158
                                switch (nativeCallConv.Value)
 
159
                                {
 
160
                                        case System.Runtime.InteropServices.CallingConvention.Cdecl:
 
161
                                                flags |= CallConvCdecl;
 
162
                                                break;
 
163
                                        case System.Runtime.InteropServices.CallingConvention.FastCall:
 
164
                                                flags |= CallConvFastcall;
 
165
                                                break;
 
166
                                        case System.Runtime.InteropServices.CallingConvention.StdCall:
 
167
                                                flags |= CallConvStdcall;
 
168
                                                break;
 
169
                                        case System.Runtime.InteropServices.CallingConvention.ThisCall:
 
170
                                                flags |= CallConvThiscall;
 
171
                                                break;
 
172
                                        case System.Runtime.InteropServices.CallingConvention.Winapi:
 
173
                                                flags |= CallConvWinapi;
 
174
                                                break;
 
175
                                }
 
176
                        }
 
177
                        if (nativeCharSet.HasValue)
 
178
                        {
 
179
                                flags &= ~CharSetMask;
 
180
                                switch (nativeCharSet.Value)
 
181
                                {
 
182
                                        case CharSet.Ansi:
 
183
                                        case CharSet.None:
 
184
                                                flags |= CharSetAnsi;
 
185
                                                break;
 
186
                                        case CharSet.Auto:
 
187
                                                flags |= CharSetAuto;
 
188
                                                break;
 
189
                                        case CharSet.Unicode:
 
190
                                                flags |= CharSetUnicode;
 
191
                                                break;
 
192
                                }
 
193
                        }
 
194
                        if (exactSpelling.HasValue && exactSpelling.Value)
 
195
                        {
 
196
                                flags |= NoMangle;
 
197
                        }
 
198
                        if (!preserveSig.HasValue || preserveSig.Value)
 
199
                        {
 
200
                                implFlags |= MethodImplAttributes.PreserveSig;
 
201
                        }
 
202
                        if (setLastError.HasValue && setLastError.Value)
 
203
                        {
 
204
                                flags |= SupportsLastError;
 
205
                        }
 
206
                        ImplMapTable.Record rec = new ImplMapTable.Record();
 
207
                        rec.MappingFlags = flags;
 
208
                        rec.MemberForwarded = pseudoToken;
 
209
                        rec.ImportName = this.ModuleBuilder.Strings.Add(entryName ?? name);
 
210
                        rec.ImportScope = this.ModuleBuilder.ModuleRef.FindOrAddRecord(dllName == null ? 0 : this.ModuleBuilder.Strings.Add(dllName));
 
211
                        this.ModuleBuilder.ImplMap.AddRecord(rec);
 
212
                }
 
213
 
 
214
                private void SetMethodImplAttribute(CustomAttributeBuilder customBuilder)
 
215
                {
 
216
                        MethodImplOptions opt;
 
217
                        switch (customBuilder.Constructor.ParameterCount)
 
218
                        {
 
219
                                case 0:
 
220
                                        opt = 0;
 
221
                                        break;
 
222
                                case 1:
 
223
                                        {
 
224
                                                object val = customBuilder.GetConstructorArgument(0);
 
225
                                                if (val is short)
 
226
                                                {
 
227
                                                        opt = (MethodImplOptions)(short)val;
 
228
                                                }
 
229
                                                else if (val is int)
 
230
                                                {
 
231
                                                        opt = (MethodImplOptions)(int)val;
 
232
                                                }
 
233
                                                else
 
234
                                                {
 
235
                                                        opt = (MethodImplOptions)val;
 
236
                                                }
 
237
                                                break;
 
238
                                        }
 
239
                                default:
 
240
                                        throw new NotSupportedException();
 
241
                        }
 
242
                        MethodCodeType? type = customBuilder.GetFieldValue<MethodCodeType>("MethodCodeType");
 
243
                        implFlags = (MethodImplAttributes)opt;
 
244
                        if (type.HasValue)
 
245
                        {
 
246
                                implFlags |= (MethodImplAttributes)type;
 
247
                        }
 
248
                }
 
249
 
 
250
                public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
 
251
                {
 
252
                        Universe u = this.ModuleBuilder.universe;
 
253
                        Type type = customBuilder.Constructor.DeclaringType;
 
254
                        if (type == u.System_Runtime_InteropServices_DllImportAttribute)
 
255
                        {
 
256
                                attributes |= MethodAttributes.PinvokeImpl;
 
257
                                SetDllImportPseudoCustomAttribute(customBuilder.DecodeBlob(this.Module.Assembly));
 
258
                        }
 
259
                        else if (type == u.System_Runtime_CompilerServices_MethodImplAttribute)
 
260
                        {
 
261
                                SetMethodImplAttribute(customBuilder.DecodeBlob(this.Module.Assembly));
 
262
                        }
 
263
                        else if (type == u.System_Runtime_InteropServices_PreserveSigAttribute)
 
264
                        {
 
265
                                implFlags |= MethodImplAttributes.PreserveSig;
 
266
                        }
 
267
                        else if (type == u.System_Runtime_CompilerServices_SpecialNameAttribute)
 
268
                        {
 
269
                                attributes |= MethodAttributes.SpecialName;
 
270
                        }
 
271
                        else
 
272
                        {
 
273
                                if (type == u.System_Security_SuppressUnmanagedCodeSecurityAttribute)
 
274
                                {
 
275
                                        attributes |= MethodAttributes.HasSecurity;
 
276
                                }
 
277
                                this.ModuleBuilder.SetCustomAttribute(pseudoToken, customBuilder);
 
278
                        }
 
279
                }
 
280
 
 
281
                public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
 
282
                {
 
283
                        attributes |= MethodAttributes.HasSecurity;
 
284
                        if (declarativeSecurity == null)
 
285
                        {
 
286
                                declarativeSecurity = new List<CustomAttributeBuilder>();
 
287
                        }
 
288
                        declarativeSecurity.Add(customBuilder);
 
289
                }
 
290
 
 
291
                public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet)
 
292
                {
 
293
                        this.ModuleBuilder.AddDeclarativeSecurity(pseudoToken, securityAction, permissionSet);
 
294
                        this.attributes |= MethodAttributes.HasSecurity;
 
295
                }
 
296
 
 
297
                public void SetImplementationFlags(MethodImplAttributes attributes)
 
298
                {
 
299
                        implFlags = attributes;
 
300
                }
 
301
 
 
302
                public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, string strParamName)
 
303
                {
 
304
                        if (parameters == null)
 
305
                        {
 
306
                                parameters = new List<ParameterBuilder>();
 
307
                        }
 
308
                        this.ModuleBuilder.Param.AddVirtualRecord();
 
309
                        ParameterBuilder pb = new ParameterBuilder(this.ModuleBuilder, position, attributes, strParamName);
 
310
                        if (parameters.Count == 0 || position > parameters[parameters.Count - 1].Position)
 
311
                        {
 
312
                                parameters.Add(pb);
 
313
                        }
 
314
                        else
 
315
                        {
 
316
                                for (int i = 0; i < parameters.Count; i++)
 
317
                                {
 
318
                                        if (parameters[i].Position > position)
 
319
                                        {
 
320
                                                parameters.Insert(i, pb);
 
321
                                                break;
 
322
                                        }
 
323
                                }
 
324
                        }
 
325
                        return pb;
 
326
                }
 
327
 
 
328
                private void CheckSig()
 
329
                {
 
330
                        if (methodSignature != null)
 
331
                        {
 
332
                                throw new InvalidOperationException("The method signature can not be modified after it has been used.");
 
333
                        }
 
334
                }
 
335
 
 
336
                public void SetParameters(params Type[] parameterTypes)
 
337
                {
 
338
                        CheckSig();
 
339
                        this.parameterTypes = Util.Copy(parameterTypes);
 
340
                }
 
341
 
 
342
                public void SetReturnType(Type returnType)
 
343
                {
 
344
                        CheckSig();
 
345
                        this.returnType = returnType ?? this.Module.universe.System_Void;
 
346
                }
 
347
 
 
348
                public void SetSignature(Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
 
349
                {
 
350
                        SetSignature(returnType, parameterTypes, PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers,
 
351
                                parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, Util.NullSafeLength(parameterTypes)));
 
352
                }
 
353
 
 
354
                public void __SetSignature(Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
 
355
                {
 
356
                        SetSignature(returnType, parameterTypes, PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes)));
 
357
                }
 
358
 
 
359
                private void SetSignature(Type returnType, Type[] parameterTypes, PackedCustomModifiers customModifiers)
 
360
                {
 
361
                        CheckSig();
 
362
                        this.returnType = returnType ?? this.Module.universe.System_Void;
 
363
                        this.parameterTypes = Util.Copy(parameterTypes);
 
364
                        this.customModifiers = customModifiers;
 
365
                }
 
366
 
 
367
                public GenericTypeParameterBuilder[] DefineGenericParameters(params string[] names)
 
368
                {
 
369
                        CheckSig();
 
370
                        if (gtpb != null)
 
371
                        {
 
372
                                throw new InvalidOperationException("Generic parameters already defined.");
 
373
                        }
 
374
                        gtpb = new GenericTypeParameterBuilder[names.Length];
 
375
                        for (int i = 0; i < names.Length; i++)
 
376
                        {
 
377
                                gtpb[i] = new GenericTypeParameterBuilder(names[i], null, this, i);
 
378
                        }
 
379
                        return (GenericTypeParameterBuilder[])gtpb.Clone();
 
380
                }
 
381
 
 
382
                public override MethodInfo MakeGenericMethod(params Type[] typeArguments)
 
383
                {
 
384
                        return new GenericMethodInstance(typeBuilder, this, typeArguments);
 
385
                }
 
386
 
 
387
                public override MethodInfo GetGenericMethodDefinition()
 
388
                {
 
389
                        if (gtpb == null)
 
390
                        {
 
391
                                throw new InvalidOperationException();
 
392
                        }
 
393
                        return this;
 
394
                }
 
395
 
 
396
                public override Type[] GetGenericArguments()
 
397
                {
 
398
                        return Util.Copy(gtpb);
 
399
                }
 
400
 
 
401
                internal override Type GetGenericMethodArgument(int index)
 
402
                {
 
403
                        return gtpb[index];
 
404
                }
 
405
 
 
406
                internal override int GetGenericMethodArgumentCount()
 
407
                {
 
408
                        return gtpb == null ? 0 : gtpb.Length;
 
409
                }
 
410
 
 
411
                public override Type ReturnType
 
412
                {
 
413
                        get { return returnType; }
 
414
                }
 
415
 
 
416
                public override ParameterInfo ReturnParameter
 
417
                {
 
418
                        get { return new ParameterInfoImpl(this, -1); }
 
419
                }
 
420
 
 
421
                public override MethodAttributes Attributes
 
422
                {
 
423
                        get { return attributes; }
 
424
                }
 
425
 
 
426
                public void __SetAttributes(MethodAttributes attributes)
 
427
                {
 
428
                        this.attributes = attributes;
 
429
                }
 
430
 
 
431
                public void __SetCallingConvention(CallingConventions callingConvention)
 
432
                {
 
433
                        this.callingConvention = callingConvention;
 
434
                        this.methodSignature = null;
 
435
                }
 
436
 
 
437
                public override MethodImplAttributes GetMethodImplementationFlags()
 
438
                {
 
439
                        return implFlags;
 
440
                }
 
441
 
 
442
                private sealed class ParameterInfoImpl : ParameterInfo
 
443
                {
 
444
                        private readonly MethodBuilder method;
 
445
                        private readonly int parameter;
 
446
 
 
447
                        internal ParameterInfoImpl(MethodBuilder method, int parameter)
 
448
                        {
 
449
                                this.method = method;
 
450
                                this.parameter = parameter;
 
451
                        }
 
452
 
 
453
                        private ParameterBuilder ParameterBuilder
 
454
                        {
 
455
                                get
 
456
                                {
 
457
                                        if (method.parameters != null)
 
458
                                        {
 
459
                                                foreach (ParameterBuilder pb in method.parameters)
 
460
                                                {
 
461
                                                        // ParameterBuilder.Position is 1-based
 
462
                                                        if (pb.Position - 1 == parameter)
 
463
                                                        {
 
464
                                                                return pb;
 
465
                                                        }
 
466
                                                }
 
467
                                        }
 
468
                                        return null;
 
469
                                }
 
470
                        }
 
471
 
 
472
                        public override string Name
 
473
                        {
 
474
                                get
 
475
                                {
 
476
                                        ParameterBuilder pb = this.ParameterBuilder;
 
477
                                        return pb != null ? pb.Name : null;
 
478
                                }
 
479
                        }
 
480
 
 
481
                        public override Type ParameterType
 
482
                        {
 
483
                                get { return parameter == -1 ? method.returnType : method.parameterTypes[parameter]; }
 
484
                        }
 
485
 
 
486
                        public override ParameterAttributes Attributes
 
487
                        {
 
488
                                get
 
489
                                {
 
490
                                        ParameterBuilder pb = this.ParameterBuilder;
 
491
                                        return pb != null ? (ParameterAttributes)pb.Attributes : ParameterAttributes.None;
 
492
                                }
 
493
                        }
 
494
 
 
495
                        public override int Position
 
496
                        {
 
497
                                get { return parameter; }
 
498
                        }
 
499
 
 
500
                        public override object RawDefaultValue
 
501
                        {
 
502
                                get
 
503
                                {
 
504
                                        ParameterBuilder pb = this.ParameterBuilder;
 
505
                                        if (pb != null && (pb.Attributes & (int)ParameterAttributes.HasDefault) != 0)
 
506
                                        {
 
507
                                                return method.ModuleBuilder.Constant.GetRawConstantValue(method.ModuleBuilder, pb.PseudoToken);
 
508
                                        }
 
509
                                        if (pb != null && (pb.Attributes & (int)ParameterAttributes.Optional) != 0)
 
510
                                        {
 
511
                                                return Missing.Value;
 
512
                                        }
 
513
                                        return null;
 
514
                                }
 
515
                        }
 
516
 
 
517
                        public override CustomModifiers __GetCustomModifiers()
 
518
                        {
 
519
                                return method.customModifiers.GetParameterCustomModifiers(parameter);
 
520
                        }
 
521
 
 
522
                        public override bool __TryGetFieldMarshal(out FieldMarshal fieldMarshal)
 
523
                        {
 
524
                                fieldMarshal = new FieldMarshal();
 
525
                                return false;
 
526
                        }
 
527
 
 
528
                        public override MemberInfo Member
 
529
                        {
 
530
                                get { return method; }
 
531
                        }
 
532
 
 
533
                        public override int MetadataToken
 
534
                        {
 
535
                                get
 
536
                                {
 
537
                                        ParameterBuilder pb = this.ParameterBuilder;
 
538
                                        return pb != null ? pb.PseudoToken : 0x08000000;
 
539
                                }
 
540
                        }
 
541
 
 
542
                        internal override Module Module
 
543
                        {
 
544
                                get { return method.Module; }
 
545
                        }
 
546
                }
 
547
 
 
548
                public override ParameterInfo[] GetParameters()
 
549
                {
 
550
                        ParameterInfo[] parameters = new ParameterInfo[parameterTypes.Length];
 
551
                        for (int i = 0; i < parameters.Length; i++)
 
552
                        {
 
553
                                parameters[i] = new ParameterInfoImpl(this, i);
 
554
                        }
 
555
                        return parameters;
 
556
                }
 
557
 
 
558
                internal override int ParameterCount
 
559
                {
 
560
                        get { return parameterTypes.Length; }
 
561
                }
 
562
 
 
563
                public override Type DeclaringType
 
564
                {
 
565
                        get { return typeBuilder.IsModulePseudoType ? null : typeBuilder; }
 
566
                }
 
567
 
 
568
                public override string Name
 
569
                {
 
570
                        get { return name; }
 
571
                }
 
572
 
 
573
                public override CallingConventions CallingConvention
 
574
                {
 
575
                        get { return callingConvention; }
 
576
                }
 
577
 
 
578
                public override int MetadataToken
 
579
                {
 
580
                        get { return pseudoToken; }
 
581
                }
 
582
 
 
583
                public override bool IsGenericMethod
 
584
                {
 
585
                        get { return gtpb != null; }
 
586
                }
 
587
 
 
588
                public override bool IsGenericMethodDefinition
 
589
                {
 
590
                        get { return gtpb != null; }
 
591
                }
 
592
 
 
593
                public override Module Module
 
594
                {
 
595
                        get { return typeBuilder.Module; }
 
596
                }
 
597
 
 
598
                public Module GetModule()
 
599
                {
 
600
                        return typeBuilder.Module;
 
601
                }
 
602
 
 
603
                public MethodToken GetToken()
 
604
                {
 
605
                        return new MethodToken(pseudoToken);
 
606
                }
 
607
 
 
608
                public override MethodBody GetMethodBody()
 
609
                {
 
610
                        throw new NotSupportedException();
 
611
                }
 
612
 
 
613
                public override int __MethodRVA
 
614
                {
 
615
                        get { throw new NotImplementedException(); }
 
616
                }
 
617
 
 
618
                public bool InitLocals
 
619
                {
 
620
                        get { return initLocals; }
 
621
                        set { initLocals = value; }
 
622
                }
 
623
 
 
624
                public void __AddUnmanagedExport(string name, int ordinal)
 
625
                {
 
626
                        this.ModuleBuilder.AddUnmanagedExport(name, ordinal, this, new RelativeVirtualAddress(0xFFFFFFFF));
 
627
                }
 
628
 
 
629
                public void CreateMethodBody(byte[] il, int count)
 
630
                {
 
631
                        if (il == null)
 
632
                        {
 
633
                                throw new NotSupportedException();
 
634
                        }
 
635
                        if (il.Length != count)
 
636
                        {
 
637
                                Array.Resize(ref il, count);
 
638
                        }
 
639
                        SetMethodBody(il, 16, null, null, null);
 
640
                }
 
641
 
 
642
                public void SetMethodBody(byte[] il, int maxStack, byte[] localSignature, IEnumerable<ExceptionHandler> exceptionHandlers, IEnumerable<int> tokenFixups)
 
643
                {
 
644
                        ByteBuffer bb = this.ModuleBuilder.methodBodies;
 
645
 
 
646
                        if (localSignature == null && exceptionHandlers == null && maxStack <= 8 && il.Length < 64)
 
647
                        {
 
648
                                rva = bb.Position;
 
649
                                ILGenerator.WriteTinyHeader(bb, il.Length);
 
650
                        }
 
651
                        else
 
652
                        {
 
653
                                // fat headers require 4-byte alignment
 
654
                                bb.Align(4);
 
655
                                rva = bb.Position;
 
656
                                ILGenerator.WriteFatHeader(bb, initLocals, exceptionHandlers != null, (ushort)maxStack, il.Length,
 
657
                                        localSignature == null ? 0 : this.ModuleBuilder.GetSignatureToken(localSignature, localSignature.Length).Token);
 
658
                        }
 
659
 
 
660
                        if (tokenFixups != null)
 
661
                        {
 
662
                                ILGenerator.AddTokenFixups(bb.Position, this.ModuleBuilder.tokenFixupOffsets, tokenFixups);
 
663
                        }
 
664
                        bb.Write(il);
 
665
 
 
666
                        if (exceptionHandlers != null)
 
667
                        {
 
668
                                List<ILGenerator.ExceptionBlock> exceptions = new List<ILGenerator.ExceptionBlock>();
 
669
                                foreach (ExceptionHandler block in exceptionHandlers)
 
670
                                {
 
671
                                        exceptions.Add(new ILGenerator.ExceptionBlock(block));
 
672
                                }
 
673
                                ILGenerator.WriteExceptionHandlers(bb, exceptions);
 
674
                        }
 
675
                }
 
676
 
 
677
                internal void Bake()
 
678
                {
 
679
                        this.nameIndex = this.ModuleBuilder.Strings.Add(name);
 
680
                        this.signature = this.ModuleBuilder.GetSignatureBlobIndex(this.MethodSignature);
 
681
 
 
682
                        __ReleaseILGenerator();
 
683
 
 
684
                        if (declarativeSecurity != null)
 
685
                        {
 
686
                                this.ModuleBuilder.AddDeclarativeSecurity(pseudoToken, declarativeSecurity);
 
687
                        }
 
688
                }
 
689
 
 
690
                internal ModuleBuilder ModuleBuilder
 
691
                {
 
692
                        get { return typeBuilder.ModuleBuilder; }
 
693
                }
 
694
 
 
695
                internal void WriteMethodDefRecord(int baseRVA, MetadataWriter mw, ref int paramList)
 
696
                {
 
697
                        if (rva != -1)
 
698
                        {
 
699
                                mw.Write(rva + baseRVA);
 
700
                        }
 
701
                        else
 
702
                        {
 
703
                                mw.Write(0);
 
704
                        }
 
705
                        mw.Write((short)implFlags);
 
706
                        mw.Write((short)attributes);
 
707
                        mw.WriteStringIndex(nameIndex);
 
708
                        mw.WriteBlobIndex(signature);
 
709
                        mw.WriteParam(paramList);
 
710
                        if (parameters != null)
 
711
                        {
 
712
                                paramList += parameters.Count;
 
713
                        }
 
714
                }
 
715
 
 
716
                internal void WriteParamRecords(MetadataWriter mw)
 
717
                {
 
718
                        if (parameters != null)
 
719
                        {
 
720
                                foreach (ParameterBuilder pb in parameters)
 
721
                                {
 
722
                                        pb.WriteParamRecord(mw);
 
723
                                }
 
724
                        }
 
725
                }
 
726
 
 
727
                internal void FixupToken(int token, ref int parameterToken)
 
728
                {
 
729
                        typeBuilder.ModuleBuilder.RegisterTokenFixup(this.pseudoToken, token);
 
730
                        if (parameters != null)
 
731
                        {
 
732
                                foreach (ParameterBuilder pb in parameters)
 
733
                                {
 
734
                                        pb.FixupToken(parameterToken++);
 
735
                                }
 
736
                        }
 
737
                }
 
738
 
 
739
                internal override MethodSignature MethodSignature
 
740
                {
 
741
                        get
 
742
                        {
 
743
                                if (methodSignature == null)
 
744
                                {
 
745
                                        methodSignature = MethodSignature.MakeFromBuilder(returnType, parameterTypes, customModifiers, callingConvention, gtpb == null ? 0 : gtpb.Length);
 
746
                                }
 
747
                                return methodSignature;
 
748
                        }
 
749
                }
 
750
 
 
751
                internal override int ImportTo(ModuleBuilder other)
 
752
                {
 
753
                        return other.ImportMethodOrField(typeBuilder, name, this.MethodSignature);
 
754
                }
 
755
 
 
756
                internal void CheckBaked()
 
757
                {
 
758
                        typeBuilder.CheckBaked();
 
759
                }
 
760
 
 
761
                internal override int GetCurrentToken()
 
762
                {
 
763
                        if (typeBuilder.ModuleBuilder.IsSaved)
 
764
                        {
 
765
                                return typeBuilder.ModuleBuilder.ResolvePseudoToken(pseudoToken);
 
766
                        }
 
767
                        else
 
768
                        {
 
769
                                return pseudoToken;
 
770
                        }
 
771
                }
 
772
 
 
773
                internal override bool IsBaked
 
774
                {
 
775
                        get { return typeBuilder.IsBaked; }
 
776
                }
 
777
        }
 
778
}