2
Copyright (C) 2008-2012 Jeroen Frijters
4
This software is provided 'as-is', without any express or implied
5
warranty. In no event will the authors be held liable for any damages
6
arising from the use of this software.
8
Permission is granted to anyone to use this software for any purpose,
9
including commercial applications, and to alter it and redistribute it
10
freely, subject to the following restrictions:
12
1. The origin of this software must not be misrepresented; you must not
13
claim that you wrote the original software. If you use this software
14
in a product, an acknowledgment in the product documentation would be
15
appreciated but is not required.
16
2. Altered source versions must be plainly marked as such, and must not be
17
misrepresented as being the original software.
18
3. This notice may not be removed or altered from any source distribution.
25
using System.Collections.Generic;
26
using System.Runtime.CompilerServices;
27
using IKVM.Reflection.Metadata;
28
using IKVM.Reflection.Writer;
30
namespace IKVM.Reflection.Emit
32
public sealed class FieldBuilder : FieldInfo
34
private readonly TypeBuilder typeBuilder;
35
private readonly string name;
36
private readonly int pseudoToken;
37
private FieldAttributes attribs;
38
private readonly int nameIndex;
39
private readonly int signature;
40
private readonly FieldSignature fieldSig;
42
internal FieldBuilder(TypeBuilder type, string name, Type fieldType, CustomModifiers customModifiers, FieldAttributes attribs)
44
this.typeBuilder = type;
46
this.pseudoToken = type.ModuleBuilder.AllocPseudoToken();
47
this.nameIndex = type.ModuleBuilder.Strings.Add(name);
48
this.fieldSig = FieldSignature.Create(fieldType, customModifiers);
49
ByteBuffer sig = new ByteBuffer(5);
50
fieldSig.WriteSig(this.typeBuilder.ModuleBuilder, sig);
51
this.signature = this.typeBuilder.ModuleBuilder.Blobs.Add(sig);
52
this.attribs = attribs;
53
this.typeBuilder.ModuleBuilder.Field.AddVirtualRecord();
56
public void SetConstant(object defaultValue)
58
attribs |= FieldAttributes.HasDefault;
59
typeBuilder.ModuleBuilder.AddConstant(pseudoToken, defaultValue);
62
public override object GetRawConstantValue()
64
if (!typeBuilder.IsCreated())
66
// the .NET FieldBuilder doesn't support this method
67
// (since we dont' have a different FieldInfo object after baking, we will support it once we're baked)
68
throw new NotSupportedException();
70
return typeBuilder.Module.Constant.GetRawConstantValue(typeBuilder.Module, GetCurrentToken());
73
public void __SetDataAndRVA(byte[] data)
75
SetDataAndRvaImpl(data, typeBuilder.ModuleBuilder.initializedData, 0);
78
public void __SetReadOnlyDataAndRVA(byte[] data)
80
SetDataAndRvaImpl(data, typeBuilder.ModuleBuilder.methodBodies, unchecked((int)0x80000000));
83
private void SetDataAndRvaImpl(byte[] data, ByteBuffer bb, int readonlyMarker)
85
attribs |= FieldAttributes.HasFieldRVA;
86
FieldRVATable.Record rec = new FieldRVATable.Record();
88
rec.RVA = bb.Position + readonlyMarker;
89
rec.Field = pseudoToken;
90
typeBuilder.ModuleBuilder.FieldRVA.AddRecord(rec);
94
public override void __GetDataFromRVA(byte[] data, int offset, int length)
96
throw new NotImplementedException();
99
public override int __FieldRVA
101
get { throw new NotImplementedException(); }
104
public override bool __TryGetFieldOffset(out int offset)
106
int pseudoTokenOrIndex = pseudoToken;
107
if (typeBuilder.ModuleBuilder.IsSaved)
109
pseudoTokenOrIndex = typeBuilder.ModuleBuilder.ResolvePseudoToken(pseudoToken) & 0xFFFFFF;
111
foreach (int i in this.Module.FieldLayout.Filter(pseudoTokenOrIndex))
113
offset = this.Module.FieldLayout.records[i].Offset;
120
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
122
SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
125
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
127
Universe u = this.Module.universe;
128
if (customBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_FieldOffsetAttribute)
130
customBuilder = customBuilder.DecodeBlob(this.Module.Assembly);
131
SetOffset((int)customBuilder.GetConstructorArgument(0));
133
else if (customBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_MarshalAsAttribute)
135
FieldMarshal.SetMarshalAsAttribute(typeBuilder.ModuleBuilder, pseudoToken, customBuilder);
136
attribs |= FieldAttributes.HasFieldMarshal;
138
else if (customBuilder.Constructor.DeclaringType == u.System_NonSerializedAttribute)
140
attribs |= FieldAttributes.NotSerialized;
142
else if (customBuilder.Constructor.DeclaringType == u.System_Runtime_CompilerServices_SpecialNameAttribute)
144
attribs |= FieldAttributes.SpecialName;
148
typeBuilder.ModuleBuilder.SetCustomAttribute(pseudoToken, customBuilder);
152
public void SetOffset(int iOffset)
154
FieldLayoutTable.Record rec = new FieldLayoutTable.Record();
155
rec.Offset = iOffset;
156
rec.Field = pseudoToken;
157
typeBuilder.ModuleBuilder.FieldLayout.AddRecord(rec);
160
public override FieldAttributes Attributes
162
get { return attribs; }
165
public override Type DeclaringType
167
get { return typeBuilder.IsModulePseudoType ? null : typeBuilder; }
170
public override string Name
175
public override int MetadataToken
177
get { return pseudoToken; }
180
public override Module Module
182
get { return typeBuilder.Module; }
185
public FieldToken GetToken()
187
return new FieldToken(pseudoToken);
190
internal void WriteFieldRecords(MetadataWriter mw)
192
mw.Write((short)attribs);
193
mw.WriteStringIndex(nameIndex);
194
mw.WriteBlobIndex(signature);
197
internal void FixupToken(int token)
199
typeBuilder.ModuleBuilder.RegisterTokenFixup(this.pseudoToken, token);
202
internal override FieldSignature FieldSignature
204
get { return fieldSig; }
207
internal override int ImportTo(ModuleBuilder other)
209
return other.ImportMethodOrField(typeBuilder, name, fieldSig);
212
internal override int GetCurrentToken()
214
if (typeBuilder.ModuleBuilder.IsSaved)
216
return typeBuilder.ModuleBuilder.ResolvePseudoToken(pseudoToken);
224
internal override bool IsBaked
226
get { return typeBuilder.IsBaked; }