1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 20:12:21 +02:00

Added const expr reflection type

This commit is contained in:
Brian Fiete 2021-12-30 08:38:37 -05:00
parent 674f0f6a56
commit 0eb19245eb
6 changed files with 214 additions and 23 deletions

View file

@ -208,6 +208,14 @@ namespace System
} }
} }
public bool IsConstExpr
{
get
{
return (mTypeFlags & TypeFlags.ConstExpr) != 0;
}
}
public bool IsObject public bool IsObject
{ {
get get
@ -1087,6 +1095,43 @@ namespace System.Reflection
} }
} }
[Ordered, AlwaysInclude(AssumeInstantiated=true)]
class ConstExprType : Type
{
TypeId mValueType;
int64 mValue;
public Type ValueType
{
get
{
return Type.GetType(mValueType);
}
}
public ref int64 ValueData
{
get
{
return ref mValue;
}
}
public override void GetFullName(String strBuffer)
{
strBuffer.Append("const ");
switch (GetType(mValueType))
{
case typeof(float):
(*(float*)&mValue).ToString(strBuffer);
case typeof(double):
(*(double*)&mValue).ToString(strBuffer);
default:
mValue.ToString(strBuffer);
}
}
}
[Ordered, AlwaysInclude(AssumeInstantiated=true)] [Ordered, AlwaysInclude(AssumeInstantiated=true)]
class UnspecializedGenericType : TypeInstance class UnspecializedGenericType : TypeInstance
{ {
@ -1227,11 +1272,12 @@ namespace System.Reflection
SizedArray = 0x1000, SizedArray = 0x1000,
Splattable = 0x2000, Splattable = 0x2000,
Union = 0x4000, Union = 0x4000,
ConstExpr = 0x8000,
// //
WantsMark = 0x8000, WantsMark = 0x10000,
Delegate = 0x10000, Delegate = 0x20000,
Function = 0x20000, Function = 0x40000,
HasDestructor = 0x40000, HasDestructor = 0x80000,
} }
public enum FieldFlags : uint16 public enum FieldFlags : uint16

View file

@ -208,6 +208,14 @@ namespace System
} }
} }
public bool IsConstExpr
{
get
{
return (mTypeFlags & TypeFlags.ConstExpr) != 0;
}
}
public bool IsObject public bool IsObject
{ {
get get
@ -473,6 +481,15 @@ namespace System
} }
static extern Type Comptime_GetTypeById(int32 typeId); static extern Type Comptime_GetTypeById(int32 typeId);
static extern Type Comptime_GetTypeByName(StringView name);
static extern Type Comptime_GetSpecializedType(Type unspecializedType, Span<Type> typeArgs);
static extern bool Comptime_Type_GetCustomAttribute(int32 typeId, int32 attributeId, void* dataPtr);
static extern int32 Comptime_GetMethodCount(int32 typeId);
static extern int64 Comptime_GetMethod(int32 typeId, int32 methodIdx);
static extern String Comptime_Method_ToString(int64 methodHandle);
static extern String Comptime_Method_GetName(int64 methodHandle);
static extern ComptimeMethodInfo.Info Comptime_Method_GetInfo(int64 methodHandle);
static extern ComptimeMethodInfo.ParamInfo Comptime_Method_GetParamInfo(int64 methodHandle, int32 paramIdx);
protected static Type GetType(TypeId typeId) protected static Type GetType(TypeId typeId)
{ {
@ -488,6 +505,19 @@ namespace System
return sTypes[typeId]; return sTypes[typeId];
} }
public static Result<Type> GetTypeByName(StringView typeName)
{
if (Compiler.IsComptime)
{
var type = Comptime_GetTypeByName(typeName);
if (type == null)
return .Err;
return type;
}
return .Err;
}
void GetBasicName(String strBuffer) void GetBasicName(String strBuffer)
{ {
switch (mTypeCode) switch (mTypeCode)
@ -558,8 +588,28 @@ namespace System
return FieldInfo.Enumerator(null, bindingFlags); return FieldInfo.Enumerator(null, bindingFlags);
} }
public bool HasCustomAttribute<T>() where T : Attribute
{
if (Compiler.IsComptime)
{
return Comptime_Type_GetCustomAttribute((int32)TypeId, (.)typeof(T).TypeId, null);
}
if (var typeInstance = this as TypeInstance)
return typeInstance.[Friend]HasCustomAttribute<T>(typeInstance.[Friend]mCustomAttributesIdx);
return false;
}
public Result<T> GetCustomAttribute<T>() where T : Attribute public Result<T> GetCustomAttribute<T>() where T : Attribute
{ {
if (Compiler.IsComptime)
{
T val = ?;
if (Comptime_Type_GetCustomAttribute((int32)TypeId, (.)typeof(T).TypeId, &val))
return val;
return .Err;
}
if (var typeInstance = this as TypeInstance) if (var typeInstance = this as TypeInstance)
return typeInstance.[Friend]GetCustomAttribute<T>(typeInstance.[Friend]mCustomAttributesIdx); return typeInstance.[Friend]GetCustomAttribute<T>(typeInstance.[Friend]mCustomAttributesIdx);
return .Err; return .Err;
@ -578,6 +628,9 @@ namespace System
{ {
while (true) while (true)
{ {
if (Compiler.IsComptime)
Runtime.FatalError("Comptime type enumeration not supported");
if (mCurId >= sTypeCount) if (mCurId >= sTypeCount)
return .Err; return .Err;
let type = sTypes[mCurId++]; let type = sTypes[mCurId++];
@ -639,13 +692,7 @@ namespace System
namespace System.Reflection namespace System.Reflection
{ {
public struct TypeId : int32 public struct TypeId : int32 {}
{
public Type ToType()
{
return Type.[Friend]sTypes[(int32)this];
}
}
[Ordered, AlwaysInclude(AssumeInstantiated=true)] [Ordered, AlwaysInclude(AssumeInstantiated=true)]
public class TypeInstance : Type public class TypeInstance : Type
@ -655,7 +702,10 @@ namespace System.Reflection
{ {
public String mName; public String mName;
public TypeId mFieldTypeId; public TypeId mFieldTypeId;
public int64 mData; public int mData;
#if BF_32_BIT
public int mDataHi;
#endif
public FieldFlags mFlags; public FieldFlags mFlags;
public int32 mCustomAttributesIdx; public int32 mCustomAttributesIdx;
} }
@ -932,9 +982,29 @@ namespace System.Reflection
return FieldInfo.Enumerator(this, bindingFlags); return FieldInfo.Enumerator(this, bindingFlags);
} }
bool HasCustomAttribute<T>(int customAttributeIdx) where T : Attribute
{
if (customAttributeIdx == -1)
return false;
void* data = mCustomAttrDataPtr[customAttributeIdx];
return AttributeInfo.HasCustomAttribute(data, typeof(T));
}
Result<T> GetCustomAttribute<T>(int customAttributeIdx) where T : Attribute Result<T> GetCustomAttribute<T>(int customAttributeIdx) where T : Attribute
{ {
if (customAttributeIdx == -1)
return .Err; return .Err;
void* data = mCustomAttrDataPtr[customAttributeIdx];
T attrInst = ?;
switch (AttributeInfo.GetCustomAttribute(data, typeof(T), &attrInst))
{
case .Ok: return .Ok(attrInst);
default:
return .Err;
}
} }
} }
@ -1025,6 +1095,43 @@ namespace System.Reflection
} }
} }
[Ordered, AlwaysInclude(AssumeInstantiated=true)]
class ConstExprType : Type
{
TypeId mValueType;
int64 mValue;
public Type ValueType
{
get
{
return Type.GetType(mValueType);
}
}
public ref int64 ValueData
{
get
{
return ref mValue;
}
}
public override void GetFullName(String strBuffer)
{
strBuffer.Append("const ");
switch (GetType(mValueType))
{
case typeof(float):
(*(float*)&mValue).ToString(strBuffer);
case typeof(double):
(*(double*)&mValue).ToString(strBuffer);
default:
mValue.ToString(strBuffer);
}
}
}
[Ordered, AlwaysInclude(AssumeInstantiated=true)] [Ordered, AlwaysInclude(AssumeInstantiated=true)]
class UnspecializedGenericType : TypeInstance class UnspecializedGenericType : TypeInstance
{ {
@ -1035,6 +1142,17 @@ namespace System.Reflection
} }
uint8 mGenericParamCount; uint8 mGenericParamCount;
public Result<Type> GetSpecializedType(params Span<Type> typeArgs)
{
if (Compiler.IsComptime)
{
var specializedType = Type.[Friend]Comptime_GetSpecializedType(this, typeArgs);
if (specializedType != null)
return specializedType;
}
return .Err;
}
} }
// Only for resolved types // Only for resolved types
@ -1064,7 +1182,7 @@ namespace System.Reflection
public Type GetGenericArg(int argIdx) public Type GetGenericArg(int argIdx)
{ {
return mResolvedTypeRefs[argIdx].ToType(); return Type.GetType(mResolvedTypeRefs[argIdx]);
} }
public override void GetFullName(String strBuffer) public override void GetFullName(String strBuffer)
@ -1154,11 +1272,12 @@ namespace System.Reflection
SizedArray = 0x1000, SizedArray = 0x1000,
Splattable = 0x2000, Splattable = 0x2000,
Union = 0x4000, Union = 0x4000,
ConstExpr = 0x8000,
// //
WantsMark = 0x8000, WantsMark = 0x10000,
Delegate = 0x10000, Delegate = 0x20000,
Function = 0x20000, Function = 0x40000,
HasDestructor = 0x40000, HasDestructor = 0x80000,
} }
public enum FieldFlags : uint16 public enum FieldFlags : uint16
@ -1180,7 +1299,8 @@ namespace System.Reflection
Const = 0x0040, // Value is compile time constant. Const = 0x0040, // Value is compile time constant.
SpecialName = 0x0080, // field is special. Name describes how. SpecialName = 0x0080, // field is special. Name describes how.
EnumPayload = 0x0100, EnumPayload = 0x0100,
EnumDiscriminator = 0x0200 EnumDiscriminator = 0x0200,
EnumCase = 0x0400
} }
public enum MethodFlags : uint16 public enum MethodFlags : uint16

View file

@ -447,6 +447,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mReflectPointerType = NULL; mReflectPointerType = NULL;
mReflectRefType = NULL; mReflectRefType = NULL;
mReflectSizedArrayType = NULL; mReflectSizedArrayType = NULL;
mReflectConstExprType = NULL;
mReflectSpecializedGenericType = NULL; mReflectSpecializedGenericType = NULL;
mReflectTypeInstanceTypeDef = NULL; mReflectTypeInstanceTypeDef = NULL;
mReflectUnspecializedGenericType = NULL; mReflectUnspecializedGenericType = NULL;
@ -6805,6 +6806,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mReflectPointerType = _GetRequiredType("System.Reflection.PointerType"); mReflectPointerType = _GetRequiredType("System.Reflection.PointerType");
mReflectRefType = _GetRequiredType("System.Reflection.RefType"); mReflectRefType = _GetRequiredType("System.Reflection.RefType");
mReflectSizedArrayType = _GetRequiredType("System.Reflection.SizedArrayType"); mReflectSizedArrayType = _GetRequiredType("System.Reflection.SizedArrayType");
mReflectConstExprType = _GetRequiredType("System.Reflection.ConstExprType");
mReflectSpecializedGenericType = _GetRequiredType("System.Reflection.SpecializedGenericType"); mReflectSpecializedGenericType = _GetRequiredType("System.Reflection.SpecializedGenericType");
mReflectTypeInstanceTypeDef = _GetRequiredType("System.Reflection.TypeInstance"); mReflectTypeInstanceTypeDef = _GetRequiredType("System.Reflection.TypeInstance");
mReflectUnspecializedGenericType = _GetRequiredType("System.Reflection.UnspecializedGenericType"); mReflectUnspecializedGenericType = _GetRequiredType("System.Reflection.UnspecializedGenericType");

View file

@ -402,6 +402,7 @@ public:
BfTypeDef* mReflectPointerType; BfTypeDef* mReflectPointerType;
BfTypeDef* mReflectRefType; BfTypeDef* mReflectRefType;
BfTypeDef* mReflectSizedArrayType; BfTypeDef* mReflectSizedArrayType;
BfTypeDef* mReflectConstExprType;
BfTypeDef* mReflectSpecializedGenericType; BfTypeDef* mReflectSpecializedGenericType;
BfTypeDef* mReflectTypeInstanceTypeDef; BfTypeDef* mReflectTypeInstanceTypeDef;
BfTypeDef* mReflectUnspecializedGenericType; BfTypeDef* mReflectUnspecializedGenericType;

View file

@ -5333,6 +5333,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
typeDataSource = ResolveTypeDef(mCompiler->mReflectRefType)->ToTypeInstance(); typeDataSource = ResolveTypeDef(mCompiler->mReflectRefType)->ToTypeInstance();
else if (type->IsSizedArray()) else if (type->IsSizedArray())
typeDataSource = ResolveTypeDef(mCompiler->mReflectSizedArrayType)->ToTypeInstance(); typeDataSource = ResolveTypeDef(mCompiler->mReflectSizedArrayType)->ToTypeInstance();
else if (type->IsConstExprValue())
typeDataSource = ResolveTypeDef(mCompiler->mReflectConstExprType)->ToTypeInstance();
else else
typeDataSource = mContext->mBfTypeType; typeDataSource = mContext->mBfTypeType;
@ -5430,6 +5432,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
typeFlags |= BfTypeFlags_Nullable; typeFlags |= BfTypeFlags_Nullable;
if (type->IsSizedArray()) if (type->IsSizedArray())
typeFlags |= BfTypeFlags_SizedArray; typeFlags |= BfTypeFlags_SizedArray;
if (type->IsConstExprValue())
typeFlags |= BfTypeFlags_ConstExpr;
if (type->IsSplattable()) if (type->IsSplattable())
typeFlags |= BfTypeFlags_Splattable; typeFlags |= BfTypeFlags_Splattable;
if (type->IsUnion()) if (type->IsUnion())
@ -5545,6 +5549,23 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize); mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize);
typeDataVar = mBfIRBuilder->CreateBitCast(typeDataVar, mBfIRBuilder->MapType(mContext->mBfTypeType)); typeDataVar = mBfIRBuilder->CreateBitCast(typeDataVar, mBfIRBuilder->MapType(mContext->mBfTypeType));
} }
else if (type->IsConstExprValue())
{
auto constExprType = (BfConstExprValueType*)type;
SizedArray<BfIRValue, 3> constExprTypeDataParms =
{
typeData,
GetConstValue(constExprType->mType->mTypeId, typeIdType),
GetConstValue(constExprType->mValue.mInt64, longType)
};
auto reflectConstExprType = ResolveTypeDef(mCompiler->mReflectConstExprType)->ToTypeInstance();
auto ConstExprTypeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectConstExprType, BfIRPopulateType_Full), constExprTypeDataParms);
typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(reflectConstExprType), true,
BfIRLinkageType_External, ConstExprTypeData, typeDataName);
mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize);
typeDataVar = mBfIRBuilder->CreateBitCast(typeDataVar, mBfIRBuilder->MapType(mContext->mBfTypeType));
}
else else
{ {
typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(mContext->mBfTypeType), true, typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(mContext->mBfTypeType), true,

View file

@ -180,11 +180,12 @@ enum BfTypeFlags
BfTypeFlags_SizedArray = 0x1000, BfTypeFlags_SizedArray = 0x1000,
BfTypeFlags_Splattable = 0x2000, BfTypeFlags_Splattable = 0x2000,
BfTypeFlags_Union = 0x4000, BfTypeFlags_Union = 0x4000,
BfTypeFlags_ConstExpr = 0x8000,
// //
BfTypeFlags_WantsMarking = 0x8000, BfTypeFlags_WantsMarking = 0x10000,
BfTypeFlags_Delegate = 0x10000, BfTypeFlags_Delegate = 0x20000,
BfTypeFlags_Function = 0x20000, BfTypeFlags_Function = 0x40000,
BfTypeFlags_HasDestructor = 0x40000, BfTypeFlags_HasDestructor = 0x80000,
}; };
enum BfMethodFlags enum BfMethodFlags