[fix] 修复WebGL平台ABI的bug
parent
8439e4176d
commit
21b85aa2d3
|
@ -19,8 +19,6 @@ namespace HybridCLR.Editor.ABI
|
||||||
{
|
{
|
||||||
public override bool IsArch32 => false;
|
public override bool IsArch32 => false;
|
||||||
|
|
||||||
public override bool IsSupportHFA => true;
|
|
||||||
|
|
||||||
protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType)
|
protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType)
|
||||||
{
|
{
|
||||||
if (!type.IsGeneralValueType)
|
if (!type.IsGeneralValueType)
|
||||||
|
@ -42,5 +40,99 @@ namespace HybridCLR.Editor.ABI
|
||||||
}
|
}
|
||||||
return TypeInfo.s_ref;
|
return TypeInfo.s_ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static bool IsNotHFAFastCheck(int typeSize)
|
||||||
|
{
|
||||||
|
return typeSize % 4 != 0 || typeSize > 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool ComputHFATypeInfo0(TypeSig type, HFATypeInfo typeInfo)
|
||||||
|
{
|
||||||
|
TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDefThrow();
|
||||||
|
|
||||||
|
List<TypeSig> klassInst = type.ToGenericInstSig()?.GenericArguments?.ToList();
|
||||||
|
GenericArgumentContext ctx = klassInst != null ? new GenericArgumentContext(klassInst, null) : null;
|
||||||
|
|
||||||
|
var fields = typeDef.Fields;// typeDef.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||||
|
foreach (FieldDef field in fields)
|
||||||
|
{
|
||||||
|
if (field.IsStatic)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TypeSig ftype = ctx != null ? MetaUtil.Inflate(field.FieldType, ctx) : field.FieldType;
|
||||||
|
switch (ftype.ElementType)
|
||||||
|
{
|
||||||
|
case ElementType.R4:
|
||||||
|
case ElementType.R8:
|
||||||
|
{
|
||||||
|
if (ftype == typeInfo.Type || typeInfo.Type == null)
|
||||||
|
{
|
||||||
|
typeInfo.Type = ftype;
|
||||||
|
++typeInfo.Count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ElementType.ValueType:
|
||||||
|
{
|
||||||
|
if (!ComputHFATypeInfo0(ftype, typeInfo))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ElementType.GenericInst:
|
||||||
|
{
|
||||||
|
if (!ftype.IsValueType || !ComputHFATypeInfo0(ftype, typeInfo))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typeInfo.Count <= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool ComputHFATypeInfo(TypeSig type, int typeSize, out HFATypeInfo typeInfo)
|
||||||
|
{
|
||||||
|
typeInfo = new HFATypeInfo();
|
||||||
|
if (IsNotHFAFastCheck(typeSize))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool ok = ComputHFATypeInfo0(type, typeInfo);
|
||||||
|
if (ok && typeInfo.Count >= 1 && typeInfo.Count <= 4)
|
||||||
|
{
|
||||||
|
int fieldSize = typeInfo.Type.ElementType == ElementType.R4 ? 4 : 8;
|
||||||
|
return typeSize == fieldSize * typeInfo.Count;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool TryCreateCustomValueTypeInfo(TypeSig type, int typeSize, int typeAligment, out TypeInfo typeInfo)
|
||||||
|
{
|
||||||
|
if (ComputHFATypeInfo(type, typeSize, out HFATypeInfo hfaTypeInfo))
|
||||||
|
{
|
||||||
|
bool isFloat = hfaTypeInfo.Type.ElementType == ElementType.R4;
|
||||||
|
switch (hfaTypeInfo.Count)
|
||||||
|
{
|
||||||
|
case 1: typeInfo = isFloat ? TypeInfo.s_r4 : TypeInfo.s_r8; break;
|
||||||
|
case 2: typeInfo = isFloat ? TypeInfo.s_vf2 : TypeInfo.s_vd2; break;
|
||||||
|
case 3: typeInfo = isFloat ? TypeInfo.s_vf3 : TypeInfo.s_vd3; break;
|
||||||
|
case 4: typeInfo = isFloat ? TypeInfo.s_vf4 : TypeInfo.s_vd4; break;
|
||||||
|
default: throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
typeInfo = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,6 @@ namespace HybridCLR.Editor.ABI
|
||||||
{
|
{
|
||||||
public abstract bool IsArch32 { get; }
|
public abstract bool IsArch32 { get; }
|
||||||
|
|
||||||
public virtual bool IsSupportHFA => false;
|
|
||||||
|
|
||||||
public virtual bool IsSupportWebGLSpecialValueType => false;
|
|
||||||
|
|
||||||
public TypeInfo GetNativeIntTypeInfo() => IsArch32 ? TypeInfo.s_i4 : TypeInfo.s_i8;
|
public TypeInfo GetNativeIntTypeInfo() => IsArch32 ? TypeInfo.s_i4 : TypeInfo.s_i8;
|
||||||
|
|
||||||
public ValueTypeSizeAligmentCalculator Calculator => IsArch32 ? ValueTypeSizeAligmentCalculator.Caculator32 : ValueTypeSizeAligmentCalculator.Caculator64;
|
public ValueTypeSizeAligmentCalculator Calculator => IsArch32 ? ValueTypeSizeAligmentCalculator.Caculator32 : ValueTypeSizeAligmentCalculator.Caculator64;
|
||||||
|
@ -24,6 +20,9 @@ namespace HybridCLR.Editor.ABI
|
||||||
|
|
||||||
private readonly Dictionary<TypeSig, (int, int)> _typeSizeCache = new Dictionary<TypeSig, (int, int)>(TypeEqualityComparer.Instance);
|
private readonly Dictionary<TypeSig, (int, int)> _typeSizeCache = new Dictionary<TypeSig, (int, int)>(TypeEqualityComparer.Instance);
|
||||||
|
|
||||||
|
|
||||||
|
private readonly Dictionary<TypeSig, TypeInfo> _typeInfoCache = new Dictionary<TypeSig, TypeInfo>(TypeEqualityComparer.Instance);
|
||||||
|
|
||||||
public (int Size, int Aligment) ComputeSizeAndAligment(TypeSig t)
|
public (int Size, int Aligment) ComputeSizeAndAligment(TypeSig t)
|
||||||
{
|
{
|
||||||
if (_typeSizeCache.TryGetValue(t, out var sizeAndAligment))
|
if (_typeSizeCache.TryGetValue(t, out var sizeAndAligment))
|
||||||
|
@ -36,6 +35,16 @@ namespace HybridCLR.Editor.ABI
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeInfo CreateTypeInfo(TypeSig type)
|
public TypeInfo CreateTypeInfo(TypeSig type)
|
||||||
|
{
|
||||||
|
if (!_typeInfoCache.TryGetValue(type, out var typeInfo))
|
||||||
|
{
|
||||||
|
typeInfo = CreateTypeInfo0(type);
|
||||||
|
_typeInfoCache.Add(type, typeInfo);
|
||||||
|
}
|
||||||
|
return new TypeInfo(typeInfo.PorType, typeInfo.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeInfo CreateTypeInfo0(TypeSig type)
|
||||||
{
|
{
|
||||||
type = type.RemovePinnedAndModifiers();
|
type = type.RemovePinnedAndModifiers();
|
||||||
if (type.IsByRef)
|
if (type.IsByRef)
|
||||||
|
@ -103,175 +112,6 @@ namespace HybridCLR.Editor.ABI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsNotHFAFastCheck(int typeSize)
|
|
||||||
{
|
|
||||||
return typeSize % 4 != 0 || typeSize > 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool ComputHFATypeInfo0(TypeSig type, HFATypeInfo typeInfo)
|
|
||||||
{
|
|
||||||
TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDefThrow();
|
|
||||||
|
|
||||||
List<TypeSig> klassInst = type.ToGenericInstSig()?.GenericArguments?.ToList();
|
|
||||||
GenericArgumentContext ctx = klassInst != null ? new GenericArgumentContext(klassInst, null) : null;
|
|
||||||
|
|
||||||
var fields = typeDef.Fields;// typeDef.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
||||||
foreach (FieldDef field in fields)
|
|
||||||
{
|
|
||||||
if (field.IsStatic)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
TypeSig ftype = ctx != null ? MetaUtil.Inflate(field.FieldType, ctx) : field.FieldType;
|
|
||||||
switch (ftype.ElementType)
|
|
||||||
{
|
|
||||||
case ElementType.R4:
|
|
||||||
case ElementType.R8:
|
|
||||||
{
|
|
||||||
if (ftype == typeInfo.Type || typeInfo.Type == null)
|
|
||||||
{
|
|
||||||
typeInfo.Type = ftype;
|
|
||||||
++typeInfo.Count;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.ValueType:
|
|
||||||
{
|
|
||||||
if (!ComputHFATypeInfo0(ftype, typeInfo))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.GenericInst:
|
|
||||||
{
|
|
||||||
if (!ftype.IsValueType || !ComputHFATypeInfo0(ftype, typeInfo))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return typeInfo.Count <= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool ComputHFATypeInfo(TypeSig type, int typeSize, out HFATypeInfo typeInfo)
|
|
||||||
{
|
|
||||||
typeInfo = new HFATypeInfo();
|
|
||||||
if (IsNotHFAFastCheck(typeSize))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool ok = ComputHFATypeInfo0(type, typeInfo);
|
|
||||||
if (ok && typeInfo.Count >= 1 && typeInfo.Count <= 4)
|
|
||||||
{
|
|
||||||
int fieldSize = typeInfo.Type.ElementType == ElementType.R4 ? 4 : 8;
|
|
||||||
return typeSize == fieldSize * typeInfo.Count;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool TryComputSingletonStruct(TypeSig type, out SingletonStruct result)
|
|
||||||
{
|
|
||||||
result = new SingletonStruct();
|
|
||||||
return TryComputSingletonStruct0(type, result) && result.Type != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool TryComputSingletonStruct0(TypeSig type, SingletonStruct result)
|
|
||||||
{
|
|
||||||
TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDefThrow();
|
|
||||||
if (typeDef.IsEnum)
|
|
||||||
{
|
|
||||||
if (result.Type == null)
|
|
||||||
{
|
|
||||||
result.Type = typeDef.GetEnumUnderlyingType();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<TypeSig> klassInst = type.ToGenericInstSig()?.GenericArguments?.ToList();
|
|
||||||
GenericArgumentContext ctx = klassInst != null ? new GenericArgumentContext(klassInst, null) : null;
|
|
||||||
|
|
||||||
var fields = typeDef.Fields;// typeDef.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
||||||
foreach (FieldDef field in fields)
|
|
||||||
{
|
|
||||||
if (field.IsStatic)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
TypeSig ftype = ctx != null ? MetaUtil.Inflate(field.FieldType, ctx) : field.FieldType;
|
|
||||||
|
|
||||||
switch (ftype.ElementType)
|
|
||||||
{
|
|
||||||
case ElementType.TypedByRef: return false;
|
|
||||||
case ElementType.ValueType:
|
|
||||||
{
|
|
||||||
if (!TryComputSingletonStruct0(ftype, result))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ElementType.GenericInst:
|
|
||||||
{
|
|
||||||
if (!ftype.IsValueType)
|
|
||||||
{
|
|
||||||
goto default;
|
|
||||||
}
|
|
||||||
if (!TryComputSingletonStruct0(ftype, result))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if (result.Type != null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
result.Type = ftype;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsWebGLSpeicalValueType(TypeSig type)
|
|
||||||
{
|
|
||||||
TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDefThrow();
|
|
||||||
if (typeDef.IsEnum)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var fields = typeDef.Fields;// typeDef.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
||||||
if (fields.Count == 0)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (fields.All(f => f.IsStatic))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (typeDef.IsExplicitLayout && fields.Count(f => !f.IsStatic) > 1)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static TypeInfo CreateGeneralValueType(TypeSig type, int size, int aligment)
|
protected static TypeInfo CreateGeneralValueType(TypeSig type, int size, int aligment)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.Assert(size % aligment == 0);
|
System.Diagnostics.Debug.Assert(size % aligment == 0);
|
||||||
|
@ -285,31 +125,19 @@ namespace HybridCLR.Editor.ABI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual bool TryCreateCustomValueTypeInfo(TypeSig type, int typeSize, int typeAligment, out TypeInfo typeInfo)
|
||||||
|
{
|
||||||
|
typeInfo = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected TypeInfo CreateValueType(TypeSig type)
|
protected TypeInfo CreateValueType(TypeSig type)
|
||||||
{
|
{
|
||||||
(int typeSize, int typeAligment) = ComputeSizeAndAligment(type);
|
(int typeSize, int typeAligment) = ComputeSizeAndAligment(type);
|
||||||
if (IsSupportHFA && ComputHFATypeInfo(type, typeSize, out HFATypeInfo hfaTypeInfo))
|
if (TryCreateCustomValueTypeInfo(type, typeSize, typeAligment, out var typeInfo))
|
||||||
{
|
{
|
||||||
bool isFloat = hfaTypeInfo.Type.ElementType == ElementType.R4;
|
Debug.Log($"[{GetType().Name}] CustomeValueType:{type} => {typeInfo.CreateSigName()}");
|
||||||
switch (hfaTypeInfo.Count)
|
return typeInfo;
|
||||||
{
|
|
||||||
case 1: return isFloat ? TypeInfo.s_r4 : TypeInfo.s_r8;
|
|
||||||
case 2: return isFloat ? TypeInfo.s_vf2 : TypeInfo.s_vd2;
|
|
||||||
case 3: return isFloat ? TypeInfo.s_vf3 : TypeInfo.s_vd3;
|
|
||||||
case 4: return isFloat ? TypeInfo.s_vf4 : TypeInfo.s_vd4;
|
|
||||||
default: throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (IsSupportWebGLSpecialValueType && IsWebGLSpeicalValueType(type))
|
|
||||||
{
|
|
||||||
switch (typeAligment)
|
|
||||||
{
|
|
||||||
case 1: return new TypeInfo(ParamOrReturnType.SPECIAL_STRUCTURE_ALIGN1, typeSize);
|
|
||||||
case 2: return new TypeInfo(ParamOrReturnType.SPECIAL_STRUCTURE_ALIGN2, typeSize);
|
|
||||||
case 4: return new TypeInfo(ParamOrReturnType.SPECIAL_STRUCTURE_ALIGN4, typeSize);
|
|
||||||
case 8: return new TypeInfo(ParamOrReturnType.SPECIAL_STRUCTURE_ALIGN8, typeSize);
|
|
||||||
default: throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,8 +10,6 @@ namespace HybridCLR.Editor.ABI
|
||||||
{
|
{
|
||||||
public override bool IsArch32 => true;
|
public override bool IsArch32 => true;
|
||||||
|
|
||||||
public override bool IsSupportHFA => false;
|
|
||||||
|
|
||||||
protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType)
|
protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType)
|
||||||
{
|
{
|
||||||
if (type.PorType > ParamOrReturnType.STRUCTURE_ALIGN1 && type.PorType <= ParamOrReturnType.STRUCTURE_ALIGN4)
|
if (type.PorType > ParamOrReturnType.STRUCTURE_ALIGN1 && type.PorType <= ParamOrReturnType.STRUCTURE_ALIGN4)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -10,8 +11,6 @@ namespace HybridCLR.Editor.ABI
|
||||||
{
|
{
|
||||||
public override bool IsArch32 => false;
|
public override bool IsArch32 => false;
|
||||||
|
|
||||||
public override bool IsSupportHFA => false;
|
|
||||||
|
|
||||||
protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType)
|
protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType)
|
||||||
{
|
{
|
||||||
if (type.PorType > ParamOrReturnType.STRUCTURE_ALIGN1 && type.PorType <= ParamOrReturnType.STRUCTURE_ALIGN8)
|
if (type.PorType > ParamOrReturnType.STRUCTURE_ALIGN1 && type.PorType <= ParamOrReturnType.STRUCTURE_ALIGN8)
|
||||||
|
|
|
@ -17,11 +17,6 @@ namespace HybridCLR.Editor.ABI
|
||||||
{
|
{
|
||||||
public override bool IsArch32 => true;
|
public override bool IsArch32 => true;
|
||||||
|
|
||||||
public override bool IsSupportHFA => false;
|
|
||||||
|
|
||||||
public override bool IsSupportWebGLSpecialValueType => true;
|
|
||||||
|
|
||||||
|
|
||||||
protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType)
|
protected override TypeInfo OptimizeSigType(TypeInfo type, bool returnType)
|
||||||
{
|
{
|
||||||
//if (type.PorType > ParamOrReturnType.STRUCTURE_ALIGN1 && type.PorType <= ParamOrReturnType.STRUCTURE_ALIGN4)
|
//if (type.PorType > ParamOrReturnType.STRUCTURE_ALIGN1 && type.PorType <= ParamOrReturnType.STRUCTURE_ALIGN4)
|
||||||
|
@ -30,5 +25,196 @@ namespace HybridCLR.Editor.ABI
|
||||||
//}
|
//}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsEmptyOrSpeicalValueType(TypeSig type)
|
||||||
|
{
|
||||||
|
TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDefThrow();
|
||||||
|
if (typeDef.IsEnum)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var fields = typeDef.Fields;// typeDef.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||||
|
if (fields.Count == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (fields.All(f => f.IsStatic))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (typeDef.IsExplicitLayout && fields.Count(f => !f.IsStatic) > 1)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryComputSingletonStructTypeInfo(TypeSig type, int typeAligment, int typeSize, out TypeInfo typeInfo)
|
||||||
|
{
|
||||||
|
typeInfo = null;
|
||||||
|
if (typeAligment > 8 || typeSize > 8)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var ss = new SingletonStruct();
|
||||||
|
if (!TryComputSingletonStruct0(type, ss) || ss.Type == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ss.Type.IsByRef)
|
||||||
|
{
|
||||||
|
typeInfo = TypeInfo.s_i4;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
switch (ss.Type.ElementType)
|
||||||
|
{
|
||||||
|
case ElementType.Boolean:
|
||||||
|
case ElementType.Char:
|
||||||
|
case ElementType.I1:
|
||||||
|
case ElementType.U1:
|
||||||
|
case ElementType.I2:
|
||||||
|
case ElementType.U2:
|
||||||
|
case ElementType.I4:
|
||||||
|
case ElementType.U4:
|
||||||
|
case ElementType.I:
|
||||||
|
case ElementType.U:
|
||||||
|
case ElementType.String:
|
||||||
|
case ElementType.Ptr:
|
||||||
|
case ElementType.Class:
|
||||||
|
case ElementType.Array:
|
||||||
|
case ElementType.GenericInst:
|
||||||
|
case ElementType.FnPtr:
|
||||||
|
case ElementType.Object:
|
||||||
|
case ElementType.SZArray:
|
||||||
|
{
|
||||||
|
if (typeAligment <= 4 && typeSize <= 4)
|
||||||
|
{
|
||||||
|
typeInfo = TypeInfo.s_i4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ElementType.I8:
|
||||||
|
case ElementType.U8:
|
||||||
|
{
|
||||||
|
if (typeAligment <= 8 && typeSize <= 8)
|
||||||
|
{
|
||||||
|
typeInfo = TypeInfo.s_i8;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ElementType.R4:
|
||||||
|
{
|
||||||
|
if (typeAligment <= 4 && typeSize <= 4)
|
||||||
|
{
|
||||||
|
typeInfo = TypeInfo.s_r4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ElementType.R8:
|
||||||
|
{
|
||||||
|
if (typeAligment <= 8 && typeSize <= 8)
|
||||||
|
{
|
||||||
|
typeInfo = TypeInfo.s_r8;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
return typeInfo != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryComputSingletonStruct(TypeSig type, out SingletonStruct result)
|
||||||
|
{
|
||||||
|
result = new SingletonStruct();
|
||||||
|
return TryComputSingletonStruct0(type, result) && result.Type != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryComputSingletonStruct0(TypeSig type, SingletonStruct result)
|
||||||
|
{
|
||||||
|
TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDefThrow();
|
||||||
|
if (typeDef.IsEnum)
|
||||||
|
{
|
||||||
|
if (result.Type == null)
|
||||||
|
{
|
||||||
|
result.Type = typeDef.GetEnumUnderlyingType();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<TypeSig> klassInst = type.ToGenericInstSig()?.GenericArguments?.ToList();
|
||||||
|
GenericArgumentContext ctx = klassInst != null ? new GenericArgumentContext(klassInst, null) : null;
|
||||||
|
|
||||||
|
var fields = typeDef.Fields;// typeDef.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||||
|
foreach (FieldDef field in fields)
|
||||||
|
{
|
||||||
|
if (field.IsStatic)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TypeSig ftype = ctx != null ? MetaUtil.Inflate(field.FieldType, ctx) : field.FieldType;
|
||||||
|
|
||||||
|
switch (ftype.ElementType)
|
||||||
|
{
|
||||||
|
case ElementType.TypedByRef: return false;
|
||||||
|
case ElementType.ValueType:
|
||||||
|
{
|
||||||
|
if (!TryComputSingletonStruct0(ftype, result))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ElementType.GenericInst:
|
||||||
|
{
|
||||||
|
if (!ftype.IsValueType)
|
||||||
|
{
|
||||||
|
goto default;
|
||||||
|
}
|
||||||
|
if (!TryComputSingletonStruct0(ftype, result))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
if (result.Type != null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
result.Type = ftype;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool TryCreateCustomValueTypeInfo(TypeSig type, int typeSize, int typeAligment, out TypeInfo typeInfo)
|
||||||
|
{
|
||||||
|
typeInfo = null;
|
||||||
|
if (IsEmptyOrSpeicalValueType(type))
|
||||||
|
{
|
||||||
|
switch (typeAligment)
|
||||||
|
{
|
||||||
|
case 1: typeInfo = new TypeInfo(ParamOrReturnType.SPECIAL_STRUCTURE_ALIGN1, typeSize); break;
|
||||||
|
case 2: typeInfo = new TypeInfo(ParamOrReturnType.SPECIAL_STRUCTURE_ALIGN2, typeSize); break;
|
||||||
|
case 4: typeInfo = new TypeInfo(ParamOrReturnType.SPECIAL_STRUCTURE_ALIGN4, typeSize); break;
|
||||||
|
case 8: typeInfo = new TypeInfo(ParamOrReturnType.SPECIAL_STRUCTURE_ALIGN8, typeSize); break;
|
||||||
|
default: throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (TryComputSingletonStructTypeInfo(type, typeAligment, typeSize, out typeInfo))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue