mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 20:12:21 +02:00
Support for passing Type to attributes
This commit is contained in:
parent
eb55b2d731
commit
617cdcbede
5 changed files with 131 additions and 94 deletions
|
@ -92,6 +92,9 @@ namespace System.Reflection
|
||||||
.Double:
|
.Double:
|
||||||
let attrData = Decode!<int64>(data);
|
let attrData = Decode!<int64>(data);
|
||||||
args[argIdx] = scope:AttrBlock box attrData;
|
args[argIdx] = scope:AttrBlock box attrData;
|
||||||
|
case (TypeCode)51: //BfConstType_TypeOf
|
||||||
|
let argTypeId = Decode!<int32>(data);
|
||||||
|
args[argIdx] = Type.[Friend]GetType((.)argTypeId);
|
||||||
case (TypeCode)255:
|
case (TypeCode)255:
|
||||||
let stringId = Decode!<int32>(data);
|
let stringId = Decode!<int32>(data);
|
||||||
String str = String.[Friend]sIdStringLiterals[stringId];
|
String str = String.[Friend]sIdStringLiterals[stringId];
|
||||||
|
|
|
@ -5152,6 +5152,121 @@ BfIRValue BfModule::CreateTypeDataRef(BfType* type)
|
||||||
return mBfIRBuilder->CreateTypeOf(type, globalVariable);
|
return mBfIRBuilder->CreateTypeOf(type, globalVariable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfModule::EncodeAttributeData(BfTypeInstance* typeInstance, BfType* argType, BfIRValue arg, SizedArrayImpl<uint8>& data, Dictionary<int, int>& 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<int, int>& usedStringIdMap, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData)
|
BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStringIdMap, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData)
|
||||||
{
|
{
|
||||||
if ((mCompiler->IsHotCompile()) && (!type->mDirty))
|
if ((mCompiler->IsHotCompile()) && (!type->mDirty))
|
||||||
|
@ -6089,9 +6204,6 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
#define PUSH_INT8(val) data.push_back((uint8)val)
|
#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_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_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<uint8, 16> data;
|
SizedArray<uint8, 16> data;
|
||||||
|
|
||||||
int customAttrIdx = (int)customAttrs.size();
|
int customAttrIdx = (int)customAttrs.size();
|
||||||
|
@ -6132,94 +6244,9 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
int argIdx = 0;
|
int argIdx = 0;
|
||||||
|
|
||||||
for (auto arg : attr->mCtorArgs)
|
for (auto arg : attr->mCtorArgs)
|
||||||
{
|
|
||||||
auto constant = typeInstance->mConstHolder->GetConstant(arg);
|
|
||||||
bool handled = false;
|
|
||||||
|
|
||||||
if (constant != NULL)
|
|
||||||
{
|
{
|
||||||
auto argType = ctorMethodInstance->GetParamType(argIdx);
|
auto argType = ctorMethodInstance->GetParamType(argIdx);
|
||||||
if (argType->IsObject())
|
EncodeAttributeData(typeInstance, argType, arg, data, usedStringIdMap);
|
||||||
{
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
argIdx++;
|
argIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1942,6 +1942,7 @@ public:
|
||||||
BfIRValue GetClassVDataPtr(BfTypeInstance* typeInstance);
|
BfIRValue GetClassVDataPtr(BfTypeInstance* typeInstance);
|
||||||
BfIRValue CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTypeInstance* implTypeInst, int startVirtIdx);
|
BfIRValue CreateClassVDataExtGlobal(BfTypeInstance* declTypeInst, BfTypeInstance* implTypeInst, int startVirtIdx);
|
||||||
BfIRValue CreateTypeDataRef(BfType* type);
|
BfIRValue CreateTypeDataRef(BfType* type);
|
||||||
|
void EncodeAttributeData(BfTypeInstance* typeInstance, BfType* argType, BfIRValue arg, SizedArrayImpl<uint8>& data, Dictionary<int, int>& usedStringIdMap);
|
||||||
BfIRValue CreateTypeData(BfType* type, Dictionary<int, int>& usedStringIdMap, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData);
|
BfIRValue CreateTypeData(BfType* type, Dictionary<int, int>& usedStringIdMap, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData);
|
||||||
BfIRValue FixClassVData(BfIRValue value);
|
BfIRValue FixClassVData(BfIRValue value);
|
||||||
|
|
||||||
|
|
|
@ -3852,6 +3852,8 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
||||||
|
|
||||||
BfIRValue CeContext::CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfIRConstHolder* constHolder, BfCustomAttribute* customAttribute)
|
BfIRValue CeContext::CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfIRConstHolder* constHolder, BfCustomAttribute* customAttribute)
|
||||||
{
|
{
|
||||||
|
SetAndRestoreValue<bool> prevIgnoreWrites(module->mBfIRBuilder->mIgnoreWrites, true);
|
||||||
|
|
||||||
module->mContext->mUnreifiedModule->PopulateType(customAttribute->mType);
|
module->mContext->mUnreifiedModule->PopulateType(customAttribute->mType);
|
||||||
auto ceAttrAddr = CeMalloc(customAttribute->mType->mSize) - mMemory.mVals;
|
auto ceAttrAddr = CeMalloc(customAttribute->mType->mSize) - mMemory.mVals;
|
||||||
BfIRValue ceAttrVal = module->mBfIRBuilder->CreateConstAggCE(module->mBfIRBuilder->MapType(customAttribute->mType, BfIRPopulateType_Identity), ceAttrAddr);
|
BfIRValue ceAttrVal = module->mBfIRBuilder->CreateConstAggCE(module->mBfIRBuilder->MapType(customAttribute->mType, BfIRPopulateType_Identity), ceAttrAddr);
|
||||||
|
|
|
@ -46,11 +46,13 @@ namespace Tests
|
||||||
{
|
{
|
||||||
public int32 mA;
|
public int32 mA;
|
||||||
public float mB;
|
public float mB;
|
||||||
|
public Type mC;
|
||||||
|
|
||||||
public this(int32 a, float b)
|
public this(int32 a, float b, Type c)
|
||||||
{
|
{
|
||||||
mA = a;
|
mA = a;
|
||||||
mB = b;
|
mB = b;
|
||||||
|
mC = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +71,7 @@ namespace Tests
|
||||||
public static int32 sA = 234;
|
public static int32 sA = 234;
|
||||||
public static String sStr = "AA";
|
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)
|
static float StaticMethodA(int32 a, int32 b, float c, ref int32 d, ref StructA sa)
|
||||||
{
|
{
|
||||||
d += a + b;
|
d += a + b;
|
||||||
|
@ -169,7 +171,7 @@ namespace Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Reflect(.All), AttrC(1, 2)]
|
[Reflect(.All), AttrC(1, 2, typeof(StringView))]
|
||||||
class ClassB
|
class ClassB
|
||||||
{
|
{
|
||||||
[AttrA(11, 22, "StrA")]
|
[AttrA(11, 22, "StrA")]
|
||||||
|
@ -317,6 +319,7 @@ namespace Tests
|
||||||
let attrC = methodInfo.GetCustomAttribute<AttrCAttribute>().Get();
|
let attrC = methodInfo.GetCustomAttribute<AttrCAttribute>().Get();
|
||||||
Test.Assert(attrC.mA == 71);
|
Test.Assert(attrC.mA == 71);
|
||||||
Test.Assert(attrC.mB == 72);
|
Test.Assert(attrC.mB == 72);
|
||||||
|
Test.Assert(attrC.mC == typeof(float));
|
||||||
case 5:
|
case 5:
|
||||||
Test.Assert(methodInfo.Name == "StaticMethodB");
|
Test.Assert(methodInfo.Name == "StaticMethodB");
|
||||||
|
|
||||||
|
@ -418,6 +421,7 @@ namespace Tests
|
||||||
let attrC = typeof(ClassB).GetCustomAttribute<AttrCAttribute>().Get();
|
let attrC = typeof(ClassB).GetCustomAttribute<AttrCAttribute>().Get();
|
||||||
Test.Assert(attrC.mA == 1);
|
Test.Assert(attrC.mA == 1);
|
||||||
Test.Assert(attrC.mB == 2);
|
Test.Assert(attrC.mB == 2);
|
||||||
|
Test.Assert(attrC.mC == typeof(StringView));
|
||||||
|
|
||||||
ClassC c = scope .();
|
ClassC c = scope .();
|
||||||
Test.Assert(typeof(ClassC).GetField("mA").Value.Name == "mA");
|
Test.Assert(typeof(ClassC).GetField("mA").Value.Name == "mA");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue