[fix] fixed the bug in the MethodBridge generator where it incorrectly handle [StructLayout] and blittable types when generating code for struct classes.
parent
9e4946aa45
commit
355e24fbe8
|
|
@ -16,6 +16,7 @@ using UnityEngine;
|
||||||
using TypeInfo = HybridCLR.Editor.ABI.TypeInfo;
|
using TypeInfo = HybridCLR.Editor.ABI.TypeInfo;
|
||||||
using CallingConvention = System.Runtime.InteropServices.CallingConvention;
|
using CallingConvention = System.Runtime.InteropServices.CallingConvention;
|
||||||
using TypeAttributes = dnlib.DotNet.TypeAttributes;
|
using TypeAttributes = dnlib.DotNet.TypeAttributes;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace HybridCLR.Editor.MethodBridge
|
namespace HybridCLR.Editor.MethodBridge
|
||||||
{
|
{
|
||||||
|
|
@ -306,43 +307,105 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
|
|
||||||
private class AnalyzeTypeInfo
|
private class AnalyzeTypeInfo
|
||||||
{
|
{
|
||||||
public TypeInfo toSharedType;
|
public TypeInfo isoType;
|
||||||
public List<AnalyzeFieldInfo> fields;
|
public List<AnalyzeFieldInfo> fields;
|
||||||
public string signature;
|
public string signature;
|
||||||
public ClassLayout classLayout;
|
public uint originalPackingSize;
|
||||||
public TypeAttributes layout;
|
public uint packingSize;
|
||||||
|
public uint classSize;
|
||||||
|
public LayoutKind layout;
|
||||||
|
public bool blittable;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Dictionary<TypeInfo, AnalyzeTypeInfo> _analyzeTypeInfos = new Dictionary<TypeInfo, AnalyzeTypeInfo>();
|
private readonly Dictionary<TypeInfo, AnalyzeTypeInfo> _analyzeTypeInfos = new Dictionary<TypeInfo, AnalyzeTypeInfo>();
|
||||||
|
|
||||||
private readonly Dictionary<string, TypeInfo> _signature2Type = new Dictionary<string, TypeInfo>();
|
private readonly Dictionary<string, TypeInfo> _signature2Type = new Dictionary<string, TypeInfo>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private bool IsBlittable(TypeSig typeSig)
|
||||||
|
{
|
||||||
|
typeSig = typeSig.RemovePinnedAndModifiers();
|
||||||
|
if (typeSig.IsByRef)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
switch (typeSig.ElementType)
|
||||||
|
{
|
||||||
|
case ElementType.Void: return false;
|
||||||
|
case ElementType.Boolean:
|
||||||
|
case ElementType.I1:
|
||||||
|
case ElementType.U1:
|
||||||
|
case ElementType.I2:
|
||||||
|
case ElementType.Char:
|
||||||
|
case ElementType.U2:
|
||||||
|
case ElementType.I4:
|
||||||
|
case ElementType.U4:
|
||||||
|
case ElementType.I8:
|
||||||
|
case ElementType.U8:
|
||||||
|
case ElementType.R4:
|
||||||
|
case ElementType.R8:
|
||||||
|
case ElementType.I:
|
||||||
|
case ElementType.U:
|
||||||
|
case ElementType.Ptr:
|
||||||
|
case ElementType.ByRef:
|
||||||
|
case ElementType.FnPtr:
|
||||||
|
case ElementType.TypedByRef: return true;
|
||||||
|
case ElementType.String:
|
||||||
|
case ElementType.Class:
|
||||||
|
case ElementType.Array:
|
||||||
|
case ElementType.SZArray:
|
||||||
|
case ElementType.Object:
|
||||||
|
case ElementType.Module:
|
||||||
|
case ElementType.Var:
|
||||||
|
case ElementType.MVar: return false;
|
||||||
|
case ElementType.ValueType:
|
||||||
|
{
|
||||||
|
TypeDef typeDef = typeSig.ToTypeDefOrRef().ResolveTypeDef();
|
||||||
|
if (typeDef == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"type:{typeSig} definition could not be found. Please try `HybridCLR/Genergate/LinkXml`, then Build once to generate the AOT dll, and then regenerate the bridge function");
|
||||||
|
}
|
||||||
|
if (typeDef.IsEnum)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return CalculateAnalyzeTypeInfoBasic(GetSharedTypeInfo(typeSig)).blittable;
|
||||||
|
}
|
||||||
|
case ElementType.GenericInst:
|
||||||
|
{
|
||||||
|
GenericInstSig gis = (GenericInstSig)typeSig;
|
||||||
|
if (!gis.GenericType.IsValueType)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TypeDef typeDef = gis.GenericType.ToTypeDefOrRef().ResolveTypeDef();
|
||||||
|
if (typeDef.IsEnum)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return CalculateAnalyzeTypeInfoBasic(GetSharedTypeInfo(typeSig)).blittable;
|
||||||
|
}
|
||||||
|
default: throw new NotSupportedException($"{typeSig.ElementType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private AnalyzeTypeInfo CalculateAnalyzeTypeInfoBasic(TypeInfo typeInfo)
|
private AnalyzeTypeInfo CalculateAnalyzeTypeInfoBasic(TypeInfo typeInfo)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(typeInfo.IsStruct);
|
||||||
|
if (_analyzeTypeInfos.TryGetValue(typeInfo, out var ati))
|
||||||
|
{
|
||||||
|
return ati;
|
||||||
|
}
|
||||||
TypeSig type = typeInfo.Klass;
|
TypeSig type = typeInfo.Klass;
|
||||||
TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDefThrow();
|
TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDefThrow();
|
||||||
|
|
||||||
List<TypeSig> klassInst = type.ToGenericInstSig()?.GenericArguments?.ToList();
|
List<TypeSig> klassInst = type.ToGenericInstSig()?.GenericArguments?.ToList();
|
||||||
GenericArgumentContext ctx = klassInst != null ? new GenericArgumentContext(klassInst, null) : null;
|
GenericArgumentContext ctx = klassInst != null ? new GenericArgumentContext(klassInst, null) : null;
|
||||||
|
|
||||||
ClassLayout sa = typeDef.ClassLayout;
|
var fields = new List<AnalyzeFieldInfo>();
|
||||||
var analyzeTypeInfo = new AnalyzeTypeInfo()
|
|
||||||
{
|
|
||||||
classLayout = sa,
|
|
||||||
layout = typeDef.Layout,
|
|
||||||
};
|
|
||||||
|
|
||||||
// don't share type with explicit layout
|
|
||||||
if (sa != null)
|
|
||||||
{
|
|
||||||
analyzeTypeInfo.toSharedType = typeInfo;
|
|
||||||
analyzeTypeInfo.signature = typeInfo.CreateSigName();
|
|
||||||
_signature2Type.Add(analyzeTypeInfo.signature, typeInfo);
|
|
||||||
return analyzeTypeInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
var fields = analyzeTypeInfo.fields = new List<AnalyzeFieldInfo>();
|
|
||||||
|
|
||||||
|
bool blittable = true;
|
||||||
foreach (FieldDef field in typeDef.Fields)
|
foreach (FieldDef field in typeDef.Fields)
|
||||||
{
|
{
|
||||||
if (field.IsStatic)
|
if (field.IsStatic)
|
||||||
|
|
@ -350,8 +413,39 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TypeSig fieldType = ctx != null ? MetaUtil.Inflate(field.FieldType, ctx) : field.FieldType;
|
TypeSig fieldType = ctx != null ? MetaUtil.Inflate(field.FieldType, ctx) : field.FieldType;
|
||||||
fields.Add(new AnalyzeFieldInfo { field = field, type = GetSharedTypeInfo(fieldType) });
|
blittable &= IsBlittable(fieldType);
|
||||||
|
TypeInfo sharedFieldTypeInfo = GetSharedTypeInfo(fieldType);
|
||||||
|
TypeInfo isoType = ToIsomorphicType(sharedFieldTypeInfo);
|
||||||
|
fields.Add(new AnalyzeFieldInfo { field = field, type = isoType });
|
||||||
}
|
}
|
||||||
|
//analyzeTypeInfo.blittable = blittable;
|
||||||
|
//analyzeTypeInfo.packingSize = blittable ? analyzeTypeInfo.originalPackingSize : 0;
|
||||||
|
|
||||||
|
ClassLayout sa = typeDef.ClassLayout;
|
||||||
|
uint originalPackingSize = sa?.PackingSize ?? 0;
|
||||||
|
var analyzeTypeInfo = new AnalyzeTypeInfo()
|
||||||
|
{
|
||||||
|
originalPackingSize = originalPackingSize,
|
||||||
|
packingSize = blittable && !typeDef.IsAutoLayout ? originalPackingSize : 0,
|
||||||
|
classSize = sa?.ClassSize ?? 0,
|
||||||
|
layout = typeDef.IsAutoLayout ? LayoutKind.Auto : (typeDef.IsExplicitLayout ? LayoutKind.Explicit : LayoutKind.Sequential),
|
||||||
|
fields = fields,
|
||||||
|
blittable = blittable,
|
||||||
|
};
|
||||||
|
_analyzeTypeInfos.Add(typeInfo, analyzeTypeInfo);
|
||||||
|
analyzeTypeInfo.signature = GetOrCalculateTypeInfoSignature(typeInfo);
|
||||||
|
|
||||||
|
if (_signature2Type.TryGetValue(analyzeTypeInfo.signature, out var sharedType))
|
||||||
|
{
|
||||||
|
// Debug.Log($"[ToIsomorphicType] type:{type.Klass} ==> sharedType:{sharedType.Klass} signature:{signature} ");
|
||||||
|
analyzeTypeInfo.isoType = sharedType;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
analyzeTypeInfo.isoType = typeInfo;
|
||||||
|
_signature2Type.Add(analyzeTypeInfo.signature, typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
return analyzeTypeInfo;
|
return analyzeTypeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -376,15 +470,10 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
}
|
}
|
||||||
|
|
||||||
var sigBuf = new StringBuilder();
|
var sigBuf = new StringBuilder();
|
||||||
if (ati.classLayout != null)
|
if (ati.packingSize != 0 || ati.classSize != 0 || ati.layout != LayoutKind.Sequential || !ati.blittable)
|
||||||
{
|
{
|
||||||
sigBuf.Append($"[{ati.classLayout.ClassSize}|{ati.classLayout.PackingSize}|{ati.classLayout}]");
|
sigBuf.Append($"[{ati.classSize}|{ati.packingSize}|{ati.layout}|{(ati.blittable ? 0 : 1)}]");
|
||||||
}
|
}
|
||||||
if (ati.layout != 0)
|
|
||||||
{
|
|
||||||
sigBuf.Append($"[{(int)ati.layout}]");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var field in ati.fields)
|
foreach (var field in ati.fields)
|
||||||
{
|
{
|
||||||
string fieldOffset = field.field.FieldOffset != null ? field.field.FieldOffset.ToString() + "|" : "";
|
string fieldOffset = field.field.FieldOffset != null ? field.field.FieldOffset.ToString() + "|" : "";
|
||||||
|
|
@ -399,27 +488,7 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
{
|
{
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
if (!_analyzeTypeInfos.TryGetValue(type, out var ati))
|
return CalculateAnalyzeTypeInfoBasic(type).isoType;
|
||||||
{
|
|
||||||
ati = CalculateAnalyzeTypeInfoBasic(type);
|
|
||||||
_analyzeTypeInfos.Add(type, ati);
|
|
||||||
}
|
|
||||||
if (ati.toSharedType == null)
|
|
||||||
{
|
|
||||||
string signature = GetOrCalculateTypeInfoSignature(type);
|
|
||||||
Debug.Assert(signature == ati.signature);
|
|
||||||
if (_signature2Type.TryGetValue(signature, out var sharedType))
|
|
||||||
{
|
|
||||||
// Debug.Log($"[ToIsomorphicType] type:{type.Klass} ==> sharedType:{sharedType.Klass} signature:{signature} ");
|
|
||||||
ati.toSharedType = sharedType;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ati.toSharedType = type;
|
|
||||||
_signature2Type.Add(signature, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ati.toSharedType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MethodDesc ToIsomorphicMethod(MethodDesc method)
|
private MethodDesc ToIsomorphicMethod(MethodDesc method)
|
||||||
|
|
@ -527,8 +596,8 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
var sharedMethod = new MethodDesc
|
var sharedMethod = new MethodDesc
|
||||||
{
|
{
|
||||||
MethodDef = method.Method,
|
MethodDef = method.Method,
|
||||||
ReturnInfo = new ReturnInfo { Type = _typeCreator.CreateTypeInfo(method.Method.ReturnType) },
|
ReturnInfo = new ReturnInfo { Type = GetSharedTypeInfo(method.Method.ReturnType) },
|
||||||
ParamInfos = method.Method.Parameters.Select(p => new ParamInfo { Type = _typeCreator.CreateTypeInfo(p.Type) }).ToList(),
|
ParamInfos = method.Method.Parameters.Select(p => new ParamInfo { Type = GetSharedTypeInfo(p.Type) }).ToList(),
|
||||||
};
|
};
|
||||||
sharedMethod.Init();
|
sharedMethod.Init();
|
||||||
sharedMethod = ToIsomorphicMethod(sharedMethod);
|
sharedMethod = ToIsomorphicMethod(sharedMethod);
|
||||||
|
|
@ -563,8 +632,8 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
var sharedMethod = new MethodDesc
|
var sharedMethod = new MethodDesc
|
||||||
{
|
{
|
||||||
MethodDef = null,
|
MethodDef = null,
|
||||||
ReturnInfo = new ReturnInfo { Type = _typeCreator.CreateTypeInfo(method.MethodSig.RetType) },
|
ReturnInfo = new ReturnInfo { Type = GetSharedTypeInfo(method.MethodSig.RetType) },
|
||||||
ParamInfos = method.MethodSig.Params.Select(p => new ParamInfo { Type = _typeCreator.CreateTypeInfo(p) }).ToList(),
|
ParamInfos = method.MethodSig.Params.Select(p => new ParamInfo { Type = GetSharedTypeInfo(p) }).ToList(),
|
||||||
};
|
};
|
||||||
sharedMethod.Init();
|
sharedMethod.Init();
|
||||||
sharedMethod = ToIsomorphicMethod(sharedMethod);
|
sharedMethod = ToIsomorphicMethod(sharedMethod);
|
||||||
|
|
@ -617,7 +686,7 @@ namespace HybridCLR.Editor.MethodBridge
|
||||||
};
|
};
|
||||||
|
|
||||||
var classInfos = new List<ClassInfo>();
|
var classInfos = new List<ClassInfo>();
|
||||||
var classTypeSet = new HashSet<TypeInfo>();
|
var classTypeSet = new Dictionary<TypeInfo, ClassInfo>();
|
||||||
foreach (var type in structTypes)
|
foreach (var type in structTypes)
|
||||||
{
|
{
|
||||||
GenerateClassInfo(type, classTypeSet, classInfos);
|
GenerateClassInfo(type, classTypeSet, classInfos);
|
||||||
|
|
@ -770,47 +839,68 @@ const ReversePInvokeMethodData hybridclr::interpreter::g_reversePInvokeMethodStu
|
||||||
class ClassInfo
|
class ClassInfo
|
||||||
{
|
{
|
||||||
public TypeInfo type;
|
public TypeInfo type;
|
||||||
|
public List<AnalyzeFieldInfo> fields;
|
||||||
public TypeDef typeDef;
|
public uint packingSize;
|
||||||
|
public uint classSize;
|
||||||
public List<FieldInfo> fields = new List<FieldInfo>();
|
public LayoutKind layout;
|
||||||
|
public bool blittable;
|
||||||
public ClassLayout layout;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateClassInfo(TypeInfo type, HashSet<TypeInfo> typeSet, List<ClassInfo> classInfos)
|
private void GenerateClassInfo(TypeInfo type, Dictionary<TypeInfo, ClassInfo> typeSet, List<ClassInfo> classInfos)
|
||||||
{
|
{
|
||||||
if (!typeSet.Add(type))
|
if (typeSet.ContainsKey(type))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TypeSig typeSig = type.Klass;
|
|
||||||
var fields = new List<FieldInfo>();
|
|
||||||
|
|
||||||
TypeDef typeDef = typeSig.ToTypeDefOrRef().ResolveTypeDefThrow();
|
AnalyzeTypeInfo ati = CalculateAnalyzeTypeInfoBasic(type);
|
||||||
|
//TypeSig typeSig = type.Klass;
|
||||||
|
//var fields = new List<FieldInfo>();
|
||||||
|
|
||||||
List<TypeSig> klassInst = typeSig.ToGenericInstSig()?.GenericArguments?.ToList();
|
//TypeDef typeDef = typeSig.ToTypeDefOrRef().ResolveTypeDefThrow();
|
||||||
GenericArgumentContext ctx = klassInst != null ? new GenericArgumentContext(klassInst, null) : null;
|
|
||||||
|
|
||||||
ClassLayout sa = typeDef.ClassLayout;
|
//List<TypeSig> klassInst = typeSig.ToGenericInstSig()?.GenericArguments?.ToList();
|
||||||
|
//GenericArgumentContext ctx = klassInst != null ? new GenericArgumentContext(klassInst, null) : null;
|
||||||
|
|
||||||
ICorLibTypes corLibTypes = typeDef.Module.CorLibTypes;
|
//ClassLayout sa = typeDef.ClassLayout;
|
||||||
foreach (FieldDef field in typeDef.Fields)
|
|
||||||
|
//ICorLibTypes corLibTypes = typeDef.Module.CorLibTypes;
|
||||||
|
//bool blittable = true;
|
||||||
|
//foreach (FieldDef field in typeDef.Fields)
|
||||||
|
//{
|
||||||
|
// if (field.IsStatic)
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// TypeSig fieldType = ctx != null ? MetaUtil.Inflate(field.FieldType, ctx) : field.FieldType;
|
||||||
|
// fieldType = MetaUtil.ToShareTypeSig(corLibTypes, fieldType);
|
||||||
|
// var fieldTypeInfo = ToIsomorphicType(GetSharedTypeInfo(fieldType));
|
||||||
|
// if (fieldTypeInfo.IsStruct)
|
||||||
|
// {
|
||||||
|
// GenerateClassInfo(fieldTypeInfo, typeSet, classInfos);
|
||||||
|
// }
|
||||||
|
// blittable &= IsBlittable(fieldType, fieldTypeInfo, typeSet);
|
||||||
|
// fields.Add(new FieldInfo { field = field, type = fieldTypeInfo });
|
||||||
|
//}
|
||||||
|
|
||||||
|
foreach (var field in ati.fields)
|
||||||
{
|
{
|
||||||
if (field.IsStatic)
|
if (field.type.IsStruct)
|
||||||
{
|
{
|
||||||
continue;
|
GenerateClassInfo(field.type, typeSet, classInfos);
|
||||||
}
|
}
|
||||||
TypeSig fieldType = ctx != null ? MetaUtil.Inflate(field.FieldType, ctx) : field.FieldType;
|
}
|
||||||
fieldType = MetaUtil.ToShareTypeSig(corLibTypes, fieldType);
|
var classInfo = new ClassInfo()
|
||||||
var fieldTypeInfo = ToIsomorphicType(_typeCreator.CreateTypeInfo(fieldType));
|
|
||||||
if (fieldTypeInfo.IsStruct)
|
|
||||||
{
|
{
|
||||||
GenerateClassInfo(fieldTypeInfo, typeSet, classInfos);
|
type = type,
|
||||||
}
|
fields = ati.fields,
|
||||||
fields.Add(new FieldInfo { field = field, type = fieldTypeInfo });
|
packingSize = ati.packingSize,
|
||||||
}
|
classSize = ati.classSize,
|
||||||
classInfos.Add(new ClassInfo() { type = type, typeDef = typeDef, fields = fields, layout = sa });
|
layout = ati.layout,
|
||||||
|
blittable = ati.blittable,
|
||||||
|
};
|
||||||
|
typeSet.Add(type, classInfo);
|
||||||
|
classInfos.Add(classInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateStructDefines(List<ClassInfo> classInfos, List<string> lines)
|
private void GenerateStructDefines(List<ClassInfo> classInfos, List<string> lines)
|
||||||
|
|
@ -818,16 +908,13 @@ const ReversePInvokeMethodData hybridclr::interpreter::g_reversePInvokeMethodStu
|
||||||
foreach (var ci in classInfos)
|
foreach (var ci in classInfos)
|
||||||
{
|
{
|
||||||
lines.Add($"// {ci.type.Klass}");
|
lines.Add($"// {ci.type.Klass}");
|
||||||
uint packingSize = ci.layout?.PackingSize ?? 0;
|
uint packingSize = ci.packingSize;
|
||||||
if (packingSize != 0)
|
uint classSize = ci.classSize;
|
||||||
{
|
|
||||||
lines.Add($"#pragma pack(push, {packingSize})");
|
|
||||||
}
|
|
||||||
uint classSize = ci.layout?.ClassSize ?? 0;
|
|
||||||
|
|
||||||
if (ci.typeDef.IsExplicitLayout)
|
if (ci.layout == LayoutKind.Explicit)
|
||||||
{
|
{
|
||||||
lines.Add($"union {ci.type.GetTypeName()} {{");
|
lines.Add($"struct {ci.type.GetTypeName()} {{");
|
||||||
|
lines.Add("\tunion {");
|
||||||
if (classSize > 0)
|
if (classSize > 0)
|
||||||
{
|
{
|
||||||
lines.Add($"\tstruct {{ char __fieldSize_offsetPadding[{classSize}];}};");
|
lines.Add($"\tstruct {{ char __fieldSize_offsetPadding[{classSize}];}};");
|
||||||
|
|
@ -839,14 +926,28 @@ const ReversePInvokeMethodData hybridclr::interpreter::g_reversePInvokeMethodStu
|
||||||
string fieldName = $"__{index}";
|
string fieldName = $"__{index}";
|
||||||
string commentFieldName = $"{field.field.Name}";
|
string commentFieldName = $"{field.field.Name}";
|
||||||
lines.Add("\t#pragma pack(push, 1)");
|
lines.Add("\t#pragma pack(push, 1)");
|
||||||
lines.Add($"\tstruct {{ {(offset > 0 ? $"char {fieldName}_offsetPadding[{offset}];" : "")} {field.type.GetTypeName()} {fieldName};}}; // {commentFieldName}");
|
lines.Add($"\tstruct {{ {(offset > 0 ? $"char {fieldName}_offsetPadding[{offset}]; " : "")}{field.type.GetTypeName()} {fieldName};}}; // {commentFieldName}");
|
||||||
lines.Add($"\t#pragma pack(pop)");
|
lines.Add($"\t#pragma pack(pop)");
|
||||||
lines.Add($"\tstruct {{ {field.type.GetTypeName()} {fieldName}_forAlignmentOnly;}}; // {commentFieldName}");
|
if (packingSize > 0)
|
||||||
|
{
|
||||||
|
lines.Add($"\t#pragma pack(push, {packingSize})");
|
||||||
|
}
|
||||||
|
lines.Add($"\tstruct {{ {(offset > 0 ? $"char {fieldName}_offsetPadding_forAlignmentOnly[{offset}]; " : "")}{field.type.GetTypeName()} {fieldName}_forAlignmentOnly;}}; // {commentFieldName}");
|
||||||
|
if (packingSize > 0)
|
||||||
|
{
|
||||||
|
lines.Add($"\t#pragma pack(pop)");
|
||||||
|
}
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
|
lines.Add("\t};");
|
||||||
|
lines.Add("};");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (packingSize != 0)
|
||||||
|
{
|
||||||
|
lines.Add($"#pragma pack(push, {packingSize})");
|
||||||
|
}
|
||||||
lines.Add($"{(classSize > 0 ? "union" : "struct")} {ci.type.GetTypeName()} {{");
|
lines.Add($"{(classSize > 0 ? "union" : "struct")} {ci.type.GetTypeName()} {{");
|
||||||
if (classSize > 0)
|
if (classSize > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -865,7 +966,6 @@ const ReversePInvokeMethodData hybridclr::interpreter::g_reversePInvokeMethodStu
|
||||||
{
|
{
|
||||||
lines.Add("\t};");
|
lines.Add("\t};");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
lines.Add("};");
|
lines.Add("};");
|
||||||
if (packingSize != 0)
|
if (packingSize != 0)
|
||||||
{
|
{
|
||||||
|
|
@ -873,6 +973,7 @@ const ReversePInvokeMethodData hybridclr::interpreter::g_reversePInvokeMethodStu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private const string SigOfObj = "u";
|
private const string SigOfObj = "u";
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue