mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 12:32:20 +02:00
Comptime GetCustomAttribute for type/field/method
This commit is contained in:
parent
434a7406de
commit
4c5c89bab5
8 changed files with 110 additions and 13 deletions
|
@ -229,6 +229,13 @@ namespace System.Reflection
|
||||||
|
|
||||||
public Result<T> GetCustomAttribute<T>() where T : Attribute
|
public Result<T> GetCustomAttribute<T>() where T : Attribute
|
||||||
{
|
{
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
{
|
||||||
|
T val = ?;
|
||||||
|
if (Type.[Friend]Comptime_Field_GetCustomAttribute((int32)mTypeInstance.TypeId, mFieldData.mCustomAttributesIdx, (.)typeof(T).TypeId, &val))
|
||||||
|
return val;
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
return mTypeInstance.[Friend]GetCustomAttribute<T>(mFieldData.mCustomAttributesIdx);
|
return mTypeInstance.[Friend]GetCustomAttribute<T>(mFieldData.mCustomAttributesIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,12 @@ namespace System.Reflection
|
||||||
public Result<T> GetCustomAttribute<T>() where T : Attribute
|
public Result<T> GetCustomAttribute<T>() where T : Attribute
|
||||||
{
|
{
|
||||||
if (Compiler.IsComptime)
|
if (Compiler.IsComptime)
|
||||||
|
{
|
||||||
|
T val = ?;
|
||||||
|
if (Type.[Friend]Comptime_Method_GetCustomAttribute(mData.mComptimeMethodInstance, (.)typeof(T).TypeId, &val))
|
||||||
|
return val;
|
||||||
return .Err;
|
return .Err;
|
||||||
|
}
|
||||||
return mTypeInstance.[Friend]GetCustomAttribute<T>(mData.mMethodData.mCustomAttributesIdx);
|
return mTypeInstance.[Friend]GetCustomAttribute<T>(mData.mMethodData.mCustomAttributesIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -529,6 +529,8 @@ namespace System
|
||||||
static extern String Comptime_Type_ToString(int32 typeId);
|
static extern String Comptime_Type_ToString(int32 typeId);
|
||||||
static extern Type Comptime_GetSpecializedType(Type unspecializedType, Span<Type> typeArgs);
|
static extern Type Comptime_GetSpecializedType(Type unspecializedType, Span<Type> typeArgs);
|
||||||
static extern bool Comptime_Type_GetCustomAttribute(int32 typeId, int32 attributeId, void* dataPtr);
|
static extern bool Comptime_Type_GetCustomAttribute(int32 typeId, int32 attributeId, void* dataPtr);
|
||||||
|
static extern bool Comptime_Field_GetCustomAttribute(int32 typeId, int32 fieldIdx, int32 attributeId, void* dataPtr);
|
||||||
|
static extern bool Comptime_Method_GetCustomAttribute(int64 methodHandle, int32 attributeId, void* dataPtr);
|
||||||
static extern int32 Comptime_GetMethodCount(int32 typeId);
|
static extern int32 Comptime_GetMethodCount(int32 typeId);
|
||||||
static extern int64 Comptime_GetMethod(int32 typeId, int32 methodIdx);
|
static extern int64 Comptime_GetMethod(int32 typeId, int32 methodIdx);
|
||||||
static extern String Comptime_Method_ToString(int64 methodHandle);
|
static extern String Comptime_Method_ToString(int64 methodHandle);
|
||||||
|
|
|
@ -2222,7 +2222,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
|
||||||
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext, ceEmitContext);
|
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext, ceEmitContext);
|
||||||
auto ceContext = mCompiler->mCEMachine->AllocContext();
|
auto ceContext = mCompiler->mCEMachine->AllocContext();
|
||||||
|
|
||||||
BfIRValue attrVal = ceContext->CreateAttribute(customAttribute.mRef, this, typeInstance->mConstHolder, &customAttribute);
|
BfIRValue attrVal =ceContext->CreateAttribute(customAttribute.mRef, this, typeInstance->mConstHolder, &customAttribute);
|
||||||
for (int baseIdx = 0; baseIdx < checkDepth; baseIdx++)
|
for (int baseIdx = 0; baseIdx < checkDepth; baseIdx++)
|
||||||
attrVal = mBfIRBuilder->CreateExtractValue(attrVal, 0);
|
attrVal = mBfIRBuilder->CreateExtractValue(attrVal, 0);
|
||||||
|
|
||||||
|
|
|
@ -1422,6 +1422,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
|
||||||
auto eqVal = mBfIRBuilder->CreateCmpEQ(dscVal, GetConstValue(tagId, dscType));
|
auto eqVal = mBfIRBuilder->CreateCmpEQ(dscVal, GetConstValue(tagId, dscType));
|
||||||
exprEvaluator->mResult = BfTypedValue(eqVal, boolType);
|
exprEvaluator->mResult = BfTypedValue(eqVal, boolType);
|
||||||
|
|
||||||
|
PopulateType(outType);
|
||||||
if (!outType->IsValuelessType())
|
if (!outType->IsValuelessType())
|
||||||
{
|
{
|
||||||
auto outPtrType = CreatePointerType(outType);
|
auto outPtrType = CreatePointerType(outType);
|
||||||
|
|
|
@ -3458,7 +3458,7 @@ bool CeContext::GetStringFromStringView(addr_ce addr, StringImpl& str)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CeContext::GetCustomAttribute(BfCustomAttributes* customAttributes, int attributeTypeId, addr_ce resultAddr)
|
bool CeContext::GetCustomAttribute(BfModule* module, BfIRConstHolder* constHolder, BfCustomAttributes* customAttributes, int attributeTypeId, addr_ce resultAddr)
|
||||||
{
|
{
|
||||||
if (customAttributes == NULL)
|
if (customAttributes == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
@ -3470,17 +3470,26 @@ bool CeContext::GetCustomAttribute(BfCustomAttributes* customAttributes, int att
|
||||||
auto customAttr = customAttributes->Get(attributeType);
|
auto customAttr = customAttributes->Get(attributeType);
|
||||||
if (customAttr == NULL)
|
if (customAttr == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (resultAddr != 0)
|
auto ceContext = mCeMachine->AllocContext();
|
||||||
|
BfIRValue foreignValue = ceContext->CreateAttribute(mCurTargetSrc, module, constHolder, customAttr);
|
||||||
|
auto foreignConstant = module->mBfIRBuilder->GetConstant(foreignValue);
|
||||||
|
if (foreignConstant->mConstType == BfConstType_AggCE)
|
||||||
{
|
{
|
||||||
|
auto constAggData = (BfConstantAggCE*)foreignConstant;
|
||||||
}
|
auto value = ceContext->CreateConstant(module, ceContext->mMemory.mVals + constAggData->mCEAddr, customAttr->mType);
|
||||||
|
if (!value)
|
||||||
|
Fail("Failed to encoded attribute");
|
||||||
|
auto attrConstant = module->mBfIRBuilder->GetConstant(value);
|
||||||
|
if (!WriteConstant(module, resultAddr, attrConstant, customAttr->mType))
|
||||||
|
Fail("Failed to decode attribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
mCeMachine->ReleaseContext(ceContext);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//#define CE_GETC(T) *((T*)(addr += sizeof(T)) - 1)
|
//#define CE_GETC(T) *((T*)(addr += sizeof(T)) - 1)
|
||||||
#define CE_GETC(T) *(T*)(mMemory.mVals + addr)
|
#define CE_GETC(T) *(T*)(mMemory.mVals + addr)
|
||||||
|
|
||||||
|
@ -4172,12 +4181,13 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
||||||
return BfIRValue();
|
return BfIRValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
BfIRValue CeContext::CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfIRConstHolder* constHolder, BfCustomAttribute* customAttribute)
|
BfIRValue CeContext::CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfIRConstHolder* constHolder, BfCustomAttribute* customAttribute, addr_ce ceAttrAddr)
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<bool> prevIgnoreWrites(module->mBfIRBuilder->mIgnoreWrites, true);
|
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;
|
if (ceAttrAddr == 0)
|
||||||
|
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);
|
||||||
BfTypedValue ceAttrTypedValue(ceAttrVal, customAttribute->mType);
|
BfTypedValue ceAttrTypedValue(ceAttrVal, customAttribute->mType);
|
||||||
|
|
||||||
|
@ -5115,11 +5125,52 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
{
|
{
|
||||||
auto typeInst = type->ToTypeInstance();
|
auto typeInst = type->ToTypeInstance();
|
||||||
if (typeInst != NULL)
|
if (typeInst != NULL)
|
||||||
success = GetCustomAttribute(typeInst->mCustomAttributes, attributeTypeId, resultPtr);
|
success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, typeInst->mCustomAttributes, attributeTypeId, resultPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
*(addr_ce*)(stackPtr + 0) = success;
|
*(addr_ce*)(stackPtr + 0) = success;
|
||||||
}
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_Field_GetCustomAttribute)
|
||||||
|
{
|
||||||
|
int32 typeId = *(int32*)((uint8*)stackPtr + 1);
|
||||||
|
int32 fieldIdx = *(int32*)((uint8*)stackPtr + 1 + 4);
|
||||||
|
int32 attributeTypeId = *(int32*)((uint8*)stackPtr + 1 + 4 + 4);
|
||||||
|
addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 4 + 4 + 4);
|
||||||
|
|
||||||
|
BfType* type = GetBfType(typeId);
|
||||||
|
bool success = false;
|
||||||
|
if (type != NULL)
|
||||||
|
{
|
||||||
|
auto typeInst = type->ToTypeInstance();
|
||||||
|
if (typeInst != NULL)
|
||||||
|
{
|
||||||
|
if (typeInst->mDefineState < BfTypeDefineState_CETypeInit)
|
||||||
|
mCurModule->PopulateType(typeInst);
|
||||||
|
if (fieldIdx < typeInst->mFieldInstances.mSize)
|
||||||
|
{
|
||||||
|
auto& fieldInstance = typeInst->mFieldInstances[fieldIdx];
|
||||||
|
success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, fieldInstance.mCustomAttributes, attributeTypeId, resultPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*(addr_ce*)(stackPtr + 0) = success;
|
||||||
|
}
|
||||||
|
else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetCustomAttribute)
|
||||||
|
{
|
||||||
|
int64 methodHandle = *(int64*)((uint8*)stackPtr + 1);
|
||||||
|
int32 attributeTypeId = *(int32*)((uint8*)stackPtr + 1 + 8);
|
||||||
|
addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 8 + 4);
|
||||||
|
|
||||||
|
auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
|
||||||
|
if (methodInstance == NULL)
|
||||||
|
{
|
||||||
|
_Fail("Invalid method instance");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool success = GetCustomAttribute(mCurModule, methodInstance->GetOwner()->mConstHolder, methodInstance->GetCustomAttributes(), attributeTypeId, resultPtr);
|
||||||
|
*(addr_ce*)(stackPtr + 0) = success;
|
||||||
|
}
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_GetMethodCount)
|
else if (checkFunction->mFunctionKind == CeFunctionKind_GetMethodCount)
|
||||||
{
|
{
|
||||||
int32 typeId = *(int32*)((uint8*)stackPtr + 4);
|
int32 typeId = *(int32*)((uint8*)stackPtr + 4);
|
||||||
|
@ -8070,6 +8121,14 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
|
||||||
{
|
{
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Type_GetCustomAttribute;
|
ceFunction->mFunctionKind = CeFunctionKind_Type_GetCustomAttribute;
|
||||||
}
|
}
|
||||||
|
else if (methodDef->mName == "Comptime_Field_GetCustomAttribute")
|
||||||
|
{
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_Field_GetCustomAttribute;
|
||||||
|
}
|
||||||
|
else if (methodDef->mName == "Comptime_Method_GetCustomAttribute")
|
||||||
|
{
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_Method_GetCustomAttribute;
|
||||||
|
}
|
||||||
else if (methodDef->mName == "Comptime_GetMethod")
|
else if (methodDef->mName == "Comptime_GetMethod")
|
||||||
{
|
{
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_GetMethod;
|
ceFunction->mFunctionKind = CeFunctionKind_GetMethod;
|
||||||
|
|
|
@ -326,6 +326,8 @@ enum CeFunctionKind
|
||||||
CeFunctionKind_GetReflectSpecializedType,
|
CeFunctionKind_GetReflectSpecializedType,
|
||||||
CeFunctionKind_Type_ToString,
|
CeFunctionKind_Type_ToString,
|
||||||
CeFunctionKind_Type_GetCustomAttribute,
|
CeFunctionKind_Type_GetCustomAttribute,
|
||||||
|
CeFunctionKind_Field_GetCustomAttribute,
|
||||||
|
CeFunctionKind_Method_GetCustomAttribute,
|
||||||
CeFunctionKind_GetMethodCount,
|
CeFunctionKind_GetMethodCount,
|
||||||
CeFunctionKind_GetMethod,
|
CeFunctionKind_GetMethod,
|
||||||
CeFunctionKind_Method_ToString,
|
CeFunctionKind_Method_ToString,
|
||||||
|
@ -906,11 +908,11 @@ public:
|
||||||
bool CheckMemory(addr_ce addr, int32 size);
|
bool CheckMemory(addr_ce addr, int32 size);
|
||||||
bool GetStringFromAddr(addr_ce strInstAddr, StringImpl& str);
|
bool GetStringFromAddr(addr_ce strInstAddr, StringImpl& str);
|
||||||
bool GetStringFromStringView(addr_ce addr, StringImpl& str);
|
bool GetStringFromStringView(addr_ce addr, StringImpl& str);
|
||||||
bool GetCustomAttribute(BfCustomAttributes* customAttributes, int attributeTypeId, addr_ce resultAddr);
|
bool GetCustomAttribute(BfModule* module, BfIRConstHolder* constHolder, BfCustomAttributes* customAttributes, int attributeTypeId, addr_ce resultAddr);
|
||||||
|
|
||||||
bool WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type, bool isParams = false);
|
bool WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type, bool isParams = false);
|
||||||
BfIRValue CreateConstant(BfModule* module, uint8* ptr, BfType* type, BfType** outType = NULL);
|
BfIRValue CreateConstant(BfModule* module, uint8* ptr, BfType* type, BfType** outType = NULL);
|
||||||
BfIRValue CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfIRConstHolder* constHolder, BfCustomAttribute* customAttribute);
|
BfIRValue CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfIRConstHolder* constHolder, BfCustomAttribute* customAttribute, addr_ce ceAttrAddr = 0);
|
||||||
|
|
||||||
bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType);
|
bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType);
|
||||||
BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType);
|
BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType);
|
||||||
|
|
|
@ -7,6 +7,21 @@ namespace Tests
|
||||||
{
|
{
|
||||||
class Comptime
|
class Comptime
|
||||||
{
|
{
|
||||||
|
[AttributeUsage(.All)]
|
||||||
|
struct AddFieldAttribute : Attribute
|
||||||
|
{
|
||||||
|
public Type mType;
|
||||||
|
public String mName;
|
||||||
|
public int mVal;
|
||||||
|
|
||||||
|
public this(Type type, String name, int val)
|
||||||
|
{
|
||||||
|
mType = type;
|
||||||
|
mName = name;
|
||||||
|
mVal = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[AttributeUsage(.All)]
|
[AttributeUsage(.All)]
|
||||||
struct IFaceAAttribute : Attribute, IComptimeTypeApply
|
struct IFaceAAttribute : Attribute, IComptimeTypeApply
|
||||||
{
|
{
|
||||||
|
@ -33,6 +48,7 @@ namespace Tests
|
||||||
Compiler.EmitTypeBody(type, scope $"""
|
Compiler.EmitTypeBody(type, scope $"""
|
||||||
public int32 m{mMemberName} = {mInitVal};
|
public int32 m{mMemberName} = {mInitVal};
|
||||||
public int32 GetVal{mMemberName}() => mC;
|
public int32 GetVal{mMemberName}() => mC;
|
||||||
|
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,6 +81,7 @@ namespace Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AddField(typeof(float), "D", 4)]
|
||||||
[IFaceA("C", InitVal=345)]
|
[IFaceA("C", InitVal=345)]
|
||||||
class ClassA
|
class ClassA
|
||||||
{
|
{
|
||||||
|
@ -76,7 +93,10 @@ namespace Tests
|
||||||
Compiler.EmitTypeBody(typeof(Self), """
|
Compiler.EmitTypeBody(typeof(Self), """
|
||||||
public int32 mB = 234;
|
public int32 mB = 234;
|
||||||
public int32 GetValB() => mB;
|
public int32 GetValB() => mB;
|
||||||
|
|
||||||
""");
|
""");
|
||||||
|
if (var addFieldAttr = typeof(Self).GetCustomAttribute<AddFieldAttribute>())
|
||||||
|
Compiler.EmitTypeBody(typeof(Self), scope $"public {addFieldAttr.mType} {addFieldAttr.mName} = {addFieldAttr.mVal};");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,6 +489,7 @@ namespace Tests
|
||||||
Test.Assert(ca.GetValB() == 234);
|
Test.Assert(ca.GetValB() == 234);
|
||||||
Test.Assert(ca.mC == 345);
|
Test.Assert(ca.mC == 345);
|
||||||
Test.Assert(ca.GetValC() == 345);
|
Test.Assert(ca.GetValC() == 345);
|
||||||
|
Test.Assert(ca.D == 4);
|
||||||
|
|
||||||
StructA sa = .();
|
StructA sa = .();
|
||||||
Test.Assert(sa.mA == 123);
|
Test.Assert(sa.mA == 123);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue