зеркало из https://github.com/mono/ikvm-fork.git
Added API extension __SetStructLayoutAttribute().
This commit is contained in:
Родитель
5f9279e69a
Коммит
fe0b7faf89
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче