From c511773dad41dcc92369e0340d844fbb309d6c99 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sun, 19 Jan 2025 12:40:50 -0800 Subject: [PATCH] Added typeof_comptime const type --- .../corlib/src/Reflection/AttributeInfo.bf | 4 +-- IDEHelper/Backend/BeIRCodeGen.cpp | 12 ++++++- IDEHelper/Backend/BeModule.cpp | 7 ++++ IDEHelper/Backend/BeModule.h | 14 ++++++++ IDEHelper/Compiler/BfIRBuilder.cpp | 35 +++++++++++++++++-- IDEHelper/Compiler/BfIRBuilder.h | 2 ++ IDEHelper/Compiler/BfModule.cpp | 7 ++-- IDEHelper/Compiler/BfModule.h | 2 +- IDEHelper/Compiler/CeMachine.cpp | 11 ++++++ IDEHelper/Tests/src/Comptime.bf | 27 ++++++++++++-- 10 files changed, 111 insertions(+), 10 deletions(-) diff --git a/BeefLibs/corlib/src/Reflection/AttributeInfo.bf b/BeefLibs/corlib/src/Reflection/AttributeInfo.bf index 7c66bc4f..5194d881 100644 --- a/BeefLibs/corlib/src/Reflection/AttributeInfo.bf +++ b/BeefLibs/corlib/src/Reflection/AttributeInfo.bf @@ -104,7 +104,7 @@ namespace System.Reflection case (TypeCode)typeof(TypeCode).MaxValue + 9: //BfConstType_TypeOf let argTypeId = Decode!(data); args[argIdx] = Type.[Friend]GetType((.)argTypeId); - case (TypeCode)typeof(TypeCode).MaxValue + 18: // BfConstType_Box + case (TypeCode)typeof(TypeCode).MaxValue + 19: // BfConstType_Box let boxedTypeId = Decode!(data); var boxedType = Type.[Friend]GetType_(boxedTypeId); int dataSize = boxedType.InstanceSize - boxedType.[Friend]mMemberDataOffset; @@ -216,7 +216,7 @@ namespace System.Reflection case (TypeCode)typeof(TypeCode).MaxValue + 9: //BfConstType_TypeOf let argTypeId = AttributeInfo.Decode!(mData); args[argIdx] = Variant.Create(Type.[Friend]GetType((.)argTypeId)); - case (TypeCode)typeof(TypeCode).MaxValue + 18: // BfConstType_Box + case (TypeCode)typeof(TypeCode).MaxValue + 19: // BfConstType_Box let boxedTypeId = AttributeInfo.Decode!(mData); var boxedType = Type.[Friend]GetType_(boxedTypeId); int dataSize = boxedType.InstanceSize - boxedType.[Friend]mMemberDataOffset; diff --git a/IDEHelper/Backend/BeIRCodeGen.cpp b/IDEHelper/Backend/BeIRCodeGen.cpp index 97c06ec8..4e22e0e3 100644 --- a/IDEHelper/Backend/BeIRCodeGen.cpp +++ b/IDEHelper/Backend/BeIRCodeGen.cpp @@ -962,11 +962,21 @@ void BeIRCodeGen::Read(BeValue*& beValue) } else if (constType == BfConstType_TypeOf) { - CMD_PARAM(BeType*, type); + CMD_PARAM(BeType*, type); beValue = mReflectDataMap[type]; BF_ASSERT(beValue != NULL); return; } + else if (constType == BfConstType_TypeOf_Comptime) + { + CMD_PARAM(BeType*, typeType); + CMD_PARAM(int, bfTypeId); + auto beConst = mBeModule->mAlloc.Alloc(); + beConst->mType = typeType; + beConst->mBfTypeId = bfTypeId; + beValue = beConst; + return; + } else if (constType == BfConstType_TypeOf_WithData) { CMD_PARAM(BeType*, type); diff --git a/IDEHelper/Backend/BeModule.cpp b/IDEHelper/Backend/BeModule.cpp index 39101d4a..c4e821e2 100644 --- a/IDEHelper/Backend/BeModule.cpp +++ b/IDEHelper/Backend/BeModule.cpp @@ -1457,6 +1457,13 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo return; } + if (auto constant = BeValueDynCast(value)) + { + ToString(str, constant->GetType()); + str += StrFormat(" typeof(%d)", constant->mBfTypeId); + return; + } + if (auto constant = BeValueDynCast(value)) { ToString(str, constant->GetType()); diff --git a/IDEHelper/Backend/BeModule.h b/IDEHelper/Backend/BeModule.h index 5aa1e43d..00f41f43 100644 --- a/IDEHelper/Backend/BeModule.h +++ b/IDEHelper/Backend/BeModule.h @@ -439,6 +439,20 @@ public: } }; +class BeTypeOfConstant : public BeConstant +{ +public: + BE_VALUE_TYPE(BeTypeOfConstant, BeConstant); + + int mBfTypeId; + + virtual void HashContent(BeHashContext& hashCtx) override + { + hashCtx.Mixin(TypeId); + hashCtx.Mixin(mBfTypeId); + } +}; + class BeStringConstant : public BeConstant { public: diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index d63ac1be..7a9e97ce 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -406,6 +406,11 @@ String BfIRConstHolder::ToString(BfIRValue irValue) auto typeofConst = (BfTypeOf_Const*)constant; return "typeof " + mModule->TypeToString(typeofConst->mType); } + else if (constant->mConstType == BfConstType_TypeOf_Comptime) + { + auto typeofConst = (BfTypeOf_Const*)constant; + return "typeof_comptime " + mModule->TypeToString(typeofConst->mType); + } else if (constant->mConstType == BfConstType_TypeOf_WithData) { auto typeofConst = (BfTypeOf_WithData_Const*)constant; @@ -687,8 +692,8 @@ int BfIRConstHolder::CheckConstEquality(BfIRValue lhs, BfIRValue rhs) } } - if (((constLHS->mConstType == BfConstType_TypeOf) || (constLHS->mConstType == BfConstType_TypeOf_WithData)) && - ((constRHS->mConstType == BfConstType_TypeOf) || (constRHS->mConstType == BfConstType_TypeOf_WithData))) + if (((constLHS->mConstType == BfConstType_TypeOf) || (constLHS->mConstType == BfConstType_TypeOf_WithData) || (constLHS->mConstType == BfConstType_TypeOf_Comptime)) && + ((constRHS->mConstType == BfConstType_TypeOf) || (constRHS->mConstType == BfConstType_TypeOf_WithData) || (constRHS->mConstType == BfConstType_TypeOf_Comptime))) { auto typeOfLHS = (BfTypeOf_Const*)constLHS; auto typeOfRHS = (BfTypeOf_Const*)constRHS; @@ -892,6 +897,11 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f auto typeOf = (BfTypeOf_Const*)fromConst; return CreateTypeOf(typeOf->mType); } + else if (fromConst->mConstType == BfConstType_TypeOf_Comptime) + { + auto typeOf = (BfTypeOf_Const*)fromConst; + return CreateTypeOfComptime(typeOf->mType); + } else if (fromConst->mConstType == BfConstType_TypeOf_WithData) { auto typeOf = (BfTypeOf_WithData_Const*)fromConst; @@ -1039,6 +1049,7 @@ BfIRValue BfIRConstHolder::CreateConstAgg(BfIRType type, const BfSizedArray(); + typeOf->mConstType = BfConstType_TypeOf_Comptime; + typeOf->mType = type; + auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(typeOf)); +#ifdef CHECK_CONSTHOLDER + irValue.mHolder = this; +#endif + return irValue; +} + BfIRValue BfIRConstHolder::CreateTypeOf(BfType* type) { BfTypeOf_Const* typeOf = mTempAlloc.Alloc(); @@ -2530,6 +2553,14 @@ void BfIRBuilder::Write(const BfIRValue& irValue) Write(MapType(typeofConst->mType, BfIRPopulateType_Identity)); } break; + case (int)BfConstType_TypeOf_Comptime: + { + auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef); + auto typeofConst = (BfTypeOf_Const*)constant; + Write(MapType(typeType, BfIRPopulateType_Identity)); + Write(typeofConst->mType->mTypeId); + } + break; case (int)BfConstType_Undef: { auto undefConst = (BfConstantUndef*)constant; diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index 146c27ee..37f003c5 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -134,6 +134,7 @@ enum BfConstType BfConstType_IntToPtr, BfConstType_TypeOf, BfConstType_TypeOf_WithData, + BfConstType_TypeOf_Comptime, BfConstType_AggZero, BfConstType_Agg, BfConstType_AggCE, @@ -981,6 +982,7 @@ public: BfIRValue CreateConstBitCast(BfIRValue val, BfIRType type); BfIRValue CreateConstBox(BfIRValue val, BfIRType type); BfIRValue CreateTypeOf(BfType* type); + BfIRValue CreateTypeOfComptime(BfType* type); BfIRValue CreateTypeOf(BfType* type, BfIRValue typeData); BfIRValue GetUndefConstValue(BfIRType type); BfIRValue CreateGlobalVariableConstant(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS = false); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 1760022e..afb295f2 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -5620,7 +5620,7 @@ BfIRValue BfModule::CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTy return globalVariable; } -BfIRValue BfModule::CreateTypeDataRef(BfType* type) +BfIRValue BfModule::CreateTypeDataRef(BfType* type, bool forceConstant) { if (mBfIRBuilder->mIgnoreWrites) { @@ -5629,6 +5629,9 @@ BfIRValue BfModule::CreateTypeDataRef(BfType* type) if (mIsComptimeModule) { + if (forceConstant) + return mBfIRBuilder->CreateTypeOfComptime(type); + auto typeTypeDef = ResolveTypeDef(mCompiler->mTypeTypeDef); auto typeTypeInst = typeTypeDef->ToTypeInstance(); return mBfIRBuilder->Comptime_GetReflectType(type->mTypeId, mBfIRBuilder->MapType(typeTypeInst)); @@ -12119,7 +12122,7 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con auto constTypeOf = (BfTypeOf_Const*)constant; if (mCurTypeInstance != NULL) AddDependency(constTypeOf->mType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference); - return CreateTypeDataRef(constTypeOf->mType); + return CreateTypeDataRef(constTypeOf->mType, true); } if (constant->mConstType == BfConstType_PtrToInt) diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 0cc761fc..127784fc 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -2090,7 +2090,7 @@ public: BfIRValue CreateClassVDataGlobal(BfTypeInstance* typeInstance, int* outNumElements = NULL, String* outMangledName = NULL); BfIRValue GetClassVDataPtr(BfTypeInstance* typeInstance); BfIRValue CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTypeInstance* implTypeInst, int startVirtIdx); - BfIRValue CreateTypeDataRef(BfType* type); + BfIRValue CreateTypeDataRef(BfType* type, bool forceConstant = false); void EncodeAttributeData(BfTypeInstance* typeInstance, BfType* argType, BfIRValue arg, SizedArrayImpl& data, Dictionary& usedStringIdMap); BfIRValue CreateFieldData(BfFieldInstance* fieldInstance, int customAttrIdx); void CreateSlotOfs(BfTypeInstance* typeInstance); diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index c614d1dc..69754043 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -1885,6 +1885,17 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme // return GetOperand(callInst->mInlineResult); } break; + case BeTypeOfConstant::TypeId: + { + auto beTypeOf = (BeTypeOfConstant*)value; + auto ptrType = mCeMachine->GetBeContext()->GetVoidPtrType(); + CeOperand result = FrameAlloc(ptrType); + Emit(CeOp_GetReflectType); + EmitFrameOffset(result); + Emit((int32)beTypeOf->mBfTypeId); + return result; + } + break; } CeOperand* operandPtr = NULL; diff --git a/IDEHelper/Tests/src/Comptime.bf b/IDEHelper/Tests/src/Comptime.bf index da08ce75..48f3cc3d 100644 --- a/IDEHelper/Tests/src/Comptime.bf +++ b/IDEHelper/Tests/src/Comptime.bf @@ -551,6 +551,28 @@ namespace Tests } } + struct StructD + { + [Comptime] + public static Span GetTypes() + { + List list = scope .(); + list.Add(typeof(StructA)); + list.Add(typeof(EnumA)); + return list; + } + } + + struct StructE + { + [Comptime] + public static int GetSizes() + { + const let typeList = StructD.GetTypes(); + return typeList[0].InstanceSize + typeList[1].InstanceSize; + } + } + [Test] public static void TestBasics() { @@ -604,8 +626,6 @@ namespace Tests Test.Assert(typeof(decltype(f)) == typeof(float)); Test.Assert(ClassB.cTimesTen == 30); - - DictWrapper> dictWrap = scope .(); dictWrap.[Friend]mValue.Add(1, 2.3f); dictWrap.[Friend]mValue.Add(2, 3.4f); @@ -643,6 +663,9 @@ namespace Tests DefaultCtorTest dct = .(); Test.Assert(dct.mA == 123); + + const int typeSizes = StructE.GetSizes(); + Test.Assert(typeSizes == 25); } } }