2 Copyright (C) 2008 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.Runtime.CompilerServices;
26 using IKVM.Reflection.Metadata;
27 using IKVM.Reflection.Writer;
29 namespace IKVM.Reflection.Emit
31 public sealed class FieldBuilder : FieldInfo
33 private readonly TypeBuilder typeBuilder;
34 private readonly string name;
35 private readonly int pseudoToken;
36 private FieldAttributes attribs;
37 private readonly int nameIndex;
38 private readonly int signature;
39 private readonly FieldSignature fieldSig;
41 internal FieldBuilder(TypeBuilder type, string name, Type fieldType, CustomModifiers customModifiers, FieldAttributes attribs)
43 this.typeBuilder = type;
45 this.pseudoToken = type.ModuleBuilder.AllocPseudoToken();
46 this.nameIndex = type.ModuleBuilder.Strings.Add(name);
47 this.fieldSig = FieldSignature.Create(fieldType, customModifiers);
48 ByteBuffer sig = new ByteBuffer(5);
49 fieldSig.WriteSig(this.typeBuilder.ModuleBuilder, sig);
50 this.signature = this.typeBuilder.ModuleBuilder.Blobs.Add(sig);
51 this.attribs = attribs;
52 this.typeBuilder.ModuleBuilder.Field.AddVirtualRecord();
55 public void SetConstant(object defaultValue)
57 attribs |= FieldAttributes.HasDefault;
58 typeBuilder.ModuleBuilder.AddConstant(pseudoToken, defaultValue);
61 public override object GetRawConstantValue()
63 return typeBuilder.Module.Constant.GetRawConstantValue(typeBuilder.Module, this.MetadataToken);
66 public void __SetDataAndRVA(byte[] data)
68 SetDataAndRvaImpl(data, typeBuilder.ModuleBuilder.initializedData, 0);
71 public void __SetReadOnlyDataAndRVA(byte[] data)
73 SetDataAndRvaImpl(data, typeBuilder.ModuleBuilder.methodBodies, unchecked((int)0x80000000));
76 private void SetDataAndRvaImpl(byte[] data, ByteBuffer bb, int readonlyMarker)
78 attribs |= FieldAttributes.HasFieldRVA;
79 FieldRVATable.Record rec = new FieldRVATable.Record();
81 rec.RVA = bb.Position + readonlyMarker;
82 rec.Field = pseudoToken;
83 typeBuilder.ModuleBuilder.FieldRVA.AddRecord(rec);
87 public override void __GetDataFromRVA(byte[] data, int offset, int length)
89 throw new NotImplementedException();
92 public override int __FieldRVA
94 get { throw new NotImplementedException(); }
97 public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
99 SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
102 public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
104 Universe u = this.Module.universe;
105 if (customBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_FieldOffsetAttribute)
107 customBuilder = customBuilder.DecodeBlob(this.Module.Assembly);
108 SetOffset((int)customBuilder.GetConstructorArgument(0));
110 else if (customBuilder.Constructor.DeclaringType == u.System_Runtime_InteropServices_MarshalAsAttribute)
112 MarshalSpec.SetMarshalAsAttribute(typeBuilder.ModuleBuilder, pseudoToken, customBuilder);
113 attribs |= FieldAttributes.HasFieldMarshal;
115 else if (customBuilder.Constructor.DeclaringType == u.System_NonSerializedAttribute)
117 attribs |= FieldAttributes.NotSerialized;
119 else if (customBuilder.Constructor.DeclaringType == u.System_Runtime_CompilerServices_SpecialNameAttribute)
121 attribs |= FieldAttributes.SpecialName;
125 typeBuilder.ModuleBuilder.SetCustomAttribute(pseudoToken, customBuilder);
129 public void SetOffset(int iOffset)
131 FieldLayoutTable.Record rec = new FieldLayoutTable.Record();
132 rec.Offset = iOffset;
133 rec.Field = pseudoToken;
134 typeBuilder.ModuleBuilder.FieldLayout.AddRecord(rec);
137 public override FieldAttributes Attributes
139 get { return attribs; }
142 public override Type DeclaringType
144 get { return typeBuilder.IsModulePseudoType ? null : typeBuilder; }
147 public override string Name
152 public override int MetadataToken
154 get { return pseudoToken; }
157 public override Module Module
159 get { return typeBuilder.Module; }
162 public FieldToken GetToken()
164 return new FieldToken(pseudoToken);
167 internal void WriteFieldRecords(MetadataWriter mw)
169 mw.Write((short)attribs);
170 mw.WriteStringIndex(nameIndex);
171 mw.WriteBlobIndex(signature);
174 internal void FixupToken(int token)
176 typeBuilder.ModuleBuilder.RegisterTokenFixup(this.pseudoToken, token);
179 internal override FieldSignature FieldSignature
181 get { return fieldSig; }
184 internal override int ImportTo(ModuleBuilder other)
186 if (typeBuilder.IsGenericTypeDefinition)
188 return other.ImportMember(TypeBuilder.GetField(typeBuilder, this));
190 else if (other == typeBuilder.ModuleBuilder)
196 return other.ImportMethodOrField(typeBuilder, name, fieldSig);