diff --git a/BeefLibs/corlib/src/Reflection/AttributeInfo.bf b/BeefLibs/corlib/src/Reflection/AttributeInfo.bf index c30d130a..1e515ae9 100644 --- a/BeefLibs/corlib/src/Reflection/AttributeInfo.bf +++ b/BeefLibs/corlib/src/Reflection/AttributeInfo.bf @@ -92,6 +92,9 @@ namespace System.Reflection .Double: let attrData = Decode!(data); args[argIdx] = scope:AttrBlock box attrData; + case (TypeCode)51: //BfConstType_TypeOf + let argTypeId = Decode!(data); + args[argIdx] = Type.[Friend]GetType((.)argTypeId); case (TypeCode)255: let stringId = Decode!(data); String str = String.[Friend]sIdStringLiterals[stringId]; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 16481e93..ca797995 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -5152,6 +5152,121 @@ BfIRValue BfModule::CreateTypeDataRef(BfType* type) return mBfIRBuilder->CreateTypeOf(type, globalVariable); } +void BfModule::EncodeAttributeData(BfTypeInstance* typeInstance, BfType* argType, BfIRValue arg, SizedArrayImpl& data, Dictionary& usedStringIdMap) +{ +#define PUSH_INT8(val) data.push_back((uint8)val) +#define PUSH_INT16(val) { data.push_back(val & 0xFF); data.push_back((val >> 8) & 0xFF); } +#define PUSH_INT32(val) { data.push_back(val & 0xFF); data.push_back((val >> 8) & 0xFF); data.push_back((val >> 16) & 0xFF); data.push_back((val >> 24) & 0xFF); } +#define PUSH_INT64(val) { data.push_back(val & 0xFF); data.push_back((val >> 8) & 0xFF); data.push_back((val >> 16) & 0xFF); data.push_back((val >> 24) & 0xFF); \ + data.push_back((val >> 32) & 0xFF); data.push_back((val >> 40) & 0xFF); data.push_back((val >> 48) & 0xFF); data.push_back((val >> 56) & 0xFF); } + + auto constant = typeInstance->mConstHolder->GetConstant(arg); + bool handled = false; + + if (constant == NULL) + { + Fail(StrFormat("Unhandled attribute constant data in '%s'", TypeToString(typeInstance).c_str())); + return; + } + + if (argType->IsObject()) + { + if (argType->IsInstanceOf(mCompiler->mStringTypeDef)) + { + int stringId = constant->mInt32; + int* orderedIdPtr; + if (usedStringIdMap.TryAdd(stringId, NULL, &orderedIdPtr)) + { + *orderedIdPtr = (int)usedStringIdMap.size() - 1; + } + + GetStringObjectValue(stringId, true, true); + PUSH_INT8(0xFF); // String + PUSH_INT32(*orderedIdPtr); + return; + } + } + + if (argType->IsPointer()) + { + if (argType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8)) + { + if (constant->mTypeCode == BfTypeCode_StringId) + { + int stringId = constant->mInt32; + int* orderedIdPtr; + if (usedStringIdMap.TryAdd(stringId, NULL, &orderedIdPtr)) + { + *orderedIdPtr = (int)usedStringIdMap.size() - 1; + } + + GetStringObjectValue(stringId, true, true); + PUSH_INT8(0xFF); // String + PUSH_INT32(*orderedIdPtr); + return; + } + } + } + + PUSH_INT8(constant->mTypeCode); + if ((constant->mTypeCode == BfTypeCode_Int64) || + (constant->mTypeCode == BfTypeCode_UInt64) || + (constant->mTypeCode == BfTypeCode_Double)) + { + PUSH_INT64(constant->mInt64); + } + else if ((constant->mTypeCode == BfTypeCode_Int32) || + (constant->mTypeCode == BfTypeCode_UInt32) || + (constant->mTypeCode == BfTypeCode_Char32)) + { + PUSH_INT32(constant->mInt32); + } + else if (constant->mTypeCode == BfTypeCode_Float) + { + float val = (float)constant->mDouble; + PUSH_INT32(*(int*)&val); + } + else if ((constant->mTypeCode == BfTypeCode_Int16) || + (constant->mTypeCode == BfTypeCode_UInt16) || + (constant->mTypeCode == BfTypeCode_Char16)) + { + PUSH_INT16(constant->mInt16); + } + else if ((constant->mTypeCode == BfTypeCode_Int8) || + (constant->mTypeCode == BfTypeCode_UInt8) || + (constant->mTypeCode == BfTypeCode_Boolean) || + (constant->mTypeCode == BfTypeCode_Char8)) + { + PUSH_INT8(constant->mInt8); + } + else if (constant->mConstType == BfConstType_TypeOf) + { + auto typeOf = (BfTypeOf_Const*)constant; + PUSH_INT32(typeOf->mType->mTypeId); + } + else if (constant->mConstType == BfConstType_AggZero) + { + for (int i = 0; i < argType->mSize; i++) + data.Add(0); + } +// else if (constant->mConstType == BfConstType_Agg) +// { +// BF_ASSERT(argType->IsComposite()); +// if (argType->IsSizedArray()) +// { +// auto argSizedArrayType = (BfSizedArrayType*)argType; +// } +// else +// { +// auto argTypeInstance = argType->ToTypeInstance(); +// } +// } + else + { + Fail(StrFormat("Unhandled attribute constant data in '%s'", TypeToString(typeInstance).c_str())); + } +} + BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStringIdMap, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData) { if ((mCompiler->IsHotCompile()) && (!type->mDirty)) @@ -6089,9 +6204,6 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin #define PUSH_INT8(val) data.push_back((uint8)val) #define PUSH_INT16(val) { data.push_back(val & 0xFF); data.push_back((val >> 8) & 0xFF); } #define PUSH_INT32(val) { data.push_back(val & 0xFF); data.push_back((val >> 8) & 0xFF); data.push_back((val >> 16) & 0xFF); data.push_back((val >> 24) & 0xFF); } -#define PUSH_INT64(val) { data.push_back(val & 0xFF); data.push_back((val >> 8) & 0xFF); data.push_back((val >> 16) & 0xFF); data.push_back((val >> 24) & 0xFF); \ - data.push_back((val >> 32) & 0xFF); data.push_back((val >> 40) & 0xFF); data.push_back((val >> 48) & 0xFF); data.push_back((val >> 56) & 0xFF); } - SizedArray data; int customAttrIdx = (int)customAttrs.size(); @@ -6133,96 +6245,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary& usedStrin for (auto arg : attr->mCtorArgs) { - auto constant = typeInstance->mConstHolder->GetConstant(arg); - bool handled = false; - - if (constant != NULL) - { - auto argType = ctorMethodInstance->GetParamType(argIdx); - if (argType->IsObject()) - { - BF_ASSERT(argType->ToTypeInstance()->IsInstanceOf(mCompiler->mStringTypeDef)); - - int stringId = constant->mInt32; - int* orderedIdPtr; - if (usedStringIdMap.TryAdd(stringId, NULL, &orderedIdPtr)) - { - *orderedIdPtr = (int)usedStringIdMap.size() - 1; - } - - GetStringObjectValue(stringId, true, true); - PUSH_INT8(0xFF); // String - PUSH_INT32(*orderedIdPtr); - argIdx++; - continue; - } - - if (argType->IsPointer()) - { - if (argType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8)) - { - if (constant->mTypeCode == BfTypeCode_StringId) - { - int stringId = constant->mInt32; - int* orderedIdPtr; - if (usedStringIdMap.TryAdd(stringId, NULL, &orderedIdPtr)) - { - *orderedIdPtr = (int)usedStringIdMap.size() - 1; - } - - GetStringObjectValue(stringId, true, true); - PUSH_INT8(0xFF); // String - PUSH_INT32(*orderedIdPtr); - argIdx++; - continue; - } - } - } - - PUSH_INT8(constant->mTypeCode); - if ((constant->mTypeCode == BfTypeCode_Int64) || - (constant->mTypeCode == BfTypeCode_UInt64) || - (constant->mTypeCode == BfTypeCode_Double)) - { - PUSH_INT64(constant->mInt64); - } - else if ((constant->mTypeCode == BfTypeCode_Int32) || - (constant->mTypeCode == BfTypeCode_UInt32) || - (constant->mTypeCode == BfTypeCode_Char32)) - { - PUSH_INT32(constant->mInt32); - } - else if (constant->mTypeCode == BfTypeCode_Float) - { - float val = (float)constant->mDouble; - PUSH_INT32(*(int*)&val); - } - else if ((constant->mTypeCode == BfTypeCode_Int16) || - (constant->mTypeCode == BfTypeCode_UInt16) || - (constant->mTypeCode == BfTypeCode_Char16)) - { - PUSH_INT16(constant->mInt16); - } - else if ((constant->mTypeCode == BfTypeCode_Int8) || - (constant->mTypeCode == BfTypeCode_UInt8) || - (constant->mTypeCode == BfTypeCode_Boolean) || - (constant->mTypeCode == BfTypeCode_Char8)) - { - PUSH_INT8(constant->mInt8); - } - else - { - Fail(StrFormat("Unhandled attribute constant data in '%s'", TypeToString(type).c_str())); - } - } - else if (!handled) - { - BFMODULE_FATAL(this, "Unhandled"); - } - + auto argType = ctorMethodInstance->GetParamType(argIdx); + EncodeAttributeData(typeInstance, argType, arg, data, usedStringIdMap); argIdx++; } - + int size = (int)data.size() - sizeIdx; *((uint16*)&data[sizeIdx]) = size; } diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 62a2133d..b1d08992 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1942,6 +1942,7 @@ public: BfIRValue GetClassVDataPtr(BfTypeInstance* typeInstance); BfIRValue CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTypeInstance* implTypeInst, int startVirtIdx); BfIRValue CreateTypeDataRef(BfType* type); + void EncodeAttributeData(BfTypeInstance* typeInstance, BfType* argType, BfIRValue arg, SizedArrayImpl& data, Dictionary& usedStringIdMap); BfIRValue CreateTypeData(BfType* type, Dictionary& usedStringIdMap, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData); BfIRValue FixClassVData(BfIRValue value); diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index c7c3a1c6..653aef0d 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -3852,6 +3852,8 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType BfIRValue CeContext::CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfIRConstHolder* constHolder, BfCustomAttribute* customAttribute) { + SetAndRestoreValue prevIgnoreWrites(module->mBfIRBuilder->mIgnoreWrites, true); + module->mContext->mUnreifiedModule->PopulateType(customAttribute->mType); auto ceAttrAddr = CeMalloc(customAttribute->mType->mSize) - mMemory.mVals; BfIRValue ceAttrVal = module->mBfIRBuilder->CreateConstAggCE(module->mBfIRBuilder->MapType(customAttribute->mType, BfIRPopulateType_Identity), ceAttrAddr); diff --git a/IDEHelper/Tests/src/Reflection.bf b/IDEHelper/Tests/src/Reflection.bf index 89dcc0f1..f7bb4ad6 100644 --- a/IDEHelper/Tests/src/Reflection.bf +++ b/IDEHelper/Tests/src/Reflection.bf @@ -46,11 +46,13 @@ namespace Tests { public int32 mA; public float mB; + public Type mC; - public this(int32 a, float b) + public this(int32 a, float b, Type c) { mA = a; mB = b; + mC = c; } } @@ -69,7 +71,7 @@ namespace Tests public static int32 sA = 234; public static String sStr = "AA"; - [AlwaysInclude, AttrC(71, 72)] + [AlwaysInclude, AttrC(71, 72, typeof(float))] static float StaticMethodA(int32 a, int32 b, float c, ref int32 d, ref StructA sa) { d += a + b; @@ -169,7 +171,7 @@ namespace Tests } } - [Reflect(.All), AttrC(1, 2)] + [Reflect(.All), AttrC(1, 2, typeof(StringView))] class ClassB { [AttrA(11, 22, "StrA")] @@ -317,6 +319,7 @@ namespace Tests let attrC = methodInfo.GetCustomAttribute().Get(); Test.Assert(attrC.mA == 71); Test.Assert(attrC.mB == 72); + Test.Assert(attrC.mC == typeof(float)); case 5: Test.Assert(methodInfo.Name == "StaticMethodB"); @@ -418,6 +421,7 @@ namespace Tests let attrC = typeof(ClassB).GetCustomAttribute().Get(); Test.Assert(attrC.mA == 1); Test.Assert(attrC.mB == 2); + Test.Assert(attrC.mC == typeof(StringView)); ClassC c = scope .(); Test.Assert(typeof(ClassC).GetField("mA").Value.Name == "mA");