diff --git a/BeefLibs/corlib/src/Reflection/AttributeInfo.bf b/BeefLibs/corlib/src/Reflection/AttributeInfo.bf index 71398265..2ac0538c 100644 --- a/BeefLibs/corlib/src/Reflection/AttributeInfo.bf +++ b/BeefLibs/corlib/src/Reflection/AttributeInfo.bf @@ -116,40 +116,40 @@ namespace System.Reflection public struct CustomAttributeEnumerator : IEnumerator, IDisposable { - void* data; - int32 attrIdx; - uint8 count; - Variant targetAttr; + void* mData; + int32 mAttrIdx; + uint8 mCount; + Variant mTargetAttr; public this(void* inAttrData) { - data = inAttrData; - data++; - attrIdx = 0; - count = data != null ? AttributeInfo.Decode!(data) : 0; - targetAttr = default; + mData = inAttrData; + mData++; + mAttrIdx = 0; + mCount = mData != null ? AttributeInfo.Decode!(mData) : 0; + mTargetAttr = default; } public Variant Current { get { - return targetAttr; + return mTargetAttr; } } public bool MoveNext() mut { - if (attrIdx >= count || data == null) + if (mAttrIdx >= mCount || mData == null) return false; - void* startPtr = data; - var len = AttributeInfo.Decode!(data); + void* startPtr = mData; + var len = AttributeInfo.Decode!(mData); void* endPtr = (uint8*)startPtr + len; - var typeId = AttributeInfo.Decode!(data); + var typeId = AttributeInfo.Decode!(mData); - var methodIdx = AttributeInfo.Decode!(data); + var methodIdx = AttributeInfo.Decode!(mData); Type attrType = Type.[Friend]GetType(typeId); TypeInstance attrTypeInst = attrType as TypeInstance; @@ -158,40 +158,40 @@ namespace System.Reflection Object[] args = scope Object[methodInfo.[Friend]mData.mMethodData.mParamCount]; int argIdx = 0; - while (data < endPtr) + while (mData < endPtr) { - var attrDataType = AttributeInfo.Decode!(data); + var attrDataType = AttributeInfo.Decode!(mData); switch (attrDataType) { case .Int8, .UInt8, .Char8, .Boolean: - let attrData = AttributeInfo.Decode!(data); + let attrData = AttributeInfo.Decode!(mData); args[argIdx] = scope:: box attrData; case .Int16, .UInt16, .Char16: - let attrData = AttributeInfo.Decode!(data); + let attrData = AttributeInfo.Decode!(mData); args[argIdx] = scope:: box attrData; case .Int32, .UInt32, .Char32: - let attrData = AttributeInfo.Decode!(data); + let attrData = AttributeInfo.Decode!(mData); args[argIdx] = scope:: box attrData; case .Float: - let attrData = AttributeInfo.Decode!(data); + let attrData = AttributeInfo.Decode!(mData); args[argIdx] = scope:: box attrData; case .Int64, .UInt64, .Double: - let attrData = AttributeInfo.Decode!(data); + let attrData = AttributeInfo.Decode!(mData); args[argIdx] = scope:: box attrData; case (TypeCode)typeof(TypeCode).MaxValue + 8: //BfConstType_TypeOf - let argTypeId = AttributeInfo.Decode!(data); + let argTypeId = AttributeInfo.Decode!(mData); args[argIdx] = Type.[Friend]GetType((.)argTypeId); case (TypeCode)255: - let stringId = AttributeInfo.Decode!(data); + let stringId = AttributeInfo.Decode!(mData); String str = String.[Friend]sIdStringLiterals[stringId]; args[argIdx] = str; default: @@ -200,19 +200,165 @@ namespace System.Reflection argIdx++; } - targetAttr.Dispose(); - void* data = Variant.Alloc(attrType, out targetAttr); + mTargetAttr.Dispose(); + void* data = Variant.Alloc(attrType, out mTargetAttr); if (methodInfo.Invoke(data, params args) case .Ok(var val)) val.Dispose(); - attrIdx++; + mAttrIdx++; return true; } public void Dispose() mut { - targetAttr.Dispose(); + mTargetAttr.Dispose(); + } + + public Result GetNext() mut + { + if (!MoveNext()) + return .Err; + return Current; + } + } + + public struct ComptimeTypeCustomAttributeEnumerator : IEnumerator, IDisposable + { + int32 mTypeId; + int32 mAttrIdx; + Variant mTargetAttr; + + public this(int32 typeId) + { + mTypeId = typeId; + mAttrIdx = -1; + mTargetAttr = default; + } + + public Variant Current + { + get + { + return mTargetAttr; + } + } + + public bool MoveNext() mut + { + let attrType = Type.[Friend]Comptime_Type_GetCustomAttributeType(mTypeId, ++mAttrIdx); + if (attrType != null) + { + mTargetAttr.Dispose(); + void* data = Variant.Alloc(attrType, out mTargetAttr); + + if (Type.[Friend]Comptime_Type_GetCustomAttribute(mTypeId, mAttrIdx, data)) + return true; + } + return false; + } + + public void Dispose() mut + { + mTargetAttr.Dispose(); + } + + public Result GetNext() mut + { + if (!MoveNext()) + return .Err; + return Current; + } + } + + public struct ComptimeFieldCustomAttributeEnumerator : IEnumerator, IDisposable + { + int32 mTypeId; + int32 mFieldIdx; + int32 mAttrIdx; + Variant mTargetAttr; + + public this(int32 typeId, int32 fieldIdx) + { + mTypeId = typeId; + mFieldIdx = fieldIdx; + mAttrIdx = -1; + mTargetAttr = default; + } + + public Variant Current + { + get + { + return mTargetAttr; + } + } + + public bool MoveNext() mut + { + let attrType = Type.[Friend]Comptime_Field_GetCustomAttributeType(mTypeId, mFieldIdx, ++mAttrIdx); + if (attrType != null) + { + mTargetAttr.Dispose(); + void* data = Variant.Alloc(attrType, out mTargetAttr); + + if (Type.[Friend]Comptime_Field_GetCustomAttribute(mTypeId, mFieldIdx, mAttrIdx, data)) + return true; + } + return false; + } + + public void Dispose() mut + { + mTargetAttr.Dispose(); + } + + public Result GetNext() mut + { + if (!MoveNext()) + return .Err; + return Current; + } + } + + public struct ComptimeMethodCustomAttributeEnumerator : IEnumerator, IDisposable + { + int64 mMethodHandle; + int32 mAttrIdx; + Variant mTargetAttr; + + public this(int64 methodHandle) + { + mMethodHandle = methodHandle; + mAttrIdx = -1; + mTargetAttr = default; + } + + public Variant Current + { + get + { + return mTargetAttr; + } + } + + public bool MoveNext() mut + { + let attrType = Type.[Friend]Comptime_Method_GetCustomAttributeType(mMethodHandle, ++mAttrIdx); + if (attrType != null) + { + mTargetAttr.Dispose(); + void* data = Variant.Alloc(attrType, out mTargetAttr); + + if (Type.[Friend]Comptime_Method_GetCustomAttribute(mMethodHandle, mAttrIdx, data)) + return true; + } + return false; + } + + public void Dispose() mut + { + mTargetAttr.Dispose(); } public Result GetNext() mut @@ -225,31 +371,31 @@ namespace System.Reflection public struct CustomAttributeEnumerator : IEnumerator { - void* data; - int32 attrIdx; - uint8 count; - T targetAttr; + void* mData; + int32 mAttrIdx; + uint8 mCount; + T mTargetAttr; public this(void* inAttrData) { - data = inAttrData; - data++; - attrIdx = 0; - count = data != null ? AttributeInfo.Decode!(data) : 0; - targetAttr = ?; + mData = inAttrData; + mData++; + mAttrIdx = 0; + mCount = mData != null ? AttributeInfo.Decode!(mData) : 0; + mTargetAttr = ?; } public T Current { get { - return targetAttr; + return mTargetAttr; } } public bool MoveNext() mut { - if (attrIdx >= count || data == null) + if (mAttrIdx >= mCount || mData == null) return false; void* endPtr = null; @@ -257,24 +403,24 @@ namespace System.Reflection while (true) { - void* startPtr = data; - var len = AttributeInfo.Decode!(data); + void* startPtr = mData; + var len = AttributeInfo.Decode!(mData); endPtr = (uint8*)startPtr + len; - typeId = AttributeInfo.Decode!(data); + typeId = AttributeInfo.Decode!(mData); if (typeId != typeof(T).TypeId) { - attrIdx++; - if (attrIdx >= count) + mAttrIdx++; + if (mAttrIdx >= mCount) return false; - data = endPtr; + mData = endPtr; continue; } break; } - var methodIdx = AttributeInfo.Decode!(data); + var methodIdx = AttributeInfo.Decode!(mData); Type attrType = Type.[Friend]GetType(typeId); TypeInstance attrTypeInst = attrType as TypeInstance; @@ -283,40 +429,40 @@ namespace System.Reflection Object[] args = scope Object[methodInfo.[Friend]mData.mMethodData.mParamCount]; int argIdx = 0; - while (data < endPtr) + while (mData < endPtr) { - var attrDataType = AttributeInfo.Decode!(data); + var attrDataType = AttributeInfo.Decode!(mData); switch (attrDataType) { case .Int8, .UInt8, .Char8, .Boolean: - let attrData = AttributeInfo.Decode!(data); + let attrData = AttributeInfo.Decode!(mData); args[argIdx] = scope:: box attrData; case .Int16, .UInt16, .Char16: - let attrData = AttributeInfo.Decode!(data); + let attrData = AttributeInfo.Decode!(mData); args[argIdx] = scope:: box attrData; case .Int32, .UInt32, .Char32: - let attrData = AttributeInfo.Decode!(data); + let attrData = AttributeInfo.Decode!(mData); args[argIdx] = scope:: box attrData; case .Float: - let attrData = AttributeInfo.Decode!(data); + let attrData = AttributeInfo.Decode!(mData); args[argIdx] = scope:: box attrData; case .Int64, .UInt64, .Double: - let attrData = AttributeInfo.Decode!(data); + let attrData = AttributeInfo.Decode!(mData); args[argIdx] = scope:: box attrData; case (TypeCode)typeof(TypeCode).MaxValue + 8: //BfConstType_TypeOf - let argTypeId = AttributeInfo.Decode!(data); + let argTypeId = AttributeInfo.Decode!(mData); args[argIdx] = Type.[Friend]GetType((.)argTypeId); case (TypeCode)255: - let stringId = AttributeInfo.Decode!(data); + let stringId = AttributeInfo.Decode!(mData); String str = String.[Friend]sIdStringLiterals[stringId]; args[argIdx] = str; default: @@ -325,10 +471,10 @@ namespace System.Reflection argIdx++; } - if (methodInfo.Invoke(&targetAttr, params args) case .Ok(var val)) + if (methodInfo.Invoke(&mTargetAttr, params args) case .Ok(var val)) val.Dispose(); - attrIdx++; + mAttrIdx++; return true; } @@ -343,5 +489,151 @@ namespace System.Reflection return Current; } } + + public struct ComptimeTypeCustomAttributeEnumerator : IEnumerator + { + int32 mTypeId; + int32 mAttrIdx; + T mTargetAttr; + + public this(int32 typeId) + { + mTypeId = typeId; + mAttrIdx = -1; + mTargetAttr = ?; + } + + public T Current + { + get + { + return mTargetAttr; + } + } + + public bool MoveNext() mut + { + Type attrType = null; + repeat + { + attrType = Type.[Friend]Comptime_Type_GetCustomAttributeType(mTypeId, ++mAttrIdx); + if (attrType == typeof(T)) + { + if (Type.[Friend]Comptime_Type_GetCustomAttribute(mTypeId, mAttrIdx, &mTargetAttr)) + return true; + } + } while (attrType != null); + return false; + } + + public void Dispose() + { + } + + public Result GetNext() mut + { + if (!MoveNext()) + return .Err; + return Current; + } + } + + public struct ComptimeFieldCustomAttributeEnumerator : IEnumerator + { + int32 mTypeId; + int32 mFieldIdx; + int32 mAttrIdx; + T mTargetAttr; + + public this(int32 typeId, int32 fieldIdx) + { + mTypeId = typeId; + mFieldIdx = fieldIdx; + mAttrIdx = -1; + mTargetAttr = ?; + } + + public T Current + { + get + { + return mTargetAttr; + } + } + + public bool MoveNext() mut + { + Type attrType = null; + repeat + { + attrType = Type.[Friend]Comptime_Field_GetCustomAttributeType(mTypeId, mFieldIdx, ++mAttrIdx); + if (attrType == typeof(T)) + { + if (Type.[Friend]Comptime_Field_GetCustomAttribute(mTypeId, mFieldIdx, mAttrIdx, &mTargetAttr)) + return true; + } + } while (attrType != null); + return false; + } + + public void Dispose() + { + } + + public Result GetNext() mut + { + if (!MoveNext()) + return .Err; + return Current; + } + } + + public struct ComptimeMethodCustomAttributeEnumerator : IEnumerator + { + int64 mMethodHandle; + int32 mAttrIdx; + T mTargetAttr; + + public this(int64 methodHandle) + { + mMethodHandle = methodHandle; + mAttrIdx = -1; + mTargetAttr = ?; + } + + public T Current + { + get + { + return mTargetAttr; + } + } + + public bool MoveNext() mut + { + Type attrType = null; + repeat + { + attrType = Type.[Friend]Comptime_Method_GetCustomAttributeType(mMethodHandle, ++mAttrIdx); + if (attrType == typeof(T)) + { + if (Type.[Friend]Comptime_Method_GetCustomAttribute(mMethodHandle, mAttrIdx, &mTargetAttr)) + return true; + } + } while (attrType != null); + return false; + } + + public void Dispose() + { + } + + public Result GetNext() mut + { + if (!MoveNext()) + return .Err; + return Current; + } + } } } diff --git a/BeefLibs/corlib/src/Reflection/FieldInfo.bf b/BeefLibs/corlib/src/Reflection/FieldInfo.bf index 30aa16c4..f3df2ffe 100644 --- a/BeefLibs/corlib/src/Reflection/FieldInfo.bf +++ b/BeefLibs/corlib/src/Reflection/FieldInfo.bf @@ -231,9 +231,19 @@ namespace System.Reflection { if (Compiler.IsComptime) { - T val = ?; - if (Type.[Friend]Comptime_Field_GetCustomAttribute((int32)mTypeInstance.TypeId, mFieldData.mCustomAttributesIdx, (.)typeof(T).TypeId, &val)) - return val; + int32 attrIdx = -1; + Type attrType = null; + repeat + { + attrType = Type.[Friend]Comptime_Field_GetCustomAttributeType((int32)mTypeInstance.TypeId, mFieldData.mCustomAttributesIdx, ++attrIdx); + if (attrType == typeof(T)) + { + T val = ?; + if (Type.[Friend]Comptime_Field_GetCustomAttribute((int32)mTypeInstance.TypeId, mFieldData.mCustomAttributesIdx, attrIdx, &val)) + return val; + } + } + while (attrType != null); return .Err; } return mTypeInstance.[Friend]GetCustomAttribute(mFieldData.mCustomAttributesIdx); @@ -241,18 +251,26 @@ namespace System.Reflection public AttributeInfo.CustomAttributeEnumerator GetCustomAttributes() { - if (Compiler.IsComptime) - Runtime.NotImplemented(); return mTypeInstance.[Friend]GetCustomAttributes(mFieldData.mCustomAttributesIdx); } + [Comptime] + public AttributeInfo.ComptimeFieldCustomAttributeEnumerator GetCustomAttributes() + { + return .((int32)mTypeInstance.TypeId, mFieldData.mCustomAttributesIdx); + } + public AttributeInfo.CustomAttributeEnumerator GetCustomAttributes() where T : Attribute { - if (Compiler.IsComptime) - Runtime.NotImplemented(); return mTypeInstance.[Friend]GetCustomAttributes(mFieldData.mCustomAttributesIdx); } + [Comptime] + public AttributeInfo.ComptimeFieldCustomAttributeEnumerator GetCustomAttributes() where T : Attribute + { + return .((int32)mTypeInstance.TypeId, mFieldData.mCustomAttributesIdx); + } + void* GetDataPtrAndType(Object value, out Type type) { type = value.[Friend]RawGetType(); diff --git a/BeefLibs/corlib/src/Reflection/MethodInfo.bf b/BeefLibs/corlib/src/Reflection/MethodInfo.bf index d214a8a4..af81e65f 100644 --- a/BeefLibs/corlib/src/Reflection/MethodInfo.bf +++ b/BeefLibs/corlib/src/Reflection/MethodInfo.bf @@ -112,9 +112,19 @@ namespace System.Reflection { if (Compiler.IsComptime) { - T val = ?; - if (Type.[Friend]Comptime_Method_GetCustomAttribute(mData.mComptimeMethodInstance, (.)typeof(T).TypeId, &val)) - return val; + int32 attrIdx = -1; + Type attrType = null; + repeat + { + attrType = Type.[Friend]Comptime_Method_GetCustomAttributeType(mData.mComptimeMethodInstance, ++attrIdx); + if (attrType == typeof(T)) + { + T val = ?; + if (Type.[Friend]Comptime_Method_GetCustomAttribute(mData.mComptimeMethodInstance, attrIdx, &val)) + return val; + } + } + while (attrType != null); return .Err; } return mTypeInstance.[Friend]GetCustomAttribute(mData.mMethodData.mCustomAttributesIdx); @@ -122,18 +132,26 @@ namespace System.Reflection public AttributeInfo.CustomAttributeEnumerator GetCustomAttributes() { - if (Compiler.IsComptime) - Runtime.NotImplemented(); return mTypeInstance.[Friend]GetCustomAttributes(mData.mMethodData.mCustomAttributesIdx); } + [Comptime] + public AttributeInfo.ComptimeMethodCustomAttributeEnumerator GetCustomAttributes() + { + return .(mData.mComptimeMethodInstance); + } + public AttributeInfo.CustomAttributeEnumerator GetCustomAttributes() where T : Attribute { - if (Compiler.IsComptime) - Runtime.NotImplemented(); return mTypeInstance.[Friend]GetCustomAttributes(mData.mMethodData.mCustomAttributesIdx); } + [Comptime] + public AttributeInfo.ComptimeMethodCustomAttributeEnumerator GetCustomAttributes() where T : Attribute + { + return .(mData.mComptimeMethodInstance); + } + public Result GetReturnCustomAttribute() where T : Attribute { if (Compiler.IsComptime) diff --git a/BeefLibs/corlib/src/Type.bf b/BeefLibs/corlib/src/Type.bf index f8db7ed5..17f0b56a 100644 --- a/BeefLibs/corlib/src/Type.bf +++ b/BeefLibs/corlib/src/Type.bf @@ -528,9 +528,12 @@ namespace System static extern Type Comptime_GetTypeByName(StringView name); static extern String Comptime_Type_ToString(int32 typeId); static extern Type Comptime_GetSpecializedType(Type unspecializedType, Span typeArgs); - 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 bool Comptime_Type_GetCustomAttribute(int32 typeId, int32 attributeIdx, void* dataPtr); + static extern bool Comptime_Field_GetCustomAttribute(int32 typeId, int32 fieldIdx, int32 attributeIdx, void* dataPtr); + static extern bool Comptime_Method_GetCustomAttribute(int64 methodHandle, int32 attributeIdx, void* dataPtr); + static extern Type Comptime_Type_GetCustomAttributeType(int32 typeId, int32 attributeIdx); + static extern Type Comptime_Field_GetCustomAttributeType(int32 typeId, int32 fieldIdx, int32 attributeIdx); + static extern Type Comptime_Method_GetCustomAttributeType(int64 methodHandle, int32 attributeIdx); static extern int32 Comptime_GetMethodCount(int32 typeId); static extern int64 Comptime_GetMethod(int32 typeId, int32 methodIdx); static extern String Comptime_Method_ToString(int64 methodHandle); @@ -647,7 +650,16 @@ namespace System { if (Compiler.IsComptime) { - return Comptime_Type_GetCustomAttribute((int32)TypeId, (.)typeof(T).TypeId, null); + int32 attrIdx = -1; + Type attrType = null; + repeat + { + attrType = Type.[Friend]Comptime_Type_GetCustomAttributeType((int32)TypeId, ++attrIdx); + if (attrType == typeof(T)) + return true; + } + while (attrType != null); + return false; } if (var typeInstance = this as TypeInstance) @@ -659,9 +671,19 @@ namespace System { if (Compiler.IsComptime) { - T val = ?; - if (Comptime_Type_GetCustomAttribute((int32)TypeId, (.)typeof(T).TypeId, &val)) - return val; + int32 attrIdx = -1; + Type attrType = null; + repeat + { + attrType = Type.[Friend]Comptime_Type_GetCustomAttributeType((int32)TypeId, ++attrIdx); + if (attrType == typeof(T)) + { + T val = ?; + if (Type.[Friend]Comptime_Type_GetCustomAttribute((int32)TypeId, attrIdx, &val)) + return val; + } + } + while (attrType != null); return .Err; } @@ -672,24 +694,30 @@ namespace System public AttributeInfo.CustomAttributeEnumerator GetCustomAttributes() { - if (Compiler.IsComptime) - Runtime.NotImplemented(); - if (var typeInstance = this as TypeInstance) return typeInstance.[Friend]GetCustomAttributes(typeInstance.[Friend]mCustomAttributesIdx); Runtime.NotImplemented(); } + [Comptime] + public AttributeInfo.ComptimeTypeCustomAttributeEnumerator GetCustomAttributes() + { + return .((int32)TypeId); + } + public AttributeInfo.CustomAttributeEnumerator GetCustomAttributes() where T : Attribute { - if (Compiler.IsComptime) - Runtime.NotImplemented(); - if (var typeInstance = this as TypeInstance) return typeInstance.[Friend]GetCustomAttributes(typeInstance.[Friend]mCustomAttributesIdx); Runtime.NotImplemented(); } + [Comptime] + public AttributeInfo.ComptimeTypeCustomAttributeEnumerator GetCustomAttributes() where T : Attribute + { + return .((int32)TypeId); + } + public override void ToString(String strBuffer) { GetFullName(strBuffer); diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index abd33020..b1909be4 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -2904,6 +2904,13 @@ BfCustomAttribute* BfCustomAttributes::Get(BfType* type) return NULL; } +BfCustomAttribute* BfCustomAttributes::Get(int idx) +{ + if (idx >= mAttributes.size()) + return NULL; + return &mAttributes[idx]; +} + ////////////////////////////////////////////////////////////////////////// BfResolvedTypeSet::~BfResolvedTypeSet() diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 1c6c6252..08570a19 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -2550,6 +2550,7 @@ public: bool Contains(BfTypeDef* typeDef); BfCustomAttribute* Get(BfTypeDef* typeDef); BfCustomAttribute* Get(BfType* type); + BfCustomAttribute* Get(int idx); void ReportMemory(MemReporter* memReporter); }; diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index ff288c5c..760fdb8f 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -3472,16 +3472,12 @@ bool CeContext::GetStringFromStringView(addr_ce addr, StringImpl& str) return true; } -bool CeContext::GetCustomAttribute(BfModule* module, BfIRConstHolder* constHolder, BfCustomAttributes* customAttributes, int attributeTypeId, addr_ce resultAddr) +bool CeContext::GetCustomAttribute(BfModule* module, BfIRConstHolder* constHolder, BfCustomAttributes* customAttributes, int attributeIdx, addr_ce resultAddr) { if (customAttributes == NULL) return false; - BfType* attributeType = GetBfType(attributeTypeId); - if (attributeType == NULL) - return false; - - auto customAttr = customAttributes->Get(attributeType); + auto customAttr = customAttributes->Get(attributeIdx); if (customAttr == NULL) return false; @@ -3504,6 +3500,18 @@ bool CeContext::GetCustomAttribute(BfModule* module, BfIRConstHolder* constHolde return true; } +BfType* CeContext::GetCustomAttributeType(BfCustomAttributes* customAttributes, int attributeIdx) +{ + if (customAttributes == NULL) + return NULL; + + auto customAttr = customAttributes->Get(attributeIdx); + if (customAttr == NULL) + return NULL; + + return customAttr->mType; +} + //#define CE_GETC(T) *((T*)(addr += sizeof(T)) - 1) #define CE_GETC(T) *(T*)(mMemory.mVals + addr) @@ -5130,7 +5138,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* else if (checkFunction->mFunctionKind == CeFunctionKind_Type_GetCustomAttribute) { int32 typeId = *(int32*)((uint8*)stackPtr + 1); - int32 attributeTypeId = *(int32*)((uint8*)stackPtr + 1 + 4); + int32 attributeIdx = *(int32*)((uint8*)stackPtr + 1 + 4); addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 4 + 4); BfType* type = GetBfType(typeId); @@ -5139,7 +5147,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* { auto typeInst = type->ToTypeInstance(); if (typeInst != NULL) - success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, typeInst->mCustomAttributes, attributeTypeId, resultPtr); + success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, typeInst->mCustomAttributes, attributeIdx, resultPtr); _FixVariables(); } @@ -5149,7 +5157,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* { int32 typeId = *(int32*)((uint8*)stackPtr + 1); int32 fieldIdx = *(int32*)((uint8*)stackPtr + 1 + 4); - int32 attributeTypeId = *(int32*)((uint8*)stackPtr + 1 + 4 + 4); + int32 attributeIdx = *(int32*)((uint8*)stackPtr + 1 + 4 + 4); addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 4 + 4 + 4); BfType* type = GetBfType(typeId); @@ -5164,7 +5172,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* if ((fieldIdx >= 0) && (fieldIdx < typeInst->mFieldInstances.mSize)) { auto& fieldInstance = typeInst->mFieldInstances[fieldIdx]; - success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, fieldInstance.mCustomAttributes, attributeTypeId, resultPtr); + success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, fieldInstance.mCustomAttributes, attributeIdx, resultPtr); _FixVariables(); } else if (fieldIdx != -1) @@ -5180,7 +5188,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetCustomAttribute) { int64 methodHandle = *(int64*)((uint8*)stackPtr + 1); - int32 attributeTypeId = *(int32*)((uint8*)stackPtr + 1 + 8); + int32 attributeIdx = *(int32*)((uint8*)stackPtr + 1 + 8); addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 8 + 4); auto methodInstance = mCeMachine->GetMethodInstance(methodHandle); @@ -5189,10 +5197,82 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* _Fail("Invalid method instance"); return false; } - bool success = GetCustomAttribute(mCurModule, methodInstance->GetOwner()->mConstHolder, methodInstance->GetCustomAttributes(), attributeTypeId, resultPtr); + bool success = GetCustomAttribute(mCurModule, methodInstance->GetOwner()->mConstHolder, methodInstance->GetCustomAttributes(), attributeIdx, resultPtr); _FixVariables(); *(addr_ce*)(stackPtr + 0) = success; } + else if (checkFunction->mFunctionKind == CeFunctionKind_Type_GetCustomAttributeType) + { + int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize); + int32 attributeIdx = *(int32*)((uint8*)stackPtr + ptrSize + 4); + + BfType* type = GetBfType(typeId); + addr_ce reflectType = 0; + if (type != NULL) + { + auto typeInst = type->ToTypeInstance(); + if (typeInst != NULL) + { + auto attrType = GetCustomAttributeType(typeInst->mCustomAttributes, attributeIdx); + if (attrType != NULL) + reflectType = GetReflectType(attrType->mTypeId); + } + _FixVariables(); + } + + CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); + } + else if (checkFunction->mFunctionKind == CeFunctionKind_Field_GetCustomAttributeType) + { + int32 typeId = *(int32*)((uint8*)stackPtr + ptrSize); + int32 fieldIdx = *(int32*)((uint8*)stackPtr + ptrSize + 4); + int32 attributeIdx = *(int32*)((uint8*)stackPtr + ptrSize + 4 + 4); + + BfType* type = GetBfType(typeId); + addr_ce reflectType = 0; + if (type != NULL) + { + auto typeInst = type->ToTypeInstance(); + if (typeInst != NULL) + { + if (typeInst->mDefineState < BfTypeDefineState_CETypeInit) + mCurModule->PopulateType(typeInst); + if ((fieldIdx >= 0) && (fieldIdx < typeInst->mFieldInstances.mSize)) + { + auto& fieldInstance = typeInst->mFieldInstances[fieldIdx]; + auto attrType = GetCustomAttributeType(fieldInstance.mCustomAttributes, attributeIdx); + if (attrType != NULL) + reflectType = GetReflectType(attrType->mTypeId); + _FixVariables(); + } + else if (fieldIdx != -1) + { + _Fail("Invalid field"); + return false; + } + } + } + + CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); + } + else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetCustomAttributeType) + { + int64 methodHandle = *(int64*)((uint8*)stackPtr + ptrSize); + int32 attributeIdx = *(int32*)((uint8*)stackPtr + ptrSize + 8); + + auto methodInstance = mCeMachine->GetMethodInstance(methodHandle); + if (methodInstance == NULL) + { + _Fail("Invalid method instance"); + return false; + } + auto attrType = GetCustomAttributeType(methodInstance->GetCustomAttributes(), attributeIdx); + if (attrType != NULL) + CeSetAddrVal(stackPtr + 0, GetReflectType(attrType->mTypeId), ptrSize); + else + CeSetAddrVal(stackPtr + 0, 0, ptrSize); + _FixVariables(); + } else if (checkFunction->mFunctionKind == CeFunctionKind_GetMethodCount) { int32 typeId = *(int32*)((uint8*)stackPtr + 4); @@ -8151,6 +8231,18 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction) { ceFunction->mFunctionKind = CeFunctionKind_Method_GetCustomAttribute; } + else if (methodDef->mName == "Comptime_Type_GetCustomAttributeType") + { + ceFunction->mFunctionKind = CeFunctionKind_Type_GetCustomAttributeType; + } + else if (methodDef->mName == "Comptime_Field_GetCustomAttributeType") + { + ceFunction->mFunctionKind = CeFunctionKind_Field_GetCustomAttributeType; + } + else if (methodDef->mName == "Comptime_Method_GetCustomAttributeType") + { + ceFunction->mFunctionKind = CeFunctionKind_Method_GetCustomAttributeType; + } else if (methodDef->mName == "Comptime_GetMethod") { ceFunction->mFunctionKind = CeFunctionKind_GetMethod; diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index 58808656..dd324811 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -328,6 +328,9 @@ enum CeFunctionKind CeFunctionKind_Type_GetCustomAttribute, CeFunctionKind_Field_GetCustomAttribute, CeFunctionKind_Method_GetCustomAttribute, + CeFunctionKind_Type_GetCustomAttributeType, + CeFunctionKind_Field_GetCustomAttributeType, + CeFunctionKind_Method_GetCustomAttributeType, CeFunctionKind_GetMethodCount, CeFunctionKind_GetMethod, CeFunctionKind_Method_ToString, @@ -908,7 +911,8 @@ public: bool CheckMemory(addr_ce addr, int32 size); bool GetStringFromAddr(addr_ce strInstAddr, StringImpl& str); bool GetStringFromStringView(addr_ce addr, StringImpl& str); - bool GetCustomAttribute(BfModule* module, BfIRConstHolder* constHolder, BfCustomAttributes* customAttributes, int attributeTypeId, addr_ce resultAddr); + bool GetCustomAttribute(BfModule* module, BfIRConstHolder* constHolder, BfCustomAttributes* customAttributes, int attributeIdx, addr_ce resultAddr); + BfType* GetCustomAttributeType(BfCustomAttributes* customAttributes, int attributeIdx); 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);