Added API extension __SetStructLayoutAttribute().

This commit is contained in:
jfrijters 2011-03-06 07:25:38 +00:00
Родитель 5f9279e69a
Коммит fe0b7faf89
2 изменённых файлов: 74 добавлений и 84 удалений

Просмотреть файл

@ -210,7 +210,7 @@ namespace IKVM.Reflection.Emit
TypeBuilder typeBuilder = __DefineType(ns, name); TypeBuilder typeBuilder = __DefineType(ns, name);
typeBuilder.__SetAttributes(attr); typeBuilder.__SetAttributes(attr);
typeBuilder.SetParent(parent); typeBuilder.SetParent(parent);
SetPackingSizeAndTypeSize(typeBuilder, packingSize, typesize); typeBuilder.SetPackingSizeAndTypeSize(packingSize, typesize);
return typeBuilder; return typeBuilder;
} }
@ -226,18 +226,6 @@ namespace IKVM.Reflection.Emit
return typeBuilder; return typeBuilder;
} }
internal void SetPackingSizeAndTypeSize(TypeBuilder typeBuilder, PackingSize packingSize, int typesize)
{
if (packingSize != PackingSize.Unspecified || typesize != 0)
{
ClassLayoutTable.Record rec = new ClassLayoutTable.Record();
rec.PackingSize = (short)packingSize;
rec.ClassSize = typesize;
rec.Parent = typeBuilder.MetadataToken;
this.ClassLayout.AddRecord(rec);
}
}
public EnumBuilder DefineEnum(string name, TypeAttributes visibility, Type underlyingType) public EnumBuilder DefineEnum(string name, TypeAttributes visibility, Type underlyingType)
{ {
TypeBuilder tb = DefineType(name, (visibility & TypeAttributes.VisibilityMask) | TypeAttributes.Sealed, universe.System_Enum); TypeBuilder tb = DefineType(name, (visibility & TypeAttributes.VisibilityMask) | TypeAttributes.Sealed, universe.System_Enum);

Просмотреть файл

@ -234,6 +234,8 @@ namespace IKVM.Reflection.Emit
private GenericTypeParameterBuilder[] gtpb; private GenericTypeParameterBuilder[] gtpb;
private List<CustomAttributeBuilder> declarativeSecurity; private List<CustomAttributeBuilder> declarativeSecurity;
private List<Type> interfaces; private List<Type> interfaces;
private int size;
private short pack;
internal TypeBuilder(ITypeOwner owner, string ns, string name) internal TypeBuilder(ITypeOwner owner, string ns, string name)
{ {
@ -445,7 +447,8 @@ namespace IKVM.Reflection.Emit
TypeBuilder typeBuilder = __DefineNestedType(ns, name); TypeBuilder typeBuilder = __DefineNestedType(ns, name);
typeBuilder.__SetAttributes(attr); typeBuilder.__SetAttributes(attr);
typeBuilder.SetParent(parent); typeBuilder.SetParent(parent);
this.ModuleBuilder.SetPackingSizeAndTypeSize(typeBuilder, PackingSize.Unspecified, typeSize); typeBuilder.pack = (short)packSize;
typeBuilder.size = typeSize;
return typeBuilder; return typeBuilder;
} }
@ -476,32 +479,51 @@ namespace IKVM.Reflection.Emit
public int Size public int Size
{ {
get get { return size; }
{
for (int i = 0; i < this.ModuleBuilder.ClassLayout.records.Length; i++)
{
if (this.ModuleBuilder.ClassLayout.records[i].Parent == token)
{
return this.ModuleBuilder.ClassLayout.records[i].ClassSize;
}
}
return 0;
}
} }
public PackingSize PackingSize public PackingSize PackingSize
{ {
get get { return (PackingSize)pack; }
}
public void __SetStructLayoutAttribute(StructLayoutAttribute attribute)
{
attribs &= ~TypeAttributes.LayoutMask;
switch (attribute.Value)
{ {
for (int i = 0; i < this.ModuleBuilder.ClassLayout.records.Length; i++) case LayoutKind.Auto:
{ attribs |= TypeAttributes.AutoLayout;
if (this.ModuleBuilder.ClassLayout.records[i].Parent == token) break;
{ case LayoutKind.Explicit:
return (PackingSize)this.ModuleBuilder.ClassLayout.records[i].PackingSize; attribs |= TypeAttributes.ExplicitLayout;
} break;
} case LayoutKind.Sequential:
return PackingSize.Unspecified; attribs |= TypeAttributes.SequentialLayout;
break;
} }
attribs &= ~TypeAttributes.StringFormatMask;
switch (attribute.CharSet)
{
case CharSet.None:
case CharSet.Ansi:
attribs |= TypeAttributes.AnsiClass;
break;
case CharSet.Auto:
attribs |= TypeAttributes.AutoClass;
break;
case CharSet.Unicode:
attribs |= TypeAttributes.UnicodeClass;
break;
}
pack = (short)attribute.Pack;
size = attribute.Size;
}
internal void SetPackingSizeAndTypeSize(PackingSize packingSize, int typesize)
{
this.pack = (short)packingSize;
this.size = typesize;
} }
private void SetStructLayoutPseudoCustomAttribute(CustomAttributeBuilder customBuilder) private void SetStructLayoutPseudoCustomAttribute(CustomAttributeBuilder customBuilder)
@ -516,44 +538,11 @@ namespace IKVM.Reflection.Emit
{ {
layout = (LayoutKind)val; layout = (LayoutKind)val;
} }
int? pack = (int?)customBuilder.GetFieldValue("Pack"); StructLayoutAttribute attr = new StructLayoutAttribute(layout);
int? size = (int?)customBuilder.GetFieldValue("Size"); attr.Pack = (int?)customBuilder.GetFieldValue("Pack") ?? 0;
if (pack.HasValue || size.HasValue) attr.Size = (int?)customBuilder.GetFieldValue("Size") ?? 0;
{ attr.CharSet = customBuilder.GetFieldValue<CharSet>("CharSet") ?? CharSet.None;
ClassLayoutTable.Record rec = new ClassLayoutTable.Record(); __SetStructLayoutAttribute(attr);
rec.PackingSize = (short)(pack ?? 0);
rec.ClassSize = size ?? 0;
rec.Parent = token;
this.ModuleBuilder.ClassLayout.AddOrReplaceRecord(rec);
}
attribs &= ~TypeAttributes.LayoutMask;
switch (layout)
{
case LayoutKind.Auto:
attribs |= TypeAttributes.AutoLayout;
break;
case LayoutKind.Explicit:
attribs |= TypeAttributes.ExplicitLayout;
break;
case LayoutKind.Sequential:
attribs |= TypeAttributes.SequentialLayout;
break;
}
CharSet? charSet = customBuilder.GetFieldValue<CharSet>("CharSet");
attribs &= ~TypeAttributes.StringFormatMask;
switch (charSet ?? CharSet.None)
{
case CharSet.None:
case CharSet.Ansi:
attribs |= TypeAttributes.AnsiClass;
break;
case CharSet.Auto:
attribs |= TypeAttributes.AutoClass;
break;
case CharSet.Unicode:
attribs |= TypeAttributes.UnicodeClass;
break;
}
} }
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
@ -656,6 +645,14 @@ namespace IKVM.Reflection.Emit
throw new NotImplementedException(); throw new NotImplementedException();
} }
typeFlags |= TypeFlags.Baked; typeFlags |= TypeFlags.Baked;
if (pack != 0 || size != 0)
{
ClassLayoutTable.Record rec = new ClassLayoutTable.Record();
rec.PackingSize = (short)pack;
rec.ClassSize = size;
rec.Parent = token;
this.ModuleBuilder.ClassLayout.AddRecord(rec);
}
foreach (MethodBuilder mb in methods) foreach (MethodBuilder mb in methods)
{ {
mb.Bake(); mb.Bake();
@ -806,20 +803,22 @@ namespace IKVM.Reflection.Emit
{ {
get get
{ {
StructLayoutAttribute attr; LayoutKind layout;
if ((attribs & TypeAttributes.ExplicitLayout) != 0) switch (attribs & TypeAttributes.LayoutMask)
{ {
attr = new StructLayoutAttribute(LayoutKind.Explicit); case TypeAttributes.ExplicitLayout:
attr.Pack = 8; layout = LayoutKind.Explicit;
attr.Size = 0; break;
this.ModuleBuilder.ClassLayout.GetLayout(token, ref attr.Pack, ref attr.Size); case TypeAttributes.SequentialLayout:
} layout = LayoutKind.Sequential;
else break;
{ default:
attr = new StructLayoutAttribute((attribs & TypeAttributes.SequentialLayout) != 0 ? LayoutKind.Sequential : LayoutKind.Auto); layout = LayoutKind.Auto;
attr.Pack = 8; break;
attr.Size = 0;
} }
StructLayoutAttribute attr = new StructLayoutAttribute(layout);
attr.Pack = (ushort)pack;
attr.Size = size;
switch (attribs & TypeAttributes.StringFormatMask) switch (attribs & TypeAttributes.StringFormatMask)
{ {
case TypeAttributes.AutoClass: case TypeAttributes.AutoClass:
@ -831,6 +830,9 @@ namespace IKVM.Reflection.Emit
case TypeAttributes.AnsiClass: case TypeAttributes.AnsiClass:
attr.CharSet = CharSet.Ansi; attr.CharSet = CharSet.Ansi;
break; break;
default:
attr.CharSet = CharSet.None;
break;
} }
return attr; return attr;
} }