1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

Reflection fixes for static values

This commit is contained in:
Brian Fiete 2020-07-06 09:55:19 -07:00
parent 78dd56d6c5
commit 6cd66a2182
9 changed files with 165 additions and 99 deletions

View file

@ -8,7 +8,7 @@ namespace System
{ {
for (var field in type.GetFields()) for (var field in type.GetFields())
{ {
if (field.[Friend]mFieldData.[Friend]mConstValue == iVal) if (field.[Friend]mFieldData.[Friend]mData == iVal)
{ {
strBuffer.Append(field.Name); strBuffer.Append(field.Name);
return; return;
@ -24,7 +24,7 @@ namespace System
for (var field in typeInst.GetFields()) for (var field in typeInst.GetFields())
{ {
if (str.Equals(field.[Friend]mFieldData.mName, ignoreCase)) if (str.Equals(field.[Friend]mFieldData.mName, ignoreCase))
return .Ok(*((T*)(&field.[Friend]mFieldData.mConstValue))); return .Ok(*((T*)(&field.[Friend]mFieldData.mData)));
} }
return .Err; return .Err;

View file

@ -24,7 +24,7 @@ namespace System.Reflection
{ {
get get
{ {
return mFieldData.mDataOffset; return (int32)mFieldData.mData;
} }
} }
@ -64,7 +64,7 @@ namespace System.Reflection
} }
Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId); Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId);
void* fieldDataAddr = ((uint8*)Internal.UnsafeCastToPtr(obj)) + mFieldData.mDataOffset + dataOffsetAdjust; void* fieldDataAddr = ((uint8*)Internal.UnsafeCastToPtr(obj)) + (int)mFieldData.mData + dataOffsetAdjust;
if (value == null) if (value == null)
{ {
@ -123,7 +123,7 @@ namespace System.Reflection
Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId); Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId);
void* dataAddr = ((uint8*)Internal.UnsafeCastToPtr(obj)) + mFieldData.mDataOffset + dataOffsetAdjust; void* dataAddr = ((uint8*)Internal.UnsafeCastToPtr(obj)) + (int)mFieldData.mData + dataOffsetAdjust;
if (value.VariantType != fieldType) if (value.VariantType != fieldType)
return .Err;//("Invalid type"); return .Err;//("Invalid type");
@ -158,19 +158,37 @@ namespace System.Reflection
{ {
value = default(TMember); value = default(TMember);
Type tTarget; void* targetDataAddr;
void* targetDataAddr = GetDataPtrAndType(target, out tTarget); if (target == null)
{
if (mFieldData.mFlags.HasFlag(FieldFlags.Const))
{
// Unhandled
return .Err;
}
if (!mFieldData.mFlags.HasFlag(FieldFlags.Static))
return .Err;
targetDataAddr = null;
}
else
{
Type tTarget;
targetDataAddr = GetDataPtrAndType(target, out tTarget);
if (!tTarget.IsSubtypeOf(mTypeInstance))
return .Err; //"Invalid type");
}
Type tMember = typeof(TMember); Type tMember = typeof(TMember);
targetDataAddr = (uint8*)targetDataAddr + mFieldData.mDataOffset; targetDataAddr = (uint8*)targetDataAddr + (int)mFieldData.mData;
Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId); Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId);
if (tMember.[Friend]mTypeCode == TypeCode.Object) if (tMember.[Friend]mTypeCode == TypeCode.Object)
{ {
if (!tTarget.IsSubtypeOf(mTypeInstance))
Runtime.FatalError();
value = *(TMember*)targetDataAddr; value = *(TMember*)targetDataAddr;
} }
else if (fieldType.[Friend]mTypeCode == tMember.[Friend]mTypeCode) else if (fieldType.[Friend]mTypeCode == tMember.[Friend]mTypeCode)
@ -189,13 +207,29 @@ namespace System.Reflection
{ {
Variant value = Variant(); Variant value = Variant();
Type tTarget; void* targetDataAddr;
void* targetDataAddr = GetDataPtrAndType(target, out tTarget); if (target == null)
{
if (mFieldData.mFlags.HasFlag(FieldFlags.Const))
{
return Variant.Create(FieldType, &mFieldData.mData);
}
if (!tTarget.IsSubtypeOf(mTypeInstance)) if (!mFieldData.mFlags.HasFlag(FieldFlags.Static))
Runtime.FatalError("Invalid type"); return .Err;
targetDataAddr = (uint8*)targetDataAddr + mFieldData.mDataOffset; targetDataAddr = null;
}
else
{
Type tTarget;
targetDataAddr = GetDataPtrAndType(target, out tTarget);
if (!tTarget.IsSubtypeOf(mTypeInstance))
return .Err; //Invalid type;
}
targetDataAddr = (uint8*)targetDataAddr + (int)mFieldData.mData;
Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId); Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId);
@ -220,13 +254,29 @@ namespace System.Reflection
{ {
Variant value = Variant(); Variant value = Variant();
Type tTarget; void* targetDataAddr;
void* targetDataAddr = GetDataPtrAndType(target, out tTarget); if (target == null)
{
if (mFieldData.mFlags.HasFlag(FieldFlags.Const))
{
return Variant.Create(FieldType, &mFieldData.mData);
}
if (!tTarget.IsSubtypeOf(mTypeInstance)) if (!mFieldData.mFlags.HasFlag(FieldFlags.Static))
Runtime.FatalError("Invalid type"); return .Err;
targetDataAddr = (uint8*)targetDataAddr + mFieldData.mDataOffset; targetDataAddr = null;
}
else
{
Type tTarget;
targetDataAddr = GetDataPtrAndType(target, out tTarget);
if (!tTarget.IsSubtypeOf(mTypeInstance))
return .Err; //Invalid type;
}
targetDataAddr = (uint8*)targetDataAddr + (int)mFieldData.mData;
Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId); Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId);
@ -239,48 +289,6 @@ namespace System.Reflection
return value; return value;
} }
public Result<Variant> GetValue()
{
Variant value = Variant();
//TODO: Assert static
if (mFieldData.mFlags.HasFlag(FieldFlags.Const))
{
return Variant.Create(FieldType, &mFieldData.mConstValue);
}
ThrowUnimplemented();
//Type tTarget;
#unwarn
void* targetDataAddr = (void*)(int)mFieldData.mConstValue;
Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId);
value.[Friend]mStructType = (int)Internal.UnsafeCastToPtr(fieldType);
TypeCode typeCode = fieldType.[Friend]mTypeCode;
if (typeCode == TypeCode.Enum)
typeCode = fieldType.UnderlyingType.[Friend]mTypeCode;
if (typeCode == TypeCode.Int32)
{
*(int32*)&value.[Friend]mData = *(int32*)targetDataAddr;
}
else if (typeCode == TypeCode.Object)
{
value.[Friend]mStructType = 0;
value.[Friend]mData = (int)targetDataAddr;
}
else
{
return .Err;
}
return value;
}
public struct Enumerator : IEnumerator<FieldInfo> public struct Enumerator : IEnumerator<FieldInfo>
{ {
BindingFlags mBindingFlags; BindingFlags mBindingFlags;

View file

@ -105,12 +105,12 @@ namespace System.Reflection
if (fieldType.IsStruct) if (fieldType.IsStruct)
{ {
SplatArg((TypeInstance)fieldType, (uint8*)ptr + fieldData.mDataOffset); SplatArg((TypeInstance)fieldType, (uint8*)ptr + (int)fieldData.mData);
} }
else else
{ {
ffiParamList.Add(FFIType.Get(fieldType, null, null)); ffiParamList.Add(FFIType.Get(fieldType, null, null));
ffiArgList.Add((uint8*)ptr + fieldData.mDataOffset); ffiArgList.Add((uint8*)ptr + (int)fieldData.mData);
} }
} }
} }
@ -387,12 +387,12 @@ namespace System.Reflection
if (fieldType.IsStruct) if (fieldType.IsStruct)
{ {
SplatArg((TypeInstance)fieldType, (uint8*)ptr + fieldData.mDataOffset); SplatArg((TypeInstance)fieldType, (uint8*)ptr + (int)fieldData.mData);
} }
else else
{ {
ffiParamList.Add(FFIType.Get(fieldType, null, null)); ffiParamList.Add(FFIType.Get(fieldType, null, null));
ffiArgList.Add((uint8*)ptr + fieldData.mDataOffset); ffiArgList.Add((uint8*)ptr + (int)fieldData.mData);
} }
} }
} }

View file

@ -607,8 +607,7 @@ namespace System.Reflection
public struct FieldData public struct FieldData
{ {
public String mName; public String mName;
public int64 mConstValue; public int64 mData;
public int32 mDataOffset;
public TypeId mFieldTypeId; public TypeId mFieldTypeId;
public FieldFlags mFlags; public FieldFlags mFlags;
public int32 mCustomAttributesIdx; public int32 mCustomAttributesIdx;

View file

@ -478,7 +478,7 @@ namespace System
for (var field in typeInst.GetFields()) for (var field in typeInst.GetFields())
{ {
if (str == field.[Friend]mFieldData.mName) if (str == field.[Friend]mFieldData.mName)
return .Ok(*((T*)(&field.[Friend]mFieldData.mConstValue))); return .Ok(*((T*)(&field.[Friend]mFieldData.mData)));
} }
return .Err; return .Err;

View file

@ -24,7 +24,7 @@ namespace System.Reflection
{ {
get get
{ {
return mFieldData.mDataOffset; return (int32)mFieldData.mData;
} }
} }
@ -64,7 +64,7 @@ namespace System.Reflection
} }
Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId); Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId);
void* fieldDataAddr = ((uint8*)(void*)obj) + mFieldData.mDataOffset + dataOffsetAdjust; void* fieldDataAddr = ((uint8*)(void*)obj) + mFieldData.mData + dataOffsetAdjust;
Type rawValueType = value.[Friend]RawGetType(); Type rawValueType = value.[Friend]RawGetType();
void* valueDataAddr = ((uint8*)(void*)value) + rawValueType.[Friend]mMemberDataOffset; void* valueDataAddr = ((uint8*)(void*)value) + rawValueType.[Friend]mMemberDataOffset;
@ -123,7 +123,7 @@ namespace System.Reflection
Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId); Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId);
void* dataAddr = ((uint8*)(void*)obj) + mFieldData.mDataOffset + dataOffsetAdjust; void* dataAddr = ((uint8*)(void*)obj) + mFieldData.mData + dataOffsetAdjust;
if (value.VariantType != fieldType) if (value.VariantType != fieldType)
return .Err;//("Invalid type"); return .Err;//("Invalid type");
@ -175,7 +175,7 @@ namespace System.Reflection
Type tMember = typeof(TMember); Type tMember = typeof(TMember);
targetDataAddr = (uint8*)targetDataAddr + mFieldData.mDataOffset; targetDataAddr = (uint8*)targetDataAddr + mFieldData.mData;
Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId); Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId);
@ -207,7 +207,7 @@ namespace System.Reflection
if (!tTarget.IsSubtypeOf(mTypeInstance)) if (!tTarget.IsSubtypeOf(mTypeInstance))
Runtime.FatalError("Invalid type"); Runtime.FatalError("Invalid type");
targetDataAddr = (uint8*)targetDataAddr + mFieldData.mDataOffset; targetDataAddr = (uint8*)targetDataAddr + mFieldData.mData;
Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId); Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId);
@ -236,14 +236,14 @@ namespace System.Reflection
if (mFieldData.mFlags.HasFlag(FieldFlags.Const)) if (mFieldData.mFlags.HasFlag(FieldFlags.Const))
{ {
return Variant.Create(FieldType, &mFieldData.mConstValue); return Variant.Create(FieldType, &mFieldData.mData);
} }
ThrowUnimplemented(); ThrowUnimplemented();
//Type tTarget; //Type tTarget;
#unwarn #unwarn
void* targetDataAddr = (void*)(int)mFieldData.mConstValue; void* targetDataAddr = (void*)(int)mFieldData.mData;
Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId); Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId);
value.[Friend]mStructType = (int)Internal.UnsafeCastToPtr(fieldType); value.[Friend]mStructType = (int)Internal.UnsafeCastToPtr(fieldType);

View file

@ -246,12 +246,27 @@ namespace System
} }
} }
public bool IsBoxedStructPtr public Type BoxedPtrType
{ {
get get
{ {
return (mTypeFlags & (TypeFlags.Boxed | TypeFlags.Pointer)) == TypeFlags.Boxed | TypeFlags.Pointer; if (!mTypeFlags.HasFlag(.Boxed))
} return null;
if (mTypeFlags.HasFlag(.Pointer))
{
return UnderlyingType;
}
let underyingType = UnderlyingType;
if (var genericTypeInstance = underyingType as SpecializedGenericType)
{
if (genericTypeInstance.UnspecializedType == typeof(Pointer<>))
return genericTypeInstance.GetGenericArg(0);
}
return null;
}
} }
public bool IsEnum public bool IsEnum
@ -532,6 +547,7 @@ namespace System
Char32, Char32,
Float, Float,
Double, Double,
Float2,
Object, Object,
Interface, Interface,
Struct, Struct,
@ -558,8 +574,7 @@ namespace System.Reflection
public struct FieldData public struct FieldData
{ {
public String mName; public String mName;
public int64 mConstValue; public int64 mData;
public int32 mDataOffset;
public TypeId mFieldTypeId; public TypeId mFieldTypeId;
public FieldFlags mFlags; public FieldFlags mFlags;
public int32 mCustomAttributesIdx; public int32 mCustomAttributesIdx;
@ -708,6 +723,12 @@ namespace System.Reflection
} }
strBuffer.Append(')'); strBuffer.Append(')');
} }
else if (mTypeFlags.HasFlag(.Boxed))
{
strBuffer.Append("boxed ");
let ut = UnderlyingType;
ut.GetFullName(strBuffer);
}
else else
{ {
if (mOuterType != 0) if (mOuterType != 0)
@ -721,7 +742,8 @@ namespace System.Reflection
strBuffer.Append(mNamespace, "."); strBuffer.Append(mNamespace, ".");
} }
strBuffer.Append(mName); if (mName != null)
strBuffer.Append(mName);
} }
} }
@ -853,6 +875,14 @@ namespace System.Reflection
TypeId mUnspecializedType; TypeId mUnspecializedType;
TypeId* mResolvedTypeRefs; TypeId* mResolvedTypeRefs;
public Type UnspecializedType
{
get
{
return Type.[Friend]GetType(mUnspecializedType);
}
}
public override int32 GenericParamCount public override int32 GenericParamCount
{ {
get get

View file

@ -5761,8 +5761,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
{ {
emptyValueType, emptyValueType,
payloadNameConst, // mName payloadNameConst, // mName
GetConstValue(0, longType), // mConstValue GetConstValue(0, longType), // mData
GetConstValue(0, intType), // mDataOffset
GetConstValue(payloadType->mTypeId, typeIdType), // mFieldTypeId GetConstValue(payloadType->mTypeId, typeIdType), // mFieldTypeId
GetConstValue(FieldFlags_SpecialName | FieldFlags_EnumPayload, shortType), // mFlags GetConstValue(FieldFlags_SpecialName | FieldFlags_EnumPayload, shortType), // mFlags
GetConstValue(-1, intType), // mCustomAttributesIdx GetConstValue(-1, intType), // mCustomAttributesIdx
@ -5777,8 +5776,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
{ {
emptyValueType, emptyValueType,
dscrNameConst, // mName dscrNameConst, // mName
GetConstValue(0, longType), // mConstValue GetConstValue(BF_ALIGN(payloadType->mSize, dscrType->mAlign), longType), // mData
GetConstValue(BF_ALIGN(payloadType->mSize, dscrType->mAlign), intType), // mDataOffset
GetConstValue(dscrType->mTypeId, typeIdType), // mFieldTypeId GetConstValue(dscrType->mTypeId, typeIdType), // mFieldTypeId
GetConstValue(FieldFlags_SpecialName | FieldFlags_EnumDiscriminator, shortType), // mFlags GetConstValue(FieldFlags_SpecialName | FieldFlags_EnumDiscriminator, shortType), // mFlags
GetConstValue(-1, intType), // mCustomAttributesIdx GetConstValue(-1, intType), // mCustomAttributesIdx
@ -5818,7 +5816,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
fieldFlags = (FieldFlags)(fieldFlags | FieldFlags_Const); fieldFlags = (FieldFlags)(fieldFlags | FieldFlags_Const);
int customAttrIdx = _HandleCustomAttrs(fieldInstance->mCustomAttributes); int customAttrIdx = _HandleCustomAttrs(fieldInstance->mCustomAttributes);
BfIRValue constValue = GetConstValue(0, longType); BfIRValue constValue;
if (fieldInstance->GetFieldDef()->mIsConst) if (fieldInstance->GetFieldDef()->mIsConst)
{ {
if (fieldInstance->mConstIdx != -1) if (fieldInstance->mConstIdx != -1)
@ -5827,13 +5825,23 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
constValue = mBfIRBuilder->CreateConst(BfTypeCode_UInt64, constant->mUInt64); constValue = mBfIRBuilder->CreateConst(BfTypeCode_UInt64, constant->mUInt64);
} }
} }
else if (fieldInstance->GetFieldDef()->mIsStatic)
{
auto refVal = ReferenceStaticField(fieldInstance);
if (refVal.IsAddr())
constValue = mBfIRBuilder->CreatePtrToInt(refVal.mValue, BfTypeCode_Int64);
}
if (!constValue)
{
constValue = GetConstValue(fieldInstance->mDataOffset, longType);
}
SizedArray<BfIRValue, 8> fieldVals = SizedArray<BfIRValue, 8> fieldVals =
{ {
emptyValueType, emptyValueType,
fieldNameConst, // mName fieldNameConst, // mName
constValue, // mConstValue constValue, // mConstValue
GetConstValue(fieldInstance->mDataOffset, intType), // mDataOffset
GetConstValue(typeId, typeIdType), // mFieldTypeId GetConstValue(typeId, typeIdType), // mFieldTypeId
GetConstValue(fieldFlags, shortType), // mFlags GetConstValue(fieldFlags, shortType), // mFlags
GetConstValue(customAttrIdx, intType), // mCustomAttributesIdx GetConstValue(customAttrIdx, intType), // mCustomAttributesIdx

View file

@ -53,8 +53,11 @@ namespace Tests
[Reflect] [Reflect]
class ClassA class ClassA
{ {
int32 mA = 123; public int32 mA = 123;
String mStr = "A"; public String mStr = "A";
public static int32 sA = 234;
public static String sStr = "AA";
[AlwaysInclude, AttrC(71, 72)] [AlwaysInclude, AttrC(71, 72)]
static float StaticMethodA(int32 a, int32 b, float c, ref int32 d, ref StructA sa) static float StaticMethodA(int32 a, int32 b, float c, ref int32 d, ref StructA sa)
@ -237,6 +240,8 @@ namespace Tests
Test.Assert(fieldStrV.Get<String>() == "A"); Test.Assert(fieldStrV.Get<String>() == "A");
var res = methodInfo.Invoke(.(), fieldAV, fieldStrV).Value; var res = methodInfo.Invoke(.(), fieldAV, fieldStrV).Value;
Test.Assert(ca.mA == 1123);
Test.Assert(ca.mB == "B");
var sa = res.Get<StructA>(); var sa = res.Get<StructA>();
Test.Assert(sa.mA == 12); Test.Assert(sa.mA == 12);
Test.Assert(sa.mB == 34); Test.Assert(sa.mB == 34);
@ -253,6 +258,22 @@ namespace Tests
Test.Assert(fieldStrV.Get<String>() == "B"); Test.Assert(fieldStrV.Get<String>() == "B");
fieldAV.Dispose(); fieldAV.Dispose();
fieldStrV.Dispose(); fieldStrV.Dispose();
var fieldSA = typeInfo.GetField("sA").Value;
var fieldSStr = typeInfo.GetField("sStr").Value;
var fieldSAV = fieldSA.GetValueReference(null).Value;
var fieldSStrV = fieldSStr.GetValueReference(null).Value;
Test.Assert(fieldSAV.Get<int32>() == 234);
Test.Assert(fieldSStrV.Get<String>() == "AA");
res = methodInfo.Invoke(.(), fieldSAV, fieldSStrV).Value;
Test.Assert(fieldSAV.Get<int32>() == 1234);
Test.Assert(fieldSStrV.Get<String>() == "B");
Test.Assert(ClassA.sA == 1234);
Test.Assert(ClassA.sStr == "B");
res.Dispose();
fieldSAV.Dispose();
fieldSStrV.Dispose();
case 2: case 2:
Test.Assert(methodInfo.Name == "MemberMethodA"); Test.Assert(methodInfo.Name == "MemberMethodA");
var result = methodInfo.Invoke(ca, 100, (int32)20, 3.0f).Get(); var result = methodInfo.Invoke(ca, 100, (int32)20, 3.0f).Get();