diff --git a/BeefLibs/corlib/src/Type.bf b/BeefLibs/corlib/src/Type.bf index e78108f8..08b7c865 100644 --- a/BeefLibs/corlib/src/Type.bf +++ b/BeefLibs/corlib/src/Type.bf @@ -208,6 +208,14 @@ namespace System } } + public bool IsConstExpr + { + get + { + return (mTypeFlags & TypeFlags.ConstExpr) != 0; + } + } + public bool IsObject { 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)] class UnspecializedGenericType : TypeInstance { @@ -1227,11 +1272,12 @@ namespace System.Reflection SizedArray = 0x1000, Splattable = 0x2000, Union = 0x4000, + ConstExpr = 0x8000, // - WantsMark = 0x8000, - Delegate = 0x10000, - Function = 0x20000, - HasDestructor = 0x40000, + WantsMark = 0x10000, + Delegate = 0x20000, + Function = 0x40000, + HasDestructor = 0x80000, } public enum FieldFlags : uint16 diff --git a/IDE/mintest/minlib/src/System/Type.bf b/IDE/mintest/minlib/src/System/Type.bf index 9a7a0601..08b7c865 100644 --- a/IDE/mintest/minlib/src/System/Type.bf +++ b/IDE/mintest/minlib/src/System/Type.bf @@ -208,6 +208,14 @@ namespace System } } + public bool IsConstExpr + { + get + { + return (mTypeFlags & TypeFlags.ConstExpr) != 0; + } + } + public bool IsObject { get @@ -473,6 +481,15 @@ namespace System } static extern Type Comptime_GetTypeById(int32 typeId); + static extern Type Comptime_GetTypeByName(StringView name); + static extern Type Comptime_GetSpecializedType(Type unspecializedType, Span 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) { @@ -488,6 +505,19 @@ namespace System return sTypes[typeId]; } + public static Result GetTypeByName(StringView typeName) + { + if (Compiler.IsComptime) + { + var type = Comptime_GetTypeByName(typeName); + if (type == null) + return .Err; + return type; + } + + return .Err; + } + void GetBasicName(String strBuffer) { switch (mTypeCode) @@ -558,8 +588,28 @@ namespace System return FieldInfo.Enumerator(null, bindingFlags); } + public bool HasCustomAttribute() 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(typeInstance.[Friend]mCustomAttributesIdx); + return false; + } + public Result GetCustomAttribute() 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) return typeInstance.[Friend]GetCustomAttribute(typeInstance.[Friend]mCustomAttributesIdx); return .Err; @@ -578,6 +628,9 @@ namespace System { while (true) { + if (Compiler.IsComptime) + Runtime.FatalError("Comptime type enumeration not supported"); + if (mCurId >= sTypeCount) return .Err; let type = sTypes[mCurId++]; @@ -639,13 +692,7 @@ namespace System namespace System.Reflection { - public struct TypeId : int32 - { - public Type ToType() - { - return Type.[Friend]sTypes[(int32)this]; - } - } + public struct TypeId : int32 {} [Ordered, AlwaysInclude(AssumeInstantiated=true)] public class TypeInstance : Type @@ -655,7 +702,10 @@ namespace System.Reflection { public String mName; public TypeId mFieldTypeId; - public int64 mData; + public int mData; +#if BF_32_BIT + public int mDataHi; +#endif public FieldFlags mFlags; public int32 mCustomAttributesIdx; } @@ -932,9 +982,29 @@ namespace System.Reflection return FieldInfo.Enumerator(this, bindingFlags); } + bool HasCustomAttribute(int customAttributeIdx) where T : Attribute + { + if (customAttributeIdx == -1) + return false; + + void* data = mCustomAttrDataPtr[customAttributeIdx]; + return AttributeInfo.HasCustomAttribute(data, typeof(T)); + } + Result GetCustomAttribute(int customAttributeIdx) where T : Attribute { - return .Err; + if (customAttributeIdx == -1) + 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)] class UnspecializedGenericType : TypeInstance { @@ -1035,6 +1142,17 @@ namespace System.Reflection } uint8 mGenericParamCount; + + public Result GetSpecializedType(params Span typeArgs) + { + if (Compiler.IsComptime) + { + var specializedType = Type.[Friend]Comptime_GetSpecializedType(this, typeArgs); + if (specializedType != null) + return specializedType; + } + return .Err; + } } // Only for resolved types @@ -1064,7 +1182,7 @@ namespace System.Reflection public Type GetGenericArg(int argIdx) { - return mResolvedTypeRefs[argIdx].ToType(); + return Type.GetType(mResolvedTypeRefs[argIdx]); } public override void GetFullName(String strBuffer) @@ -1154,11 +1272,12 @@ namespace System.Reflection SizedArray = 0x1000, Splattable = 0x2000, Union = 0x4000, + ConstExpr = 0x8000, // - WantsMark = 0x8000, - Delegate = 0x10000, - Function = 0x20000, - HasDestructor = 0x40000, + WantsMark = 0x10000, + Delegate = 0x20000, + Function = 0x40000, + HasDestructor = 0x80000, } public enum FieldFlags : uint16 @@ -1180,7 +1299,8 @@ namespace System.Reflection Const = 0x0040, // Value is compile time constant. SpecialName = 0x0080, // field is special. Name describes how. EnumPayload = 0x0100, - EnumDiscriminator = 0x0200 + EnumDiscriminator = 0x0200, + EnumCase = 0x0400 } public enum MethodFlags : uint16 diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index bdf49e2f..54398637 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -447,6 +447,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) mReflectPointerType = NULL; mReflectRefType = NULL; mReflectSizedArrayType = NULL; + mReflectConstExprType = NULL; mReflectSpecializedGenericType = NULL; mReflectTypeInstanceTypeDef = NULL; mReflectUnspecializedGenericType = NULL; @@ -6805,6 +6806,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) mReflectPointerType = _GetRequiredType("System.Reflection.PointerType"); mReflectRefType = _GetRequiredType("System.Reflection.RefType"); mReflectSizedArrayType = _GetRequiredType("System.Reflection.SizedArrayType"); + mReflectConstExprType = _GetRequiredType("System.Reflection.ConstExprType"); mReflectSpecializedGenericType = _GetRequiredType("System.Reflection.SpecializedGenericType"); mReflectTypeInstanceTypeDef = _GetRequiredType("System.Reflection.TypeInstance"); mReflectUnspecializedGenericType = _GetRequiredType("System.Reflection.UnspecializedGenericType"); diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index ceb327e3..ed840e29 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -402,6 +402,7 @@ public: BfTypeDef* mReflectPointerType; BfTypeDef* mReflectRefType; BfTypeDef* mReflectSizedArrayType; + BfTypeDef* mReflectConstExprType; BfTypeDef* mReflectSpecializedGenericType; BfTypeDef* mReflectTypeInstanceTypeDef; BfTypeDef* mReflectUnspecializedGenericType; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 15cfe10c..de5789e5 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -5333,6 +5333,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin typeDataSource = ResolveTypeDef(mCompiler->mReflectRefType)->ToTypeInstance(); else if (type->IsSizedArray()) typeDataSource = ResolveTypeDef(mCompiler->mReflectSizedArrayType)->ToTypeInstance(); + else if (type->IsConstExprValue()) + typeDataSource = ResolveTypeDef(mCompiler->mReflectConstExprType)->ToTypeInstance(); else typeDataSource = mContext->mBfTypeType; @@ -5430,6 +5432,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin typeFlags |= BfTypeFlags_Nullable; if (type->IsSizedArray()) typeFlags |= BfTypeFlags_SizedArray; + if (type->IsConstExprValue()) + typeFlags |= BfTypeFlags_ConstExpr; if (type->IsSplattable()) typeFlags |= BfTypeFlags_Splattable; if (type->IsUnion()) @@ -5545,6 +5549,23 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize); typeDataVar = mBfIRBuilder->CreateBitCast(typeDataVar, mBfIRBuilder->MapType(mContext->mBfTypeType)); } + else if (type->IsConstExprValue()) + { + auto constExprType = (BfConstExprValueType*)type; + SizedArray 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 { typeDataVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapTypeInst(mContext->mBfTypeType), true, diff --git a/IDEHelper/Compiler/BfSystem.h b/IDEHelper/Compiler/BfSystem.h index 83900000..b26fb876 100644 --- a/IDEHelper/Compiler/BfSystem.h +++ b/IDEHelper/Compiler/BfSystem.h @@ -180,11 +180,12 @@ enum BfTypeFlags BfTypeFlags_SizedArray = 0x1000, BfTypeFlags_Splattable = 0x2000, BfTypeFlags_Union = 0x4000, + BfTypeFlags_ConstExpr = 0x8000, // - BfTypeFlags_WantsMarking = 0x8000, - BfTypeFlags_Delegate = 0x10000, - BfTypeFlags_Function = 0x20000, - BfTypeFlags_HasDestructor = 0x40000, + BfTypeFlags_WantsMarking = 0x10000, + BfTypeFlags_Delegate = 0x20000, + BfTypeFlags_Function = 0x40000, + BfTypeFlags_HasDestructor = 0x80000, }; enum BfMethodFlags