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

« back to all changes in this revision

Viewing changes to external/ikvm/reflect/Emit/ModuleBuilder.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.IO;
 
27
using System.Diagnostics;
 
28
using System.Diagnostics.SymbolStore;
 
29
using System.Security.Cryptography;
 
30
using System.Resources;
 
31
using System.Runtime.CompilerServices;
 
32
using System.Runtime.InteropServices;
 
33
using IKVM.Reflection.Impl;
 
34
using IKVM.Reflection.Metadata;
 
35
using IKVM.Reflection.Writer;
 
36
 
 
37
namespace IKVM.Reflection.Emit
 
38
{
 
39
        public sealed class ModuleBuilder : Module, ITypeOwner
 
40
        {
 
41
                private static readonly bool usePublicKeyAssemblyReference = false;
 
42
                private Guid mvid = Guid.NewGuid();
 
43
                private long imageBaseAddress = 0x00400000;
 
44
                private long stackReserve = -1;
 
45
                private int fileAlignment = 0x200;
 
46
                private DllCharacteristics dllCharacteristics = DllCharacteristics.DynamicBase | DllCharacteristics.NoSEH | DllCharacteristics.NXCompat | DllCharacteristics.TerminalServerAware;
 
47
                private readonly AssemblyBuilder asm;
 
48
                internal readonly string moduleName;
 
49
                internal readonly string fileName;
 
50
                internal readonly ISymbolWriterImpl symbolWriter;
 
51
                private readonly TypeBuilder moduleType;
 
52
                private readonly List<TypeBuilder> types = new List<TypeBuilder>();
 
53
                private readonly Dictionary<Type, int> typeTokens = new Dictionary<Type, int>();
 
54
                private readonly Dictionary<Type, int> memberRefTypeTokens = new Dictionary<Type, int>();
 
55
                internal readonly ByteBuffer methodBodies = new ByteBuffer(128 * 1024);
 
56
                internal readonly List<int> tokenFixupOffsets = new List<int>();
 
57
                internal readonly ByteBuffer initializedData = new ByteBuffer(512);
 
58
                internal readonly ByteBuffer manifestResources = new ByteBuffer(512);
 
59
                internal ResourceSection unmanagedResources;
 
60
                private readonly Dictionary<MemberRefKey, int> importedMemberRefs = new Dictionary<MemberRefKey, int>();
 
61
                private readonly Dictionary<MethodSpecKey, int> importedMethodSpecs = new Dictionary<MethodSpecKey, int>();
 
62
                private readonly Dictionary<Assembly, int> referencedAssemblies = new Dictionary<Assembly, int>();
 
63
                private List<AssemblyName> referencedAssemblyNames;
 
64
                private int nextPseudoToken = -1;
 
65
                private readonly List<int> resolvedTokens = new List<int>();
 
66
                internal readonly TableHeap Tables = new TableHeap();
 
67
                internal readonly StringHeap Strings = new StringHeap();
 
68
                internal readonly UserStringHeap UserStrings = new UserStringHeap();
 
69
                internal readonly GuidHeap Guids = new GuidHeap();
 
70
                internal readonly BlobHeap Blobs = new BlobHeap();
 
71
                internal readonly List<VTableFixups> vtablefixups = new List<VTableFixups>();
 
72
                internal readonly List<UnmanagedExport> unmanagedExports = new List<UnmanagedExport>();
 
73
                private List<InterfaceImplCustomAttribute> interfaceImplCustomAttributes;
 
74
                private List<ResourceWriterRecord> resourceWriters;
 
75
                private bool saved;
 
76
 
 
77
                private struct ResourceWriterRecord
 
78
                {
 
79
                        private readonly string name;
 
80
                        private readonly ResourceWriter rw;
 
81
                        private readonly MemoryStream mem;
 
82
                        private readonly ResourceAttributes attributes;
 
83
 
 
84
                        internal ResourceWriterRecord(string name, ResourceWriter rw, MemoryStream mem, ResourceAttributes attributes)
 
85
                        {
 
86
                                this.name = name;
 
87
                                this.rw = rw;
 
88
                                this.mem = mem;
 
89
                                this.attributes = attributes;
 
90
                        }
 
91
 
 
92
                        internal void Emit(ModuleBuilder mb)
 
93
                        {
 
94
                                rw.Generate();
 
95
                                mem.Position = 0;
 
96
                                mb.DefineManifestResource(name, mem, attributes);
 
97
                                rw.Close();
 
98
                        }
 
99
                }
 
100
 
 
101
                internal struct VTableFixups
 
102
                {
 
103
                        internal uint initializedDataOffset;
 
104
                        internal ushort count;
 
105
                        internal ushort type;
 
106
 
 
107
                        internal int SlotWidth
 
108
                        {
 
109
                                get { return (type & 0x02) == 0 ? 4 : 8; }
 
110
                        }
 
111
                }
 
112
 
 
113
                struct InterfaceImplCustomAttribute
 
114
                {
 
115
                        internal int type;
 
116
                        internal int interfaceType;
 
117
                        internal int pseudoToken;
 
118
                }
 
119
 
 
120
                struct MemberRefKey : IEquatable<MemberRefKey>
 
121
                {
 
122
                        private readonly Type type;
 
123
                        private readonly string name;
 
124
                        private readonly Signature signature;
 
125
 
 
126
                        internal MemberRefKey(Type type, string name, Signature signature)
 
127
                        {
 
128
                                this.type = type;
 
129
                                this.name = name;
 
130
                                this.signature = signature;
 
131
                        }
 
132
 
 
133
                        public bool Equals(MemberRefKey other)
 
134
                        {
 
135
                                return other.type.Equals(type)
 
136
                                        && other.name == name
 
137
                                        && other.signature.Equals(signature);
 
138
                        }
 
139
 
 
140
                        public override bool Equals(object obj)
 
141
                        {
 
142
                                MemberRefKey? other = obj as MemberRefKey?;
 
143
                                return other != null && Equals(other);
 
144
                        }
 
145
 
 
146
                        public override int GetHashCode()
 
147
                        {
 
148
                                return type.GetHashCode() + name.GetHashCode() + signature.GetHashCode();
 
149
                        }
 
150
 
 
151
                        internal MethodBase LookupMethod()
 
152
                        {
 
153
                                return type.FindMethod(name, (MethodSignature)signature);
 
154
                        }
 
155
                }
 
156
 
 
157
                struct MethodSpecKey : IEquatable<MethodSpecKey>
 
158
                {
 
159
                        private readonly Type type;
 
160
                        private readonly string name;
 
161
                        private readonly MethodSignature signature;
 
162
                        private readonly Type[] genericParameters;
 
163
 
 
164
                        internal MethodSpecKey(Type type, string name, MethodSignature signature, Type[] genericParameters)
 
165
                        {
 
166
                                this.type = type;
 
167
                                this.name = name;
 
168
                                this.signature = signature;
 
169
                                this.genericParameters = genericParameters;
 
170
                        }
 
171
 
 
172
                        public bool Equals(MethodSpecKey other)
 
173
                        {
 
174
                                return other.type.Equals(type)
 
175
                                        && other.name == name
 
176
                                        && other.signature.Equals(signature)
 
177
                                        && Util.ArrayEquals(other.genericParameters, genericParameters);
 
178
                        }
 
179
 
 
180
                        public override bool Equals(object obj)
 
181
                        {
 
182
                                MethodSpecKey? other = obj as MethodSpecKey?;
 
183
                                return other != null && Equals(other);
 
184
                        }
 
185
 
 
186
                        public override int GetHashCode()
 
187
                        {
 
188
                                return type.GetHashCode() + name.GetHashCode() + signature.GetHashCode() + Util.GetHashCode(genericParameters);
 
189
                        }
 
190
                }
 
191
 
 
192
                internal ModuleBuilder(AssemblyBuilder asm, string moduleName, string fileName, bool emitSymbolInfo)
 
193
                        : base(asm.universe)
 
194
                {
 
195
                        this.asm = asm;
 
196
                        this.moduleName = moduleName;
 
197
                        this.fileName = fileName;
 
198
                        if (emitSymbolInfo)
 
199
                        {
 
200
                                symbolWriter = SymbolSupport.CreateSymbolWriterFor(this);
 
201
                        }
 
202
                        // <Module> must be the first record in the TypeDef table
 
203
                        moduleType = new TypeBuilder(this, null, "<Module>");
 
204
                        types.Add(moduleType);
 
205
                }
 
206
 
 
207
                internal void PopulatePropertyAndEventTables()
 
208
                {
 
209
                        // LAMESPEC the PropertyMap and EventMap tables are not required to be sorted by the CLI spec,
 
210
                        // but .NET sorts them and Mono requires them to be sorted, so we have to populate the
 
211
                        // tables in the right order
 
212
                        foreach (TypeBuilder type in types)
 
213
                        {
 
214
                                type.PopulatePropertyAndEventTables();
 
215
                        }
 
216
                }
 
217
 
 
218
                internal void WriteTypeDefTable(MetadataWriter mw)
 
219
                {
 
220
                        int fieldList = 1;
 
221
                        int methodList = 1;
 
222
                        foreach (TypeBuilder type in types)
 
223
                        {
 
224
                                type.WriteTypeDefRecord(mw, ref fieldList, ref methodList);
 
225
                        }
 
226
                }
 
227
 
 
228
                internal void WriteMethodDefTable(int baseRVA, MetadataWriter mw)
 
229
                {
 
230
                        int paramList = 1;
 
231
                        foreach (TypeBuilder type in types)
 
232
                        {
 
233
                                type.WriteMethodDefRecords(baseRVA, mw, ref paramList);
 
234
                        }
 
235
                }
 
236
 
 
237
                internal void WriteParamTable(MetadataWriter mw)
 
238
                {
 
239
                        foreach (TypeBuilder type in types)
 
240
                        {
 
241
                                type.WriteParamRecords(mw);
 
242
                        }
 
243
                }
 
244
 
 
245
                internal void WriteFieldTable(MetadataWriter mw)
 
246
                {
 
247
                        foreach (TypeBuilder type in types)
 
248
                        {
 
249
                                type.WriteFieldRecords(mw);
 
250
                        }
 
251
                }
 
252
 
 
253
                internal int AllocPseudoToken()
 
254
                {
 
255
                        return nextPseudoToken--;
 
256
                }
 
257
 
 
258
                public TypeBuilder DefineType(string name)
 
259
                {
 
260
                        return DefineType(name, TypeAttributes.Class);
 
261
                }
 
262
 
 
263
                public TypeBuilder DefineType(string name, TypeAttributes attr)
 
264
                {
 
265
                        return DefineType(name, attr, null);
 
266
                }
 
267
 
 
268
                public TypeBuilder DefineType(string name, TypeAttributes attr, Type parent)
 
269
                {
 
270
                        return DefineType(name, attr, parent, PackingSize.Unspecified, 0);
 
271
                }
 
272
 
 
273
                public TypeBuilder DefineType(string name, TypeAttributes attr, Type parent, int typesize)
 
274
                {
 
275
                        return DefineType(name, attr, parent, PackingSize.Unspecified, typesize);
 
276
                }
 
277
 
 
278
                public TypeBuilder DefineType(string name, TypeAttributes attr, Type parent, PackingSize packsize)
 
279
                {
 
280
                        return DefineType(name, attr, parent, packsize, 0);
 
281
                }
 
282
 
 
283
                public TypeBuilder DefineType(string name, TypeAttributes attr, Type parent, Type[] interfaces)
 
284
                {
 
285
                        TypeBuilder tb = DefineType(name, attr, parent);
 
286
                        foreach (Type iface in interfaces)
 
287
                        {
 
288
                                tb.AddInterfaceImplementation(iface);
 
289
                        }
 
290
                        return tb;
 
291
                }
 
292
 
 
293
                public TypeBuilder DefineType(string name, TypeAttributes attr, Type parent, PackingSize packingSize, int typesize)
 
294
                {
 
295
                        string ns = null;
 
296
                        int lastdot = name.LastIndexOf('.');
 
297
                        if (lastdot > 0)
 
298
                        {
 
299
                                ns = name.Substring(0, lastdot);
 
300
                                name = name.Substring(lastdot + 1);
 
301
                        }
 
302
                        TypeBuilder typeBuilder = __DefineType(ns, name);
 
303
                        typeBuilder.__SetAttributes(attr);
 
304
                        typeBuilder.SetParent(parent);
 
305
                        if (packingSize != PackingSize.Unspecified || typesize != 0)
 
306
                        {
 
307
                                typeBuilder.__SetLayout((int)packingSize, typesize);
 
308
                        }
 
309
                        return typeBuilder;
 
310
                }
 
311
 
 
312
                public TypeBuilder __DefineType(string ns, string name)
 
313
                {
 
314
                        return DefineType(this, ns, name);
 
315
                }
 
316
 
 
317
                internal TypeBuilder DefineType(ITypeOwner owner, string ns, string name)
 
318
                {
 
319
                        TypeBuilder typeBuilder = new TypeBuilder(owner, ns, name);
 
320
                        types.Add(typeBuilder);
 
321
                        return typeBuilder;
 
322
                }
 
323
 
 
324
                public EnumBuilder DefineEnum(string name, TypeAttributes visibility, Type underlyingType)
 
325
                {
 
326
                        TypeBuilder tb = DefineType(name, (visibility & TypeAttributes.VisibilityMask) | TypeAttributes.Sealed, universe.System_Enum);
 
327
                        FieldBuilder fb = tb.DefineField("value__", underlyingType, FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);
 
328
                        return new EnumBuilder(tb, fb);
 
329
                }
 
330
 
 
331
                public FieldBuilder __DefineField(string name, Type type, CustomModifiers customModifiers, FieldAttributes attributes)
 
332
                {
 
333
                        return moduleType.__DefineField(name, type, customModifiers, attributes);
 
334
                }
 
335
 
 
336
                [Obsolete("Please use __DefineField(string, Type, CustomModifiers, FieldAttributes) instead.")]
 
337
                public FieldBuilder __DefineField(string name, Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes)
 
338
                {
 
339
                        return moduleType.DefineField(name, type, requiredCustomModifiers, optionalCustomModifiers, attributes);
 
340
                }
 
341
 
 
342
                public ConstructorBuilder __DefineModuleInitializer(MethodAttributes visibility)
 
343
                {
 
344
                        return moduleType.DefineConstructor(visibility | MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, Type.EmptyTypes);
 
345
                }
 
346
 
 
347
                public FieldBuilder DefineUninitializedData(string name, int size, FieldAttributes attributes)
 
348
                {
 
349
                        return moduleType.DefineUninitializedData(name, size, attributes);
 
350
                }
 
351
 
 
352
                public FieldBuilder DefineInitializedData(string name, byte[] data, FieldAttributes attributes)
 
353
                {
 
354
                        return moduleType.DefineInitializedData(name, data, attributes);
 
355
                }
 
356
 
 
357
                public MethodBuilder DefineGlobalMethod(string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes)
 
358
                {
 
359
                        return moduleType.DefineMethod(name, attributes, returnType, parameterTypes);
 
360
                }
 
361
 
 
362
                public MethodBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
 
363
                {
 
364
                        return moduleType.DefineMethod(name, attributes, callingConvention, returnType, parameterTypes);
 
365
                }
 
366
 
 
367
                public MethodBuilder DefineGlobalMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
 
368
                {
 
369
                        return moduleType.DefineMethod(name, attributes, callingConvention, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
 
370
                }
 
371
 
 
372
                public MethodBuilder DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet)
 
373
                {
 
374
                        return moduleType.DefinePInvokeMethod(name, dllName, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet);
 
375
                }
 
376
 
 
377
                public MethodBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet)
 
378
                {
 
379
                        return moduleType.DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet);
 
380
                }
 
381
 
 
382
                public void CreateGlobalFunctions()
 
383
                {
 
384
                        moduleType.CreateType();
 
385
                }
 
386
 
 
387
                internal void AddTypeForwarder(Type type)
 
388
                {
 
389
                        ExportType(type);
 
390
                        if (!type.__IsMissing)
 
391
                        {
 
392
                                foreach (Type nested in type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic))
 
393
                                {
 
394
                                        // we export all nested types (i.e. even the private ones)
 
395
                                        // (this behavior is the same as the C# compiler)
 
396
                                        AddTypeForwarder(nested);
 
397
                                }
 
398
                        }
 
399
                }
 
400
 
 
401
                private int ExportType(Type type)
 
402
                {
 
403
                        ExportedTypeTable.Record rec = new ExportedTypeTable.Record();
 
404
                        rec.TypeName = this.Strings.Add(type.__Name);
 
405
                        string ns = type.__Namespace;
 
406
                        rec.TypeNamespace = ns == null ? 0 : this.Strings.Add(ns);
 
407
                        if (type.IsNested)
 
408
                        {
 
409
                                rec.Flags = 0;
 
410
                                rec.Implementation = ExportType(type.DeclaringType);
 
411
                        }
 
412
                        else
 
413
                        {
 
414
                                rec.Flags = 0x00200000; // CorTypeAttr.tdForwarder
 
415
                                rec.Implementation = ImportAssemblyRef(type.Assembly);
 
416
                        }
 
417
                        return 0x27000000 | this.ExportedType.FindOrAddRecord(rec);
 
418
                }
 
419
 
 
420
                public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
 
421
                {
 
422
                        SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
 
423
                }
 
424
 
 
425
                public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
 
426
                {
 
427
                        SetCustomAttribute(0x00000001, customBuilder);
 
428
                }
 
429
 
 
430
                internal void SetCustomAttribute(int token, CustomAttributeBuilder customBuilder)
 
431
                {
 
432
                        Debug.Assert(!customBuilder.IsPseudoCustomAttribute);
 
433
                        CustomAttributeTable.Record rec = new CustomAttributeTable.Record();
 
434
                        rec.Parent = token;
 
435
                        rec.Type = asm.IsWindowsRuntime ? customBuilder.Constructor.ImportTo(this) : GetConstructorToken(customBuilder.Constructor).Token;
 
436
                        rec.Value = customBuilder.WriteBlob(this);
 
437
                        this.CustomAttribute.AddRecord(rec);
 
438
                }
 
439
 
 
440
                internal void AddDeclarativeSecurity(int token, System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet)
 
441
                {
 
442
                        DeclSecurityTable.Record rec = new DeclSecurityTable.Record();
 
443
                        rec.Action = (short)securityAction;
 
444
                        rec.Parent = token;
 
445
                        // like Ref.Emit, we're using the .NET 1.x xml format
 
446
                        rec.PermissionSet = this.Blobs.Add(ByteBuffer.Wrap(System.Text.Encoding.Unicode.GetBytes(permissionSet.ToXml().ToString())));
 
447
                        this.DeclSecurity.AddRecord(rec);
 
448
                }
 
449
 
 
450
                internal void AddDeclarativeSecurity(int token, List<CustomAttributeBuilder> declarativeSecurity)
 
451
                {
 
452
                        Dictionary<int, List<CustomAttributeBuilder>> ordered = new Dictionary<int, List<CustomAttributeBuilder>>();
 
453
                        foreach (CustomAttributeBuilder cab in declarativeSecurity)
 
454
                        {
 
455
                                int action;
 
456
                                // check for HostProtectionAttribute without SecurityAction
 
457
                                if (cab.ConstructorArgumentCount == 0)
 
458
                                {
 
459
                                        action = (int)System.Security.Permissions.SecurityAction.LinkDemand;
 
460
                                }
 
461
                                else
 
462
                                {
 
463
                                        action = (int)cab.GetConstructorArgument(0);
 
464
                                }
 
465
                                List<CustomAttributeBuilder> list;
 
466
                                if (!ordered.TryGetValue(action, out list))
 
467
                                {
 
468
                                        list = new List<CustomAttributeBuilder>();
 
469
                                        ordered.Add(action, list);
 
470
                                }
 
471
                                list.Add(cab);
 
472
                        }
 
473
                        foreach (KeyValuePair<int, List<CustomAttributeBuilder>> kv in ordered)
 
474
                        {
 
475
                                DeclSecurityTable.Record rec = new DeclSecurityTable.Record();
 
476
                                rec.Action = (short)kv.Key;
 
477
                                rec.Parent = token;
 
478
                                rec.PermissionSet = WriteDeclSecurityBlob(kv.Value);
 
479
                                this.DeclSecurity.AddRecord(rec);
 
480
                        }
 
481
                }
 
482
 
 
483
                private int WriteDeclSecurityBlob(List<CustomAttributeBuilder> list)
 
484
                {
 
485
                        string xml;
 
486
                        if (list.Count == 1 && (xml = list[0].GetLegacyDeclSecurity()) != null)
 
487
                        {
 
488
                                // write .NET 1.1 format
 
489
                                return this.Blobs.Add(ByteBuffer.Wrap(System.Text.Encoding.Unicode.GetBytes(xml)));
 
490
                        }
 
491
                        ByteBuffer namedArgs = new ByteBuffer(100);
 
492
                        ByteBuffer bb = new ByteBuffer(list.Count * 100);
 
493
                        bb.Write((byte)'.');
 
494
                        bb.WriteCompressedUInt(list.Count);
 
495
                        foreach (CustomAttributeBuilder cab in list)
 
496
                        {
 
497
                                bb.Write(cab.Constructor.DeclaringType.AssemblyQualifiedName);
 
498
                                namedArgs.Clear();
 
499
                                cab.WriteNamedArgumentsForDeclSecurity(this, namedArgs);
 
500
                                bb.WriteCompressedUInt(namedArgs.Length);
 
501
                                bb.Write(namedArgs);
 
502
                        }
 
503
                        return this.Blobs.Add(bb);
 
504
                }
 
505
 
 
506
                public void DefineManifestResource(string name, Stream stream, ResourceAttributes attribute)
 
507
                {
 
508
                        manifestResources.Align(8);
 
509
                        ManifestResourceTable.Record rec = new ManifestResourceTable.Record();
 
510
                        rec.Offset = manifestResources.Position;
 
511
                        rec.Flags = (int)attribute;
 
512
                        rec.Name = this.Strings.Add(name);
 
513
                        rec.Implementation = 0;
 
514
                        this.ManifestResource.AddRecord(rec);
 
515
                        manifestResources.Write(0);     // placeholder for the length
 
516
                        manifestResources.Write(stream);
 
517
                        int savePosition = manifestResources.Position;
 
518
                        manifestResources.Position = rec.Offset;
 
519
                        manifestResources.Write(savePosition - (manifestResources.Position + 4));
 
520
                        manifestResources.Position = savePosition;
 
521
                }
 
522
 
 
523
                public IResourceWriter DefineResource(string name, string description)
 
524
                {
 
525
                        return DefineResource(name, description, ResourceAttributes.Public);
 
526
                }
 
527
 
 
528
                public IResourceWriter DefineResource(string name, string description, ResourceAttributes attribute)
 
529
                {
 
530
                        // FXBUG we ignore the description, because there is no such thing
 
531
 
 
532
                        if (resourceWriters == null)
 
533
                        {
 
534
                                resourceWriters = new List<ResourceWriterRecord>();
 
535
                        }
 
536
                        MemoryStream mem = new MemoryStream();
 
537
                        ResourceWriter rw = new ResourceWriter(mem);
 
538
                        resourceWriters.Add(new ResourceWriterRecord(name, rw, mem, attribute));
 
539
                        return rw;
 
540
                }
 
541
 
 
542
                internal void EmitResources()
 
543
                {
 
544
                        if (resourceWriters != null)
 
545
                        {
 
546
                                foreach (ResourceWriterRecord rwr in resourceWriters)
 
547
                                {
 
548
                                        rwr.Emit(this);
 
549
                                }
 
550
                        }
 
551
                }
 
552
 
 
553
                public override Assembly Assembly
 
554
                {
 
555
                        get { return asm; }
 
556
                }
 
557
 
 
558
                internal override Type FindType(TypeName name)
 
559
                {
 
560
                        foreach (Type type in types)
 
561
                        {
 
562
                                if (type.__Namespace == name.Namespace && type.__Name == name.Name)
 
563
                                {
 
564
                                        return type;
 
565
                                }
 
566
                        }
 
567
                        return null;
 
568
                }
 
569
 
 
570
                internal override Type FindTypeIgnoreCase(TypeName lowerCaseName)
 
571
                {
 
572
                        foreach (Type type in types)
 
573
                        {
 
574
                                if (new TypeName(type.__Namespace, type.__Name).ToLowerInvariant() == lowerCaseName)
 
575
                                {
 
576
                                        return type;
 
577
                                }
 
578
                        }
 
579
                        return null;
 
580
                }
 
581
 
 
582
                internal override void GetTypesImpl(List<Type> list)
 
583
                {
 
584
                        foreach (Type type in types)
 
585
                        {
 
586
                                if (type != moduleType)
 
587
                                {
 
588
                                        list.Add(type);
 
589
                                }
 
590
                        }
 
591
                }
 
592
 
 
593
                public ISymbolDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType)
 
594
                {
 
595
                        return symbolWriter.DefineDocument(url, language, languageVendor, documentType);
 
596
                }
 
597
 
 
598
                public int __GetAssemblyToken(Assembly assembly)
 
599
                {
 
600
                        return ImportAssemblyRef(assembly);
 
601
                }
 
602
 
 
603
                public TypeToken GetTypeToken(string name)
 
604
                {
 
605
                        return new TypeToken(GetType(name, true, false).MetadataToken);
 
606
                }
 
607
 
 
608
                public TypeToken GetTypeToken(Type type)
 
609
                {
 
610
                        if (type.Module == this && !asm.IsWindowsRuntime)
 
611
                        {
 
612
                                return new TypeToken(type.GetModuleBuilderToken());
 
613
                        }
 
614
                        else
 
615
                        {
 
616
                                return new TypeToken(ImportType(type));
 
617
                        }
 
618
                }
 
619
 
 
620
                internal int GetTypeTokenForMemberRef(Type type)
 
621
                {
 
622
                        if (type.__IsMissing)
 
623
                        {
 
624
                                return ImportType(type);
 
625
                        }
 
626
                        else if (type.IsGenericTypeDefinition)
 
627
                        {
 
628
                                int token;
 
629
                                if (!memberRefTypeTokens.TryGetValue(type, out token))
 
630
                                {
 
631
                                        ByteBuffer spec = new ByteBuffer(5);
 
632
                                        Signature.WriteTypeSpec(this, spec, type);
 
633
                                        token = 0x1B000000 | this.TypeSpec.AddRecord(this.Blobs.Add(spec));
 
634
                                        memberRefTypeTokens.Add(type, token);
 
635
                                }
 
636
                                return token;
 
637
                        }
 
638
                        else if (type.IsModulePseudoType)
 
639
                        {
 
640
                                return 0x1A000000 | this.ModuleRef.FindOrAddRecord(this.Strings.Add(type.Module.ScopeName));
 
641
                        }
 
642
                        else
 
643
                        {
 
644
                                return GetTypeToken(type).Token;
 
645
                        }
 
646
                }
 
647
 
 
648
                private static bool IsFromGenericTypeDefinition(MemberInfo member)
 
649
                {
 
650
                        Type decl = member.DeclaringType;
 
651
                        return decl != null && !decl.__IsMissing && decl.IsGenericTypeDefinition;
 
652
                }
 
653
 
 
654
                public FieldToken GetFieldToken(FieldInfo field)
 
655
                {
 
656
                        // NOTE for some reason, when TypeBuilder.GetFieldToken() is used on a field in a generic type definition,
 
657
                        // a memberref token is returned (confirmed on .NET) unlike for Get(Method|Constructor)Token which always
 
658
                        // simply returns the MethodDef token (if the method is from the same module).
 
659
                        FieldBuilder fb = field as FieldBuilder;
 
660
                        if (fb != null && fb.Module == this && !IsFromGenericTypeDefinition(fb))
 
661
                        {
 
662
                                return new FieldToken(fb.MetadataToken);
 
663
                        }
 
664
                        else
 
665
                        {
 
666
                                return new FieldToken(field.ImportTo(this));
 
667
                        }
 
668
                }
 
669
 
 
670
                public MethodToken GetMethodToken(MethodInfo method)
 
671
                {
 
672
                        MethodBuilder mb = method as MethodBuilder;
 
673
                        if (mb != null && mb.ModuleBuilder == this)
 
674
                        {
 
675
                                return new MethodToken(mb.MetadataToken);
 
676
                        }
 
677
                        else
 
678
                        {
 
679
                                return new MethodToken(method.ImportTo(this));
 
680
                        }
 
681
                }
 
682
 
 
683
                // new in .NET 4.5
 
684
                public MethodToken GetMethodToken(MethodInfo method, IEnumerable<Type> optionalParameterTypes)
 
685
                {
 
686
                        return __GetMethodToken(method, Util.ToArray(optionalParameterTypes), null);
 
687
                }
 
688
 
 
689
                public MethodToken __GetMethodToken(MethodInfo method, Type[] optionalParameterTypes, CustomModifiers[] customModifiers)
 
690
                {
 
691
                        ByteBuffer sig = new ByteBuffer(16);
 
692
                        method.MethodSignature.WriteMethodRefSig(this, sig, optionalParameterTypes, customModifiers);
 
693
                        MemberRefTable.Record record = new MemberRefTable.Record();
 
694
                        if (method.Module == this)
 
695
                        {
 
696
                                record.Class = method.MetadataToken;
 
697
                        }
 
698
                        else
 
699
                        {
 
700
                                record.Class = GetTypeTokenForMemberRef(method.DeclaringType ?? method.Module.GetModuleType());
 
701
                        }
 
702
                        record.Name = Strings.Add(method.Name);
 
703
                        record.Signature = Blobs.Add(sig);
 
704
                        return new MethodToken(0x0A000000 | MemberRef.FindOrAddRecord(record));
 
705
                }
 
706
 
 
707
                // when we refer to a method on a generic type definition in the IL stream,
 
708
                // we need to use a MemberRef (even if the method is in the same module)
 
709
                internal MethodToken GetMethodTokenForIL(MethodInfo method)
 
710
                {
 
711
                        if (method.IsGenericMethodDefinition)
 
712
                        {
 
713
                                method = method.MakeGenericMethod(method.GetGenericArguments());
 
714
                        }
 
715
                        if (IsFromGenericTypeDefinition(method))
 
716
                        {
 
717
                                return new MethodToken(method.ImportTo(this));
 
718
                        }
 
719
                        else
 
720
                        {
 
721
                                return GetMethodToken(method);
 
722
                        }
 
723
                }
 
724
 
 
725
                internal int GetMethodTokenWinRT(MethodInfo method)
 
726
                {
 
727
                        return asm.IsWindowsRuntime ? method.ImportTo(this) : GetMethodToken(method).Token;
 
728
                }
 
729
 
 
730
                public MethodToken GetConstructorToken(ConstructorInfo constructor)
 
731
                {
 
732
                        return GetMethodToken(constructor.GetMethodInfo());
 
733
                }
 
734
 
 
735
                // new in .NET 4.5
 
736
                public MethodToken GetConstructorToken(ConstructorInfo constructor, IEnumerable<Type> optionalParameterTypes)
 
737
                {
 
738
                        return GetMethodToken(constructor.GetMethodInfo(), optionalParameterTypes);
 
739
                }
 
740
 
 
741
                public MethodToken __GetConstructorToken(ConstructorInfo constructor, Type[] optionalParameterTypes, CustomModifiers[] customModifiers)
 
742
                {
 
743
                        return __GetMethodToken(constructor.GetMethodInfo(), optionalParameterTypes, customModifiers);
 
744
                }
 
745
 
 
746
                internal int ImportMethodOrField(Type declaringType, string name, Signature sig)
 
747
                {
 
748
                        int token;
 
749
                        MemberRefKey key = new MemberRefKey(declaringType, name, sig);
 
750
                        if (!importedMemberRefs.TryGetValue(key, out token))
 
751
                        {
 
752
                                MemberRefTable.Record rec = new MemberRefTable.Record();
 
753
                                rec.Class = GetTypeTokenForMemberRef(declaringType);
 
754
                                rec.Name = this.Strings.Add(name);
 
755
                                ByteBuffer bb = new ByteBuffer(16);
 
756
                                sig.WriteSig(this, bb);
 
757
                                rec.Signature = this.Blobs.Add(bb);
 
758
                                token = 0x0A000000 | this.MemberRef.AddRecord(rec);
 
759
                                importedMemberRefs.Add(key, token);
 
760
                        }
 
761
                        return token;
 
762
                }
 
763
 
 
764
                internal int ImportMethodSpec(Type declaringType, MethodInfo method, Type[] genericParameters)
 
765
                {
 
766
                        Debug.Assert(method.__IsMissing || method.GetMethodOnTypeDefinition() == method);
 
767
                        int token;
 
768
                        MethodSpecKey key = new MethodSpecKey(declaringType, method.Name, method.MethodSignature, genericParameters);
 
769
                        if (!importedMethodSpecs.TryGetValue(key, out token))
 
770
                        {
 
771
                                MethodSpecTable.Record rec = new MethodSpecTable.Record();
 
772
                                MethodBuilder mb = method as MethodBuilder;
 
773
                                if (mb != null && mb.ModuleBuilder == this && !declaringType.IsGenericType)
 
774
                                {
 
775
                                        rec.Method = mb.MetadataToken;
 
776
                                }
 
777
                                else
 
778
                                {
 
779
                                        // we're calling ImportMethodOrField directly here, because 'method' may be a MethodDef on a generic TypeDef and 'declaringType' the type instance
 
780
                                        // (in order words the method and type have already been decoupled by the caller)
 
781
                                        rec.Method = ImportMethodOrField(declaringType, method.Name, method.MethodSignature);
 
782
                                }
 
783
                                Writer.ByteBuffer spec = new Writer.ByteBuffer(10);
 
784
                                Signature.WriteMethodSpec(this, spec, genericParameters);
 
785
                                rec.Instantiation = this.Blobs.Add(spec);
 
786
                                token = 0x2B000000 | this.MethodSpec.FindOrAddRecord(rec);
 
787
                                importedMethodSpecs.Add(key, token);
 
788
                        }
 
789
                        return token;
 
790
                }
 
791
 
 
792
                internal int ImportType(Type type)
 
793
                {
 
794
                        int token;
 
795
                        if (!typeTokens.TryGetValue(type, out token))
 
796
                        {
 
797
                                if (type.HasElementType || type.IsConstructedGenericType || type.__IsFunctionPointer)
 
798
                                {
 
799
                                        ByteBuffer spec = new ByteBuffer(5);
 
800
                                        Signature.WriteTypeSpec(this, spec, type);
 
801
                                        token = 0x1B000000 | this.TypeSpec.AddRecord(this.Blobs.Add(spec));
 
802
                                }
 
803
                                else
 
804
                                {
 
805
                                        TypeRefTable.Record rec = new TypeRefTable.Record();
 
806
                                        if (type.IsNested)
 
807
                                        {
 
808
                                                rec.ResolutionScope = GetTypeToken(type.DeclaringType).Token;
 
809
                                        }
 
810
                                        else if (type.Module == this)
 
811
                                        {
 
812
                                                rec.ResolutionScope = 1;
 
813
                                        }
 
814
                                        else
 
815
                                        {
 
816
                                                rec.ResolutionScope = ImportAssemblyRef(type.Assembly);
 
817
                                        }
 
818
                                        rec.TypeName = this.Strings.Add(type.__Name);
 
819
                                        string ns = type.__Namespace;
 
820
                                        rec.TypeNameSpace = ns == null ? 0 : this.Strings.Add(ns);
 
821
                                        token = 0x01000000 | this.TypeRef.AddRecord(rec);
 
822
                                }
 
823
                                typeTokens.Add(type, token);
 
824
                        }
 
825
                        return token;
 
826
                }
 
827
 
 
828
                private int ImportAssemblyRef(Assembly asm)
 
829
                {
 
830
                        int token;
 
831
                        if (!referencedAssemblies.TryGetValue(asm, out token))
 
832
                        {
 
833
                                // We can't write the AssemblyRef record here yet, because the identity of the assembly can still change
 
834
                                // (if it's an AssemblyBuilder).
 
835
                                token = AllocPseudoToken();
 
836
                                referencedAssemblies.Add(asm, token);
 
837
                        }
 
838
                        return token;
 
839
                }
 
840
 
 
841
                internal void FillAssemblyRefTable()
 
842
                {
 
843
                        foreach (KeyValuePair<Assembly, int> kv in referencedAssemblies)
 
844
                        {
 
845
                                if (IsPseudoToken(kv.Value))
 
846
                                {
 
847
                                        RegisterTokenFixup(kv.Value, FindOrAddAssemblyRef(kv.Key.GetName(), false));
 
848
                                }
 
849
                        }
 
850
                }
 
851
 
 
852
                private int FindOrAddAssemblyRef(AssemblyName name, bool alwaysAdd)
 
853
                {
 
854
                        AssemblyRefTable.Record rec = new AssemblyRefTable.Record();
 
855
                        Version ver = name.Version ?? new Version(0, 0, 0, 0);
 
856
                        rec.MajorVersion = (ushort)ver.Major;
 
857
                        rec.MinorVersion = (ushort)ver.Minor;
 
858
                        rec.BuildNumber = (ushort)ver.Build;
 
859
                        rec.RevisionNumber = (ushort)ver.Revision;
 
860
                        rec.Flags = (int)(name.Flags & ~AssemblyNameFlags.PublicKey);
 
861
                        const AssemblyNameFlags afPA_Specified = (AssemblyNameFlags)0x0080;
 
862
                        const AssemblyNameFlags afPA_Mask = (AssemblyNameFlags)0x0070;
 
863
                        if ((name.RawFlags & afPA_Specified) != 0)
 
864
                        {
 
865
                                rec.Flags |= (int)(name.RawFlags & afPA_Mask);
 
866
                        }
 
867
                        if (name.ContentType == AssemblyContentType.WindowsRuntime)
 
868
                        {
 
869
                                rec.Flags |= 0x0200;
 
870
                        }
 
871
                        byte[] publicKeyOrToken = null;
 
872
                        if (usePublicKeyAssemblyReference)
 
873
                        {
 
874
                                publicKeyOrToken = name.GetPublicKey();
 
875
                        }
 
876
                        if (publicKeyOrToken == null || publicKeyOrToken.Length == 0)
 
877
                        {
 
878
                                publicKeyOrToken = name.GetPublicKeyToken() ?? Empty<byte>.Array;
 
879
                        }
 
880
                        else
 
881
                        {
 
882
                                const int PublicKey = 0x0001;
 
883
                                rec.Flags |= PublicKey;
 
884
                        }
 
885
                        rec.PublicKeyOrToken = this.Blobs.Add(ByteBuffer.Wrap(publicKeyOrToken));
 
886
                        rec.Name = this.Strings.Add(name.Name);
 
887
                        rec.Culture = name.Culture == null ? 0 : this.Strings.Add(name.Culture);
 
888
                        if (name.hash != null)
 
889
                        {
 
890
                                rec.HashValue = this.Blobs.Add(ByteBuffer.Wrap(name.hash));
 
891
                        }
 
892
                        else
 
893
                        {
 
894
                                rec.HashValue = 0;
 
895
                        }
 
896
                        return 0x23000000 | (alwaysAdd ? this.AssemblyRef.AddRecord(rec) : this.AssemblyRef.FindOrAddRecord(rec));
 
897
                }
 
898
 
 
899
                internal void WriteSymbolTokenMap()
 
900
                {
 
901
                        for (int i = 0; i < resolvedTokens.Count; i++)
 
902
                        {
 
903
                                int newToken = resolvedTokens[i];
 
904
                                // The symbol API doesn't support remapping arbitrary integers, the types have to be the same,
 
905
                                // so we copy the type from the newToken, because our pseudo tokens don't have a type.
 
906
                                // (see MethodToken.SymbolToken)
 
907
                                int oldToken = (i + 1) | (newToken & ~0xFFFFFF);
 
908
                                SymbolSupport.RemapToken(symbolWriter, oldToken, newToken);
 
909
                        }
 
910
                }
 
911
 
 
912
                internal void RegisterTokenFixup(int pseudoToken, int realToken)
 
913
                {
 
914
                        int index = -(pseudoToken + 1);
 
915
                        while (resolvedTokens.Count <= index)
 
916
                        {
 
917
                                resolvedTokens.Add(0);
 
918
                        }
 
919
                        resolvedTokens[index] = realToken;
 
920
                }
 
921
 
 
922
                internal static bool IsPseudoToken(int token)
 
923
                {
 
924
                        return token < 0;
 
925
                }
 
926
 
 
927
                internal int ResolvePseudoToken(int pseudoToken)
 
928
                {
 
929
                        int index = -(pseudoToken + 1);
 
930
                        return resolvedTokens[index];
 
931
                }
 
932
 
 
933
                internal void ApplyUnmanagedExports(ImageFileMachine imageFileMachine)
 
934
                {
 
935
                        if (unmanagedExports.Count != 0)
 
936
                        {
 
937
                                int type;
 
938
                                int size;
 
939
                                if (imageFileMachine == ImageFileMachine.I386)
 
940
                                {
 
941
                                        type = 0x05;
 
942
                                        size = 4;
 
943
                                }
 
944
                                else
 
945
                                {
 
946
                                        type = 0x06;
 
947
                                        size = 8;
 
948
                                }
 
949
                                List<MethodBuilder> methods = new List<MethodBuilder>();
 
950
                                for (int i = 0; i < unmanagedExports.Count; i++)
 
951
                                {
 
952
                                        if (unmanagedExports[i].mb != null)
 
953
                                        {
 
954
                                                methods.Add(unmanagedExports[i].mb);
 
955
                                        }
 
956
                                }
 
957
                                if (methods.Count != 0)
 
958
                                {
 
959
                                        RelativeVirtualAddress rva = __AddVTableFixups(methods.ToArray(), type);
 
960
                                        for (int i = 0; i < unmanagedExports.Count; i++)
 
961
                                        {
 
962
                                                if (unmanagedExports[i].mb != null)
 
963
                                                {
 
964
                                                        UnmanagedExport exp = unmanagedExports[i];
 
965
                                                        exp.rva = new RelativeVirtualAddress(rva.initializedDataOffset + (uint)(methods.IndexOf(unmanagedExports[i].mb) * size));
 
966
                                                        unmanagedExports[i] = exp;
 
967
                                                }
 
968
                                        }
 
969
                                }
 
970
                        }
 
971
                }
 
972
 
 
973
                internal void FixupMethodBodyTokens()
 
974
                {
 
975
                        int methodToken = 0x06000001;
 
976
                        int fieldToken = 0x04000001;
 
977
                        int parameterToken = 0x08000001;
 
978
                        foreach (TypeBuilder type in types)
 
979
                        {
 
980
                                type.ResolveMethodAndFieldTokens(ref methodToken, ref fieldToken, ref parameterToken);
 
981
                        }
 
982
                        foreach (int offset in tokenFixupOffsets)
 
983
                        {
 
984
                                methodBodies.Position = offset;
 
985
                                int pseudoToken = methodBodies.GetInt32AtCurrentPosition();
 
986
                                methodBodies.Write(ResolvePseudoToken(pseudoToken));
 
987
                        }
 
988
                        foreach (VTableFixups fixup in vtablefixups)
 
989
                        {
 
990
                                for (int i = 0; i < fixup.count; i++)
 
991
                                {
 
992
                                        initializedData.Position = (int)fixup.initializedDataOffset + i * fixup.SlotWidth;
 
993
                                        initializedData.Write(ResolvePseudoToken(initializedData.GetInt32AtCurrentPosition()));
 
994
                                }
 
995
                        }
 
996
                }
 
997
 
 
998
                private int GetHeaderLength()
 
999
                {
 
1000
                        return
 
1001
                                4 + // Signature
 
1002
                                2 + // MajorVersion
 
1003
                                2 + // MinorVersion
 
1004
                                4 + // Reserved
 
1005
                                4 + // ImageRuntimeVersion Length
 
1006
                                StringToPaddedUTF8Length(asm.ImageRuntimeVersion) +
 
1007
                                2 + // Flags
 
1008
                                2 + // Streams
 
1009
                                4 + // #~ Offset
 
1010
                                4 + // #~ Size
 
1011
                                4 + // StringToPaddedUTF8Length("#~")
 
1012
                                4 + // #Strings Offset
 
1013
                                4 + // #Strings Size
 
1014
                                12 + // StringToPaddedUTF8Length("#Strings")
 
1015
                                4 + // #US Offset
 
1016
                                4 + // #US Size
 
1017
                                4 + // StringToPaddedUTF8Length("#US")
 
1018
                                4 + // #GUID Offset
 
1019
                                4 + // #GUID Size
 
1020
                                8 + // StringToPaddedUTF8Length("#GUID")
 
1021
                                (Blobs.IsEmpty ? 0 :
 
1022
                                (
 
1023
                                4 + // #Blob Offset
 
1024
                                4 + // #Blob Size
 
1025
                                8   // StringToPaddedUTF8Length("#Blob")
 
1026
                                ));
 
1027
                }
 
1028
 
 
1029
                internal int MetadataLength
 
1030
                {
 
1031
                        get
 
1032
                        {
 
1033
                                return GetHeaderLength() + (Blobs.IsEmpty ? 0 : Blobs.Length) + Tables.Length + Strings.Length + UserStrings.Length + Guids.Length;
 
1034
                        }
 
1035
                }
 
1036
 
 
1037
                internal void WriteMetadata(MetadataWriter mw)
 
1038
                {
 
1039
                        mw.Write(0x424A5342);                   // Signature ("BSJB")
 
1040
                        mw.Write((ushort)1);                    // MajorVersion
 
1041
                        mw.Write((ushort)1);                    // MinorVersion
 
1042
                        mw.Write(0);                                    // Reserved
 
1043
                        byte[] version = StringToPaddedUTF8(asm.ImageRuntimeVersion);
 
1044
                        mw.Write(version.Length);               // Length
 
1045
                        mw.Write(version);
 
1046
                        mw.Write((ushort)0);                    // Flags
 
1047
                        // #Blob is the only optional heap
 
1048
                        if (Blobs.IsEmpty)
 
1049
                        {
 
1050
                                mw.Write((ushort)4);            // Streams
 
1051
                        }
 
1052
                        else
 
1053
                        {
 
1054
                                mw.Write((ushort)5);            // Streams
 
1055
                        }
 
1056
 
 
1057
                        int offset = GetHeaderLength();
 
1058
 
 
1059
                        // Streams
 
1060
                        mw.Write(offset);                               // Offset
 
1061
                        mw.Write(Tables.Length);                // Size
 
1062
                        mw.Write(StringToPaddedUTF8("#~"));
 
1063
                        offset += Tables.Length;
 
1064
 
 
1065
                        mw.Write(offset);                               // Offset
 
1066
                        mw.Write(Strings.Length);               // Size
 
1067
                        mw.Write(StringToPaddedUTF8("#Strings"));
 
1068
                        offset += Strings.Length;
 
1069
 
 
1070
                        mw.Write(offset);                               // Offset
 
1071
                        mw.Write(UserStrings.Length);   // Size
 
1072
                        mw.Write(StringToPaddedUTF8("#US"));
 
1073
                        offset += UserStrings.Length;
 
1074
 
 
1075
                        mw.Write(offset);                               // Offset
 
1076
                        mw.Write(Guids.Length);                 // Size
 
1077
                        mw.Write(StringToPaddedUTF8("#GUID"));
 
1078
                        offset += Guids.Length;
 
1079
 
 
1080
                        if (!Blobs.IsEmpty)
 
1081
                        {
 
1082
                                mw.Write(offset);                               // Offset
 
1083
                                mw.Write(Blobs.Length);                 // Size
 
1084
                                mw.Write(StringToPaddedUTF8("#Blob"));
 
1085
                        }
 
1086
 
 
1087
                        Tables.Write(mw);
 
1088
                        Strings.Write(mw);
 
1089
                        UserStrings.Write(mw);
 
1090
                        Guids.Write(mw);
 
1091
                        if (!Blobs.IsEmpty)
 
1092
                        {
 
1093
                                Blobs.Write(mw);
 
1094
                        }
 
1095
                }
 
1096
 
 
1097
                private static int StringToPaddedUTF8Length(string str)
 
1098
                {
 
1099
                        return (System.Text.Encoding.UTF8.GetByteCount(str) + 4) & ~3;
 
1100
                }
 
1101
 
 
1102
                private static byte[] StringToPaddedUTF8(string str)
 
1103
                {
 
1104
                        byte[] buf = new byte[(System.Text.Encoding.UTF8.GetByteCount(str) + 4) & ~3];
 
1105
                        System.Text.Encoding.UTF8.GetBytes(str, 0, str.Length, buf, 0);
 
1106
                        return buf;
 
1107
                }
 
1108
 
 
1109
                internal override void ExportTypes(int fileToken, ModuleBuilder manifestModule)
 
1110
                {
 
1111
                        manifestModule.ExportTypes(types.ToArray(), fileToken);
 
1112
                }
 
1113
 
 
1114
                internal void ExportTypes(Type[] types, int fileToken)
 
1115
                {
 
1116
                        Dictionary<Type, int> declaringTypes = new Dictionary<Type, int>();
 
1117
                        foreach (Type type in types)
 
1118
                        {
 
1119
                                if (!type.IsModulePseudoType && IsVisible(type))
 
1120
                                {
 
1121
                                        ExportedTypeTable.Record rec = new ExportedTypeTable.Record();
 
1122
                                        rec.Flags = (int)type.Attributes;
 
1123
                                        // LAMESPEC ECMA says that TypeDefId is a row index, but it should be a token
 
1124
                                        rec.TypeDefId = type.MetadataToken;
 
1125
                                        rec.TypeName = this.Strings.Add(type.__Name);
 
1126
                                        string ns = type.__Namespace;
 
1127
                                        rec.TypeNamespace = ns == null ? 0 : this.Strings.Add(ns);
 
1128
                                        if (type.IsNested)
 
1129
                                        {
 
1130
                                                rec.Implementation = declaringTypes[type.DeclaringType];
 
1131
                                        }
 
1132
                                        else
 
1133
                                        {
 
1134
                                                rec.Implementation = fileToken;
 
1135
                                        }
 
1136
                                        int exportTypeToken = 0x27000000 | this.ExportedType.AddRecord(rec);
 
1137
                                        declaringTypes.Add(type, exportTypeToken);
 
1138
                                }
 
1139
                        }
 
1140
                }
 
1141
 
 
1142
                private static bool IsVisible(Type type)
 
1143
                {
 
1144
                        // NOTE this is not the same as Type.IsVisible, because that doesn't take into account family access
 
1145
                        return type.IsPublic || ((type.IsNestedFamily || type.IsNestedFamORAssem || type.IsNestedPublic) && IsVisible(type.DeclaringType));
 
1146
                }
 
1147
 
 
1148
                internal void AddConstant(int parentToken, object defaultValue)
 
1149
                {
 
1150
                        ConstantTable.Record rec = new ConstantTable.Record();
 
1151
                        rec.Parent = parentToken;
 
1152
                        ByteBuffer val = new ByteBuffer(16);
 
1153
                        if (defaultValue == null)
 
1154
                        {
 
1155
                                rec.Type = Signature.ELEMENT_TYPE_CLASS;
 
1156
                                val.Write((int)0);
 
1157
                        }
 
1158
                        else if (defaultValue is bool)
 
1159
                        {
 
1160
                                rec.Type = Signature.ELEMENT_TYPE_BOOLEAN;
 
1161
                                val.Write((bool)defaultValue ? (byte)1 : (byte)0);
 
1162
                        }
 
1163
                        else if (defaultValue is char)
 
1164
                        {
 
1165
                                rec.Type = Signature.ELEMENT_TYPE_CHAR;
 
1166
                                val.Write((char)defaultValue);
 
1167
                        }
 
1168
                        else if (defaultValue is sbyte)
 
1169
                        {
 
1170
                                rec.Type = Signature.ELEMENT_TYPE_I1;
 
1171
                                val.Write((sbyte)defaultValue);
 
1172
                        }
 
1173
                        else if (defaultValue is byte)
 
1174
                        {
 
1175
                                rec.Type = Signature.ELEMENT_TYPE_U1;
 
1176
                                val.Write((byte)defaultValue);
 
1177
                        }
 
1178
                        else if (defaultValue is short)
 
1179
                        {
 
1180
                                rec.Type = Signature.ELEMENT_TYPE_I2;
 
1181
                                val.Write((short)defaultValue);
 
1182
                        }
 
1183
                        else if (defaultValue is ushort)
 
1184
                        {
 
1185
                                rec.Type = Signature.ELEMENT_TYPE_U2;
 
1186
                                val.Write((ushort)defaultValue);
 
1187
                        }
 
1188
                        else if (defaultValue is int)
 
1189
                        {
 
1190
                                rec.Type = Signature.ELEMENT_TYPE_I4;
 
1191
                                val.Write((int)defaultValue);
 
1192
                        }
 
1193
                        else if (defaultValue is uint)
 
1194
                        {
 
1195
                                rec.Type = Signature.ELEMENT_TYPE_U4;
 
1196
                                val.Write((uint)defaultValue);
 
1197
                        }
 
1198
                        else if (defaultValue is long)
 
1199
                        {
 
1200
                                rec.Type = Signature.ELEMENT_TYPE_I8;
 
1201
                                val.Write((long)defaultValue);
 
1202
                        }
 
1203
                        else if (defaultValue is ulong)
 
1204
                        {
 
1205
                                rec.Type = Signature.ELEMENT_TYPE_U8;
 
1206
                                val.Write((ulong)defaultValue);
 
1207
                        }
 
1208
                        else if (defaultValue is float)
 
1209
                        {
 
1210
                                rec.Type = Signature.ELEMENT_TYPE_R4;
 
1211
                                val.Write((float)defaultValue);
 
1212
                        }
 
1213
                        else if (defaultValue is double)
 
1214
                        {
 
1215
                                rec.Type = Signature.ELEMENT_TYPE_R8;
 
1216
                                val.Write((double)defaultValue);
 
1217
                        }
 
1218
                        else if (defaultValue is string)
 
1219
                        {
 
1220
                                rec.Type = Signature.ELEMENT_TYPE_STRING;
 
1221
                                foreach (char c in (string)defaultValue)
 
1222
                                {
 
1223
                                        val.Write(c);
 
1224
                                }
 
1225
                        }
 
1226
                        else if (defaultValue is DateTime)
 
1227
                        {
 
1228
                                rec.Type = Signature.ELEMENT_TYPE_I8;
 
1229
                                val.Write(((DateTime)defaultValue).Ticks);
 
1230
                        }
 
1231
                        else
 
1232
                        {
 
1233
                                throw new ArgumentException();
 
1234
                        }
 
1235
                        rec.Value = this.Blobs.Add(val);
 
1236
                        this.Constant.AddRecord(rec);
 
1237
                }
 
1238
 
 
1239
                ModuleBuilder ITypeOwner.ModuleBuilder
 
1240
                {
 
1241
                        get { return this; }
 
1242
                }
 
1243
 
 
1244
                internal override Type ResolveType(int metadataToken, IGenericContext context)
 
1245
                {
 
1246
                        if (metadataToken >> 24 != TypeDefTable.Index)
 
1247
                        {
 
1248
                                throw new NotImplementedException();
 
1249
                        }
 
1250
                        return types[(metadataToken & 0xFFFFFF) - 1];
 
1251
                }
 
1252
 
 
1253
                public override MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
 
1254
                {
 
1255
                        if (genericTypeArguments != null || genericMethodArguments != null)
 
1256
                        {
 
1257
                                throw new NotImplementedException();
 
1258
                        }
 
1259
                        // this method is inefficient, but since it isn't used we don't care
 
1260
                        if ((metadataToken >> 24) == MemberRefTable.Index)
 
1261
                        {
 
1262
                                foreach (KeyValuePair<MemberRefKey, int> kv in importedMemberRefs)
 
1263
                                {
 
1264
                                        if (kv.Value == metadataToken)
 
1265
                                        {
 
1266
                                                return kv.Key.LookupMethod();
 
1267
                                        }
 
1268
                                }
 
1269
                        }
 
1270
                        // HACK if we're given a SymbolToken, we need to convert back
 
1271
                        if ((metadataToken & 0xFF000000) == 0x06000000)
 
1272
                        {
 
1273
                                metadataToken = -(metadataToken & 0x00FFFFFF);
 
1274
                        }
 
1275
                        foreach (Type type in types)
 
1276
                        {
 
1277
                                MethodBase method = ((TypeBuilder)type).LookupMethod(metadataToken);
 
1278
                                if (method != null)
 
1279
                                {
 
1280
                                        return method;
 
1281
                                }
 
1282
                        }
 
1283
                        return ((TypeBuilder)moduleType).LookupMethod(metadataToken);
 
1284
                }
 
1285
 
 
1286
                public override FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
 
1287
                {
 
1288
                        throw new NotImplementedException();
 
1289
                }
 
1290
 
 
1291
                public override MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
 
1292
                {
 
1293
                        throw new NotImplementedException();
 
1294
                }
 
1295
 
 
1296
                public override string ResolveString(int metadataToken)
 
1297
                {
 
1298
                        throw new NotImplementedException();
 
1299
                }
 
1300
 
 
1301
                public override string FullyQualifiedName
 
1302
                {
 
1303
                        get { return Path.GetFullPath(Path.Combine(asm.dir, fileName)); }
 
1304
                }
 
1305
 
 
1306
                public override string Name
 
1307
                {
 
1308
                        get { return fileName; }
 
1309
                }
 
1310
 
 
1311
                public override Guid ModuleVersionId
 
1312
                {
 
1313
                        get { return mvid; }
 
1314
                }
 
1315
 
 
1316
                public void __SetModuleVersionId(Guid guid)
 
1317
                {
 
1318
                        mvid = guid;
 
1319
                }
 
1320
 
 
1321
                public override Type[] __ResolveOptionalParameterTypes(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments, out CustomModifiers[] customModifiers)
 
1322
                {
 
1323
                        throw new NotImplementedException();
 
1324
                }
 
1325
 
 
1326
                public override string ScopeName
 
1327
                {
 
1328
                        get { return moduleName; }
 
1329
                }
 
1330
 
 
1331
                public ISymbolWriter GetSymWriter()
 
1332
                {
 
1333
                        return symbolWriter;
 
1334
                }
 
1335
 
 
1336
                public void DefineUnmanagedResource(string resourceFileName)
 
1337
                {
 
1338
                        // This method reads the specified resource file (Win32 .res file) and converts it into the appropriate format and embeds it in the .rsrc section,
 
1339
                        // also setting the Resource Directory entry.
 
1340
                        unmanagedResources = new ResourceSection();
 
1341
                        unmanagedResources.ExtractResources(System.IO.File.ReadAllBytes(resourceFileName));
 
1342
                }
 
1343
 
 
1344
                public bool IsTransient()
 
1345
                {
 
1346
                        return false;
 
1347
                }
 
1348
 
 
1349
                public void SetUserEntryPoint(MethodInfo entryPoint)
 
1350
                {
 
1351
                        int token = entryPoint.MetadataToken;
 
1352
                        if (token < 0)
 
1353
                        {
 
1354
                                token = -token | 0x06000000;
 
1355
                        }
 
1356
                        if (symbolWriter != null)
 
1357
                        {
 
1358
                                symbolWriter.SetUserEntryPoint(new SymbolToken(token));
 
1359
                        }
 
1360
                }
 
1361
 
 
1362
                public StringToken GetStringConstant(string str)
 
1363
                {
 
1364
                        return new StringToken(this.UserStrings.Add(str) | (0x70 << 24));
 
1365
                }
 
1366
 
 
1367
                public SignatureToken GetSignatureToken(SignatureHelper sigHelper)
 
1368
                {
 
1369
                        return new SignatureToken(this.StandAloneSig.FindOrAddRecord(this.Blobs.Add(sigHelper.GetSignature(this))) | (StandAloneSigTable.Index << 24));
 
1370
                }
 
1371
 
 
1372
                public SignatureToken GetSignatureToken(byte[] sigBytes, int sigLength)
 
1373
                {
 
1374
                        return new SignatureToken(this.StandAloneSig.FindOrAddRecord(this.Blobs.Add(ByteBuffer.Wrap(sigBytes, sigLength))) | (StandAloneSigTable.Index << 24));
 
1375
                }
 
1376
 
 
1377
                public MethodInfo GetArrayMethod(Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
 
1378
                {
 
1379
                        return new ArrayMethod(this, arrayClass, methodName, callingConvention, returnType, parameterTypes);
 
1380
                }
 
1381
 
 
1382
                public MethodToken GetArrayMethodToken(Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
 
1383
                {
 
1384
                        return GetMethodToken(GetArrayMethod(arrayClass, methodName, callingConvention, returnType, parameterTypes));
 
1385
                }
 
1386
 
 
1387
                internal override Type GetModuleType()
 
1388
                {
 
1389
                        return moduleType;
 
1390
                }
 
1391
 
 
1392
                internal override IKVM.Reflection.Reader.ByteReader GetBlob(int blobIndex)
 
1393
                {
 
1394
                        return Blobs.GetBlob(blobIndex);
 
1395
                }
 
1396
 
 
1397
                internal int GetSignatureBlobIndex(Signature sig)
 
1398
                {
 
1399
                        ByteBuffer bb = new ByteBuffer(16);
 
1400
                        sig.WriteSig(this, bb);
 
1401
                        return this.Blobs.Add(bb);
 
1402
                }
 
1403
 
 
1404
                // non-standard API
 
1405
                public new long __ImageBase
 
1406
                {
 
1407
                        get { return imageBaseAddress; }
 
1408
                        set { imageBaseAddress = value; }
 
1409
                }
 
1410
 
 
1411
                protected override long GetImageBaseImpl()
 
1412
                {
 
1413
                        return imageBaseAddress;
 
1414
                }
 
1415
 
 
1416
                public new long __StackReserve
 
1417
                {
 
1418
                        get { return stackReserve; }
 
1419
                        set { stackReserve = value; }
 
1420
                }
 
1421
 
 
1422
                protected override long GetStackReserveImpl()
 
1423
                {
 
1424
                        return stackReserve;
 
1425
                }
 
1426
 
 
1427
                [Obsolete("Use __StackReserve property.")]
 
1428
                public void __SetStackReserve(long stackReserve)
 
1429
                {
 
1430
                        __StackReserve = stackReserve;
 
1431
                }
 
1432
 
 
1433
                internal ulong GetStackReserve(ulong defaultValue)
 
1434
                {
 
1435
                        return stackReserve == -1 ? defaultValue : (ulong)stackReserve;
 
1436
                }
 
1437
 
 
1438
                public new int __FileAlignment
 
1439
                {
 
1440
                        get { return fileAlignment; }
 
1441
                        set { fileAlignment = value; }
 
1442
                }
 
1443
 
 
1444
                protected override int GetFileAlignmentImpl()
 
1445
                {
 
1446
                        return fileAlignment;
 
1447
                }
 
1448
 
 
1449
                public new DllCharacteristics __DllCharacteristics
 
1450
                {
 
1451
                        get { return dllCharacteristics; }
 
1452
                        set { dllCharacteristics = value; }
 
1453
                }
 
1454
 
 
1455
                protected override DllCharacteristics GetDllCharacteristicsImpl()
 
1456
                {
 
1457
                        return dllCharacteristics;
 
1458
                }
 
1459
 
 
1460
                public override int MDStreamVersion
 
1461
                {
 
1462
                        get { return asm.mdStreamVersion; }
 
1463
                }
 
1464
 
 
1465
                private int AddTypeRefByName(int resolutionScope, string ns, string name)
 
1466
                {
 
1467
                        TypeRefTable.Record rec = new TypeRefTable.Record();
 
1468
                        rec.ResolutionScope = resolutionScope;
 
1469
                        rec.TypeName = this.Strings.Add(name);
 
1470
                        rec.TypeNameSpace = ns == null ? 0 : this.Strings.Add(ns);
 
1471
                        return 0x01000000 | this.TypeRef.AddRecord(rec);
 
1472
                }
 
1473
 
 
1474
                public void __Save(PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
 
1475
                {
 
1476
                        SaveImpl(null, portableExecutableKind, imageFileMachine);
 
1477
                }
 
1478
 
 
1479
                public void __Save(Stream stream, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
 
1480
                {
 
1481
                        if (!stream.CanRead || !stream.CanWrite || !stream.CanSeek || stream.Position != 0)
 
1482
                        {
 
1483
                                throw new ArgumentException("Stream must support read/write/seek and current position must be zero.", "stream");
 
1484
                        }
 
1485
                        SaveImpl(stream, portableExecutableKind, imageFileMachine);
 
1486
                }
 
1487
 
 
1488
                private void SaveImpl(Stream streamOrNull, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
 
1489
                {
 
1490
                        SetIsSaved();
 
1491
                        PopulatePropertyAndEventTables();
 
1492
                        IList<CustomAttributeData> attributes = asm.GetCustomAttributesData(null);
 
1493
                        if (attributes.Count > 0)
 
1494
                        {
 
1495
                                int mscorlib = ImportAssemblyRef(universe.Mscorlib);
 
1496
                                int[] placeholderTokens = new int[4];
 
1497
                                string[] placeholderTypeNames = new string[] { "AssemblyAttributesGoHere", "AssemblyAttributesGoHereM", "AssemblyAttributesGoHereS", "AssemblyAttributesGoHereSM" };
 
1498
                                foreach (CustomAttributeData cad in attributes)
 
1499
                                {
 
1500
                                        int index;
 
1501
                                        if (cad.Constructor.DeclaringType.BaseType == universe.System_Security_Permissions_CodeAccessSecurityAttribute)
 
1502
                                        {
 
1503
                                                if (cad.Constructor.DeclaringType.IsAllowMultipleCustomAttribute)
 
1504
                                                {
 
1505
                                                        index = 3;
 
1506
                                                }
 
1507
                                                else
 
1508
                                                {
 
1509
                                                        index = 2;
 
1510
                                                }
 
1511
                                        }
 
1512
                                        else if (cad.Constructor.DeclaringType.IsAllowMultipleCustomAttribute)
 
1513
                                        {
 
1514
                                                index = 1;
 
1515
                                        }
 
1516
                                        else
 
1517
                                        {
 
1518
                                                index = 0;
 
1519
                                        }
 
1520
                                        if (placeholderTokens[index] == 0)
 
1521
                                        {
 
1522
                                                // we manually add a TypeRef without looking it up in mscorlib, because Mono and Silverlight's mscorlib don't have these types
 
1523
                                                placeholderTokens[index] = AddTypeRefByName(mscorlib, "System.Runtime.CompilerServices", placeholderTypeNames[index]);
 
1524
                                        }
 
1525
                                        SetCustomAttribute(placeholderTokens[index], cad.__ToBuilder());
 
1526
                                }
 
1527
                        }
 
1528
                        FillAssemblyRefTable();
 
1529
                        EmitResources();
 
1530
                        ModuleWriter.WriteModule(null, null, this, PEFileKinds.Dll, portableExecutableKind, imageFileMachine, unmanagedResources, 0, streamOrNull);
 
1531
                }
 
1532
 
 
1533
                public void __AddAssemblyReference(AssemblyName assemblyName)
 
1534
                {
 
1535
                        __AddAssemblyReference(assemblyName, null);
 
1536
                }
 
1537
 
 
1538
                public void __AddAssemblyReference(AssemblyName assemblyName, Assembly assembly)
 
1539
                {
 
1540
                        if (referencedAssemblyNames == null)
 
1541
                        {
 
1542
                                referencedAssemblyNames = new List<AssemblyName>();
 
1543
                        }
 
1544
                        referencedAssemblyNames.Add((AssemblyName)assemblyName.Clone());
 
1545
                        int token = FindOrAddAssemblyRef(assemblyName, true);
 
1546
                        if (assembly != null)
 
1547
                        {
 
1548
                                referencedAssemblies.Add(assembly, token);
 
1549
                        }
 
1550
                }
 
1551
 
 
1552
                public override AssemblyName[] __GetReferencedAssemblies()
 
1553
                {
 
1554
                        List<AssemblyName> list = new List<AssemblyName>();
 
1555
                        if (referencedAssemblyNames != null)
 
1556
                        {
 
1557
                                foreach (AssemblyName name in referencedAssemblyNames)
 
1558
                                {
 
1559
                                        if (!list.Contains(name))
 
1560
                                        {
 
1561
                                                list.Add(name);
 
1562
                                        }
 
1563
                                }
 
1564
                        }
 
1565
                        foreach (Assembly asm in referencedAssemblies.Keys)
 
1566
                        {
 
1567
                                AssemblyName name = asm.GetName();
 
1568
                                if (!list.Contains(name))
 
1569
                                {
 
1570
                                        list.Add(name);
 
1571
                                }
 
1572
                        }
 
1573
                        return list.ToArray();
 
1574
                }
 
1575
 
 
1576
                public void __AddModuleReference(string module)
 
1577
                {
 
1578
                        this.ModuleRef.FindOrAddRecord(module == null ? 0 : this.Strings.Add(module));
 
1579
                }
 
1580
 
 
1581
                public override string[] __GetReferencedModules()
 
1582
                {
 
1583
                        string[] arr = new string[this.ModuleRef.RowCount];
 
1584
                        for (int i = 0; i < arr.Length; i++)
 
1585
                        {
 
1586
                                arr[i] = this.Strings.Find(this.ModuleRef.records[i]);
 
1587
                        }
 
1588
                        return arr;
 
1589
                }
 
1590
 
 
1591
                public override Type[] __GetReferencedTypes()
 
1592
                {
 
1593
                        List<Type> list = new List<Type>();
 
1594
                        foreach (KeyValuePair<Type, int> kv in typeTokens)
 
1595
                        {
 
1596
                                if (kv.Value >> 24 == TypeRefTable.Index)
 
1597
                                {
 
1598
                                        list.Add(kv.Key);
 
1599
                                }
 
1600
                        }
 
1601
                        return list.ToArray();
 
1602
                }
 
1603
 
 
1604
                public override Type[] __GetExportedTypes()
 
1605
                {
 
1606
                        throw new NotImplementedException();
 
1607
                }
 
1608
 
 
1609
                public int __AddModule(int flags, string name, byte[] hash)
 
1610
                {
 
1611
                        FileTable.Record file = new FileTable.Record();
 
1612
                        file.Flags = flags;
 
1613
                        file.Name = this.Strings.Add(name);
 
1614
                        file.HashValue = this.Blobs.Add(ByteBuffer.Wrap(hash));
 
1615
                        return 0x26000000 + this.File.AddRecord(file);
 
1616
                }
 
1617
 
 
1618
                public int __AddManifestResource(int offset, ResourceAttributes flags, string name, int implementation)
 
1619
                {
 
1620
                        ManifestResourceTable.Record res = new ManifestResourceTable.Record();
 
1621
                        res.Offset = offset;
 
1622
                        res.Flags = (int)flags;
 
1623
                        res.Name = this.Strings.Add(name);
 
1624
                        res.Implementation = implementation;
 
1625
                        return 0x28000000 + this.ManifestResource.AddRecord(res);
 
1626
                }
 
1627
 
 
1628
                public void __SetCustomAttributeFor(int token, CustomAttributeBuilder customBuilder)
 
1629
                {
 
1630
                        SetCustomAttribute(token, customBuilder);
 
1631
                }
 
1632
 
 
1633
                public RelativeVirtualAddress __AddVTableFixups(MethodBuilder[] methods, int type)
 
1634
                {
 
1635
                        initializedData.Align(8);
 
1636
                        VTableFixups fixups;
 
1637
                        fixups.initializedDataOffset = (uint)initializedData.Position;
 
1638
                        fixups.count = (ushort)methods.Length;
 
1639
                        fixups.type = (ushort)type;
 
1640
                        foreach (MethodBuilder mb in methods)
 
1641
                        {
 
1642
                                initializedData.Write(mb.MetadataToken);
 
1643
                                if (fixups.SlotWidth == 8)
 
1644
                                {
 
1645
                                        initializedData.Write(0);
 
1646
                                }
 
1647
                        }
 
1648
                        vtablefixups.Add(fixups);
 
1649
                        return new RelativeVirtualAddress(fixups.initializedDataOffset);
 
1650
                }
 
1651
 
 
1652
                public void __AddUnmanagedExportStub(string name, int ordinal, RelativeVirtualAddress rva)
 
1653
                {
 
1654
                        AddUnmanagedExport(name, ordinal, null, rva);
 
1655
                }
 
1656
 
 
1657
                internal void AddUnmanagedExport(string name, int ordinal, MethodBuilder methodBuilder, RelativeVirtualAddress rva)
 
1658
                {
 
1659
                        UnmanagedExport export;
 
1660
                        export.name = name;
 
1661
                        export.ordinal = ordinal;
 
1662
                        export.mb = methodBuilder;
 
1663
                        export.rva = rva;
 
1664
                        unmanagedExports.Add(export);
 
1665
                }
 
1666
 
 
1667
                internal void SetInterfaceImplementationCustomAttribute(TypeBuilder typeBuilder, Type interfaceType, CustomAttributeBuilder cab)
 
1668
                {
 
1669
                        // NOTE since interfaceimpls are extremely common and custom attributes on them are extremely rare,
 
1670
                        // we store (and resolve) the custom attributes in such away as to avoid impacting the common case performance
 
1671
                        if (interfaceImplCustomAttributes == null)
 
1672
                        {
 
1673
                                interfaceImplCustomAttributes = new List<InterfaceImplCustomAttribute>();
 
1674
                        }
 
1675
                        InterfaceImplCustomAttribute rec;
 
1676
                        rec.type = typeBuilder.MetadataToken;
 
1677
                        int token = GetTypeToken(interfaceType).Token;
 
1678
                        switch (token >> 24)
 
1679
                        {
 
1680
                                case TypeDefTable.Index:
 
1681
                                        token = (token & 0xFFFFFF) << 2 | 0;
 
1682
                                        break;
 
1683
                                case TypeRefTable.Index:
 
1684
                                        token = (token & 0xFFFFFF) << 2 | 1;
 
1685
                                        break;
 
1686
                                case TypeSpecTable.Index:
 
1687
                                        token = (token & 0xFFFFFF) << 2 | 2;
 
1688
                                        break;
 
1689
                                default:
 
1690
                                        throw new InvalidOperationException();
 
1691
                        }
 
1692
                        rec.interfaceType = token;
 
1693
                        rec.pseudoToken = AllocPseudoToken();
 
1694
                        interfaceImplCustomAttributes.Add(rec);
 
1695
                        SetCustomAttribute(rec.pseudoToken, cab);
 
1696
                }
 
1697
 
 
1698
                internal void ResolveInterfaceImplPseudoTokens()
 
1699
                {
 
1700
                        if (interfaceImplCustomAttributes != null)
 
1701
                        {
 
1702
                                foreach (InterfaceImplCustomAttribute rec in interfaceImplCustomAttributes)
 
1703
                                {
 
1704
                                        for (int i = 0; i < InterfaceImpl.records.Length; i++)
 
1705
                                        {
 
1706
                                                if (InterfaceImpl.records[i].Class == rec.type && InterfaceImpl.records[i].Interface == rec.interfaceType)
 
1707
                                                {
 
1708
                                                        RegisterTokenFixup(rec.pseudoToken, (InterfaceImplTable.Index << 24) | (i + 1));
 
1709
                                                        break;
 
1710
                                                }
 
1711
                                        }
 
1712
                                }
 
1713
                        }
 
1714
                }
 
1715
 
 
1716
                internal void FixupPseudoToken(ref int token)
 
1717
                {
 
1718
                        if (IsPseudoToken(token))
 
1719
                        {
 
1720
                                token = ResolvePseudoToken(token);
 
1721
                        }
 
1722
                }
 
1723
 
 
1724
                internal void SetIsSaved()
 
1725
                {
 
1726
                        if (saved)
 
1727
                        {
 
1728
                                throw new InvalidOperationException();
 
1729
                        }
 
1730
                        saved = true;
 
1731
                }
 
1732
 
 
1733
                internal bool IsSaved
 
1734
                {
 
1735
                        get { return saved; }
 
1736
                }
 
1737
 
 
1738
                internal override string GetString(int index)
 
1739
                {
 
1740
                        return this.Strings.Find(index);
 
1741
                }
 
1742
        }
 
1743
 
 
1744
        struct UnmanagedExport
 
1745
        {
 
1746
                internal string name;
 
1747
                internal int ordinal;
 
1748
                internal RelativeVirtualAddress rva;
 
1749
                internal MethodBuilder mb;
 
1750
        }
 
1751
 
 
1752
        public struct RelativeVirtualAddress
 
1753
        {
 
1754
                internal readonly uint initializedDataOffset;
 
1755
 
 
1756
                internal RelativeVirtualAddress(uint initializedDataOffset)
 
1757
                {
 
1758
                        this.initializedDataOffset = initializedDataOffset;
 
1759
                }
 
1760
 
 
1761
                public static RelativeVirtualAddress operator +(RelativeVirtualAddress rva, int offset)
 
1762
                {
 
1763
                        return new RelativeVirtualAddress(rva.initializedDataOffset + (uint)offset);
 
1764
                }
 
1765
        }
 
1766
 
 
1767
        class ArrayMethod : MethodInfo
 
1768
        {
 
1769
                private readonly Module module;
 
1770
                private readonly Type arrayClass;
 
1771
                private readonly string methodName;
 
1772
                private readonly CallingConventions callingConvention;
 
1773
                private readonly Type returnType;
 
1774
                protected readonly Type[] parameterTypes;
 
1775
                private MethodSignature methodSignature;
 
1776
 
 
1777
                internal ArrayMethod(Module module, Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
 
1778
                {
 
1779
                        this.module = module;
 
1780
                        this.arrayClass = arrayClass;
 
1781
                        this.methodName = methodName;
 
1782
                        this.callingConvention = callingConvention;
 
1783
                        this.returnType = returnType ?? module.universe.System_Void;
 
1784
                        this.parameterTypes = Util.Copy(parameterTypes);
 
1785
                }
 
1786
 
 
1787
                public override MethodBody GetMethodBody()
 
1788
                {
 
1789
                        throw new InvalidOperationException();
 
1790
                }
 
1791
 
 
1792
                public override int __MethodRVA
 
1793
                {
 
1794
                        get { throw new InvalidOperationException(); }
 
1795
                }
 
1796
 
 
1797
                public override MethodImplAttributes GetMethodImplementationFlags()
 
1798
                {
 
1799
                        throw new NotSupportedException();
 
1800
                }
 
1801
 
 
1802
                public override ParameterInfo[] GetParameters()
 
1803
                {
 
1804
                        throw new NotSupportedException();
 
1805
                }
 
1806
 
 
1807
                internal override int ImportTo(ModuleBuilder module)
 
1808
                {
 
1809
                        return module.ImportMethodOrField(arrayClass, methodName, MethodSignature);
 
1810
                }
 
1811
 
 
1812
                public override MethodAttributes Attributes
 
1813
                {
 
1814
                        get { throw new NotSupportedException(); }
 
1815
                }
 
1816
 
 
1817
                public override CallingConventions CallingConvention
 
1818
                {
 
1819
                        get { return callingConvention; }
 
1820
                }
 
1821
 
 
1822
                public override Type DeclaringType
 
1823
                {
 
1824
                        get { return arrayClass; }
 
1825
                }
 
1826
 
 
1827
                internal override MethodSignature MethodSignature
 
1828
                {
 
1829
                        get
 
1830
                        {
 
1831
                                if (methodSignature == null)
 
1832
                                {
 
1833
                                        methodSignature = MethodSignature.MakeFromBuilder(returnType, parameterTypes, new PackedCustomModifiers(), callingConvention, 0);
 
1834
                                }
 
1835
                                return methodSignature;
 
1836
                        }
 
1837
                }
 
1838
 
 
1839
                public override Module Module
 
1840
                {
 
1841
                        // FXBUG like .NET, we return the module that GetArrayMethod was called on, not the module associated with the array type
 
1842
                        get { return module; }
 
1843
                }
 
1844
 
 
1845
                public override string Name
 
1846
                {
 
1847
                        get { return methodName; }
 
1848
                }
 
1849
 
 
1850
                internal override int ParameterCount
 
1851
                {
 
1852
                        get { return parameterTypes.Length; }
 
1853
                }
 
1854
 
 
1855
                public override ParameterInfo ReturnParameter
 
1856
                {
 
1857
                        // FXBUG like .NET, we throw NotImplementedException
 
1858
                        get { throw new NotImplementedException(); }
 
1859
                }
 
1860
 
 
1861
                public override Type ReturnType
 
1862
                {
 
1863
                        get { return returnType; }
 
1864
                }
 
1865
 
 
1866
                internal override bool HasThis
 
1867
                {
 
1868
                        get { return (callingConvention & (CallingConventions.HasThis | CallingConventions.ExplicitThis)) == CallingConventions.HasThis; }
 
1869
                }
 
1870
 
 
1871
                internal override int GetCurrentToken()
 
1872
                {
 
1873
                        return this.MetadataToken;
 
1874
                }
 
1875
 
 
1876
                internal override bool IsBaked
 
1877
                {
 
1878
                        get { return arrayClass.IsBaked; }
 
1879
                }
 
1880
        }
 
1881
}