1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

Some refactoring and add GetCustomAttributes for Comptime

This commit is contained in:
disarray2077 2022-02-26 22:31:32 -03:00
parent d52ebfa1db
commit 3df708779d
8 changed files with 557 additions and 97 deletions

View file

@ -116,40 +116,40 @@ namespace System.Reflection
public struct CustomAttributeEnumerator : IEnumerator<Variant>, IDisposable public struct CustomAttributeEnumerator : IEnumerator<Variant>, IDisposable
{ {
void* data; void* mData;
int32 attrIdx; int32 mAttrIdx;
uint8 count; uint8 mCount;
Variant targetAttr; Variant mTargetAttr;
public this(void* inAttrData) public this(void* inAttrData)
{ {
data = inAttrData; mData = inAttrData;
data++; mData++;
attrIdx = 0; mAttrIdx = 0;
count = data != null ? AttributeInfo.Decode!<uint8>(data) : 0; mCount = mData != null ? AttributeInfo.Decode!<uint8>(mData) : 0;
targetAttr = default; mTargetAttr = default;
} }
public Variant Current public Variant Current
{ {
get get
{ {
return targetAttr; return mTargetAttr;
} }
} }
public bool MoveNext() mut public bool MoveNext() mut
{ {
if (attrIdx >= count || data == null) if (mAttrIdx >= mCount || mData == null)
return false; return false;
void* startPtr = data; void* startPtr = mData;
var len = AttributeInfo.Decode!<uint16>(data); var len = AttributeInfo.Decode!<uint16>(mData);
void* endPtr = (uint8*)startPtr + len; void* endPtr = (uint8*)startPtr + len;
var typeId = AttributeInfo.Decode!<TypeId>(data); var typeId = AttributeInfo.Decode!<TypeId>(mData);
var methodIdx = AttributeInfo.Decode!<uint16>(data); var methodIdx = AttributeInfo.Decode!<uint16>(mData);
Type attrType = Type.[Friend]GetType(typeId); Type attrType = Type.[Friend]GetType(typeId);
TypeInstance attrTypeInst = attrType as TypeInstance; TypeInstance attrTypeInst = attrType as TypeInstance;
@ -158,40 +158,40 @@ namespace System.Reflection
Object[] args = scope Object[methodInfo.[Friend]mData.mMethodData.mParamCount]; Object[] args = scope Object[methodInfo.[Friend]mData.mMethodData.mParamCount];
int argIdx = 0; int argIdx = 0;
while (data < endPtr) while (mData < endPtr)
{ {
var attrDataType = AttributeInfo.Decode!<TypeCode>(data); var attrDataType = AttributeInfo.Decode!<TypeCode>(mData);
switch (attrDataType) switch (attrDataType)
{ {
case .Int8, case .Int8,
.UInt8, .UInt8,
.Char8, .Char8,
.Boolean: .Boolean:
let attrData = AttributeInfo.Decode!<int8>(data); let attrData = AttributeInfo.Decode!<int8>(mData);
args[argIdx] = scope:: box attrData; args[argIdx] = scope:: box attrData;
case .Int16, case .Int16,
.UInt16, .UInt16,
.Char16: .Char16:
let attrData = AttributeInfo.Decode!<int16>(data); let attrData = AttributeInfo.Decode!<int16>(mData);
args[argIdx] = scope:: box attrData; args[argIdx] = scope:: box attrData;
case .Int32, case .Int32,
.UInt32, .UInt32,
.Char32: .Char32:
let attrData = AttributeInfo.Decode!<int32>(data); let attrData = AttributeInfo.Decode!<int32>(mData);
args[argIdx] = scope:: box attrData; args[argIdx] = scope:: box attrData;
case .Float: case .Float:
let attrData = AttributeInfo.Decode!<float>(data); let attrData = AttributeInfo.Decode!<float>(mData);
args[argIdx] = scope:: box attrData; args[argIdx] = scope:: box attrData;
case .Int64, case .Int64,
.UInt64, .UInt64,
.Double: .Double:
let attrData = AttributeInfo.Decode!<int64>(data); let attrData = AttributeInfo.Decode!<int64>(mData);
args[argIdx] = scope:: box attrData; args[argIdx] = scope:: box attrData;
case (TypeCode)typeof(TypeCode).MaxValue + 8: //BfConstType_TypeOf case (TypeCode)typeof(TypeCode).MaxValue + 8: //BfConstType_TypeOf
let argTypeId = AttributeInfo.Decode!<int32>(data); let argTypeId = AttributeInfo.Decode!<int32>(mData);
args[argIdx] = Type.[Friend]GetType((.)argTypeId); args[argIdx] = Type.[Friend]GetType((.)argTypeId);
case (TypeCode)255: case (TypeCode)255:
let stringId = AttributeInfo.Decode!<int32>(data); let stringId = AttributeInfo.Decode!<int32>(mData);
String str = String.[Friend]sIdStringLiterals[stringId]; String str = String.[Friend]sIdStringLiterals[stringId];
args[argIdx] = str; args[argIdx] = str;
default: default:
@ -200,19 +200,165 @@ namespace System.Reflection
argIdx++; argIdx++;
} }
targetAttr.Dispose(); mTargetAttr.Dispose();
void* data = Variant.Alloc(attrType, out targetAttr); void* data = Variant.Alloc(attrType, out mTargetAttr);
if (methodInfo.Invoke(data, params args) case .Ok(var val)) if (methodInfo.Invoke(data, params args) case .Ok(var val))
val.Dispose(); val.Dispose();
attrIdx++; mAttrIdx++;
return true; return true;
} }
public void Dispose() mut public void Dispose() mut
{ {
targetAttr.Dispose(); mTargetAttr.Dispose();
}
public Result<Variant> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
public struct ComptimeTypeCustomAttributeEnumerator : IEnumerator<Variant>, 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<Variant> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
public struct ComptimeFieldCustomAttributeEnumerator : IEnumerator<Variant>, 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<Variant> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
public struct ComptimeMethodCustomAttributeEnumerator : IEnumerator<Variant>, 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<Variant> GetNext() mut public Result<Variant> GetNext() mut
@ -225,31 +371,31 @@ namespace System.Reflection
public struct CustomAttributeEnumerator<T> : IEnumerator<T> public struct CustomAttributeEnumerator<T> : IEnumerator<T>
{ {
void* data; void* mData;
int32 attrIdx; int32 mAttrIdx;
uint8 count; uint8 mCount;
T targetAttr; T mTargetAttr;
public this(void* inAttrData) public this(void* inAttrData)
{ {
data = inAttrData; mData = inAttrData;
data++; mData++;
attrIdx = 0; mAttrIdx = 0;
count = data != null ? AttributeInfo.Decode!<uint8>(data) : 0; mCount = mData != null ? AttributeInfo.Decode!<uint8>(mData) : 0;
targetAttr = ?; mTargetAttr = ?;
} }
public T Current public T Current
{ {
get get
{ {
return targetAttr; return mTargetAttr;
} }
} }
public bool MoveNext() mut public bool MoveNext() mut
{ {
if (attrIdx >= count || data == null) if (mAttrIdx >= mCount || mData == null)
return false; return false;
void* endPtr = null; void* endPtr = null;
@ -257,24 +403,24 @@ namespace System.Reflection
while (true) while (true)
{ {
void* startPtr = data; void* startPtr = mData;
var len = AttributeInfo.Decode!<uint16>(data); var len = AttributeInfo.Decode!<uint16>(mData);
endPtr = (uint8*)startPtr + len; endPtr = (uint8*)startPtr + len;
typeId = AttributeInfo.Decode!<TypeId>(data); typeId = AttributeInfo.Decode!<TypeId>(mData);
if (typeId != typeof(T).TypeId) if (typeId != typeof(T).TypeId)
{ {
attrIdx++; mAttrIdx++;
if (attrIdx >= count) if (mAttrIdx >= mCount)
return false; return false;
data = endPtr; mData = endPtr;
continue; continue;
} }
break; break;
} }
var methodIdx = AttributeInfo.Decode!<uint16>(data); var methodIdx = AttributeInfo.Decode!<uint16>(mData);
Type attrType = Type.[Friend]GetType(typeId); Type attrType = Type.[Friend]GetType(typeId);
TypeInstance attrTypeInst = attrType as TypeInstance; TypeInstance attrTypeInst = attrType as TypeInstance;
@ -283,40 +429,40 @@ namespace System.Reflection
Object[] args = scope Object[methodInfo.[Friend]mData.mMethodData.mParamCount]; Object[] args = scope Object[methodInfo.[Friend]mData.mMethodData.mParamCount];
int argIdx = 0; int argIdx = 0;
while (data < endPtr) while (mData < endPtr)
{ {
var attrDataType = AttributeInfo.Decode!<TypeCode>(data); var attrDataType = AttributeInfo.Decode!<TypeCode>(mData);
switch (attrDataType) switch (attrDataType)
{ {
case .Int8, case .Int8,
.UInt8, .UInt8,
.Char8, .Char8,
.Boolean: .Boolean:
let attrData = AttributeInfo.Decode!<int8>(data); let attrData = AttributeInfo.Decode!<int8>(mData);
args[argIdx] = scope:: box attrData; args[argIdx] = scope:: box attrData;
case .Int16, case .Int16,
.UInt16, .UInt16,
.Char16: .Char16:
let attrData = AttributeInfo.Decode!<int16>(data); let attrData = AttributeInfo.Decode!<int16>(mData);
args[argIdx] = scope:: box attrData; args[argIdx] = scope:: box attrData;
case .Int32, case .Int32,
.UInt32, .UInt32,
.Char32: .Char32:
let attrData = AttributeInfo.Decode!<int32>(data); let attrData = AttributeInfo.Decode!<int32>(mData);
args[argIdx] = scope:: box attrData; args[argIdx] = scope:: box attrData;
case .Float: case .Float:
let attrData = AttributeInfo.Decode!<float>(data); let attrData = AttributeInfo.Decode!<float>(mData);
args[argIdx] = scope:: box attrData; args[argIdx] = scope:: box attrData;
case .Int64, case .Int64,
.UInt64, .UInt64,
.Double: .Double:
let attrData = AttributeInfo.Decode!<int64>(data); let attrData = AttributeInfo.Decode!<int64>(mData);
args[argIdx] = scope:: box attrData; args[argIdx] = scope:: box attrData;
case (TypeCode)typeof(TypeCode).MaxValue + 8: //BfConstType_TypeOf case (TypeCode)typeof(TypeCode).MaxValue + 8: //BfConstType_TypeOf
let argTypeId = AttributeInfo.Decode!<int32>(data); let argTypeId = AttributeInfo.Decode!<int32>(mData);
args[argIdx] = Type.[Friend]GetType((.)argTypeId); args[argIdx] = Type.[Friend]GetType((.)argTypeId);
case (TypeCode)255: case (TypeCode)255:
let stringId = AttributeInfo.Decode!<int32>(data); let stringId = AttributeInfo.Decode!<int32>(mData);
String str = String.[Friend]sIdStringLiterals[stringId]; String str = String.[Friend]sIdStringLiterals[stringId];
args[argIdx] = str; args[argIdx] = str;
default: default:
@ -325,10 +471,10 @@ namespace System.Reflection
argIdx++; argIdx++;
} }
if (methodInfo.Invoke(&targetAttr, params args) case .Ok(var val)) if (methodInfo.Invoke(&mTargetAttr, params args) case .Ok(var val))
val.Dispose(); val.Dispose();
attrIdx++; mAttrIdx++;
return true; return true;
} }
@ -343,5 +489,151 @@ namespace System.Reflection
return Current; return Current;
} }
} }
public struct ComptimeTypeCustomAttributeEnumerator<T> : IEnumerator<T>
{
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<T> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
public struct ComptimeFieldCustomAttributeEnumerator<T> : IEnumerator<T>
{
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<T> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
public struct ComptimeMethodCustomAttributeEnumerator<T> : IEnumerator<T>
{
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<T> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
} }
} }

View file

@ -231,9 +231,19 @@ namespace System.Reflection
{ {
if (Compiler.IsComptime) if (Compiler.IsComptime)
{ {
T val = ?; int32 attrIdx = -1;
if (Type.[Friend]Comptime_Field_GetCustomAttribute((int32)mTypeInstance.TypeId, mFieldData.mCustomAttributesIdx, (.)typeof(T).TypeId, &val)) Type attrType = null;
return val; 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 .Err;
} }
return mTypeInstance.[Friend]GetCustomAttribute<T>(mFieldData.mCustomAttributesIdx); return mTypeInstance.[Friend]GetCustomAttribute<T>(mFieldData.mCustomAttributesIdx);
@ -241,18 +251,26 @@ namespace System.Reflection
public AttributeInfo.CustomAttributeEnumerator GetCustomAttributes() public AttributeInfo.CustomAttributeEnumerator GetCustomAttributes()
{ {
if (Compiler.IsComptime)
Runtime.NotImplemented();
return mTypeInstance.[Friend]GetCustomAttributes(mFieldData.mCustomAttributesIdx); return mTypeInstance.[Friend]GetCustomAttributes(mFieldData.mCustomAttributesIdx);
} }
[Comptime]
public AttributeInfo.ComptimeFieldCustomAttributeEnumerator GetCustomAttributes()
{
return .((int32)mTypeInstance.TypeId, mFieldData.mCustomAttributesIdx);
}
public AttributeInfo.CustomAttributeEnumerator<T> GetCustomAttributes<T>() where T : Attribute public AttributeInfo.CustomAttributeEnumerator<T> GetCustomAttributes<T>() where T : Attribute
{ {
if (Compiler.IsComptime)
Runtime.NotImplemented();
return mTypeInstance.[Friend]GetCustomAttributes<T>(mFieldData.mCustomAttributesIdx); return mTypeInstance.[Friend]GetCustomAttributes<T>(mFieldData.mCustomAttributesIdx);
} }
[Comptime]
public AttributeInfo.ComptimeFieldCustomAttributeEnumerator<T> GetCustomAttributes<T>() where T : Attribute
{
return .((int32)mTypeInstance.TypeId, mFieldData.mCustomAttributesIdx);
}
void* GetDataPtrAndType(Object value, out Type type) void* GetDataPtrAndType(Object value, out Type type)
{ {
type = value.[Friend]RawGetType(); type = value.[Friend]RawGetType();

View file

@ -112,9 +112,19 @@ namespace System.Reflection
{ {
if (Compiler.IsComptime) if (Compiler.IsComptime)
{ {
T val = ?; int32 attrIdx = -1;
if (Type.[Friend]Comptime_Method_GetCustomAttribute(mData.mComptimeMethodInstance, (.)typeof(T).TypeId, &val)) Type attrType = null;
return val; 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 .Err;
} }
return mTypeInstance.[Friend]GetCustomAttribute<T>(mData.mMethodData.mCustomAttributesIdx); return mTypeInstance.[Friend]GetCustomAttribute<T>(mData.mMethodData.mCustomAttributesIdx);
@ -122,18 +132,26 @@ namespace System.Reflection
public AttributeInfo.CustomAttributeEnumerator GetCustomAttributes() public AttributeInfo.CustomAttributeEnumerator GetCustomAttributes()
{ {
if (Compiler.IsComptime)
Runtime.NotImplemented();
return mTypeInstance.[Friend]GetCustomAttributes(mData.mMethodData.mCustomAttributesIdx); return mTypeInstance.[Friend]GetCustomAttributes(mData.mMethodData.mCustomAttributesIdx);
} }
[Comptime]
public AttributeInfo.ComptimeMethodCustomAttributeEnumerator GetCustomAttributes()
{
return .(mData.mComptimeMethodInstance);
}
public AttributeInfo.CustomAttributeEnumerator<T> GetCustomAttributes<T>() where T : Attribute public AttributeInfo.CustomAttributeEnumerator<T> GetCustomAttributes<T>() where T : Attribute
{ {
if (Compiler.IsComptime)
Runtime.NotImplemented();
return mTypeInstance.[Friend]GetCustomAttributes<T>(mData.mMethodData.mCustomAttributesIdx); return mTypeInstance.[Friend]GetCustomAttributes<T>(mData.mMethodData.mCustomAttributesIdx);
} }
[Comptime]
public AttributeInfo.ComptimeMethodCustomAttributeEnumerator<T> GetCustomAttributes<T>() where T : Attribute
{
return .(mData.mComptimeMethodInstance);
}
public Result<T> GetReturnCustomAttribute<T>() where T : Attribute public Result<T> GetReturnCustomAttribute<T>() where T : Attribute
{ {
if (Compiler.IsComptime) if (Compiler.IsComptime)

View file

@ -528,9 +528,12 @@ namespace System
static extern Type Comptime_GetTypeByName(StringView name); static extern Type Comptime_GetTypeByName(StringView name);
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 attributeIdx, void* dataPtr);
static extern bool Comptime_Field_GetCustomAttribute(int32 typeId, int32 fieldIdx, int32 attributeId, 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 attributeId, 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 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);
@ -647,7 +650,16 @@ namespace System
{ {
if (Compiler.IsComptime) 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) if (var typeInstance = this as TypeInstance)
@ -659,9 +671,19 @@ namespace System
{ {
if (Compiler.IsComptime) if (Compiler.IsComptime)
{ {
T val = ?; int32 attrIdx = -1;
if (Comptime_Type_GetCustomAttribute((int32)TypeId, (.)typeof(T).TypeId, &val)) Type attrType = null;
return val; 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; return .Err;
} }
@ -672,24 +694,30 @@ namespace System
public AttributeInfo.CustomAttributeEnumerator GetCustomAttributes() public AttributeInfo.CustomAttributeEnumerator GetCustomAttributes()
{ {
if (Compiler.IsComptime)
Runtime.NotImplemented();
if (var typeInstance = this as TypeInstance) if (var typeInstance = this as TypeInstance)
return typeInstance.[Friend]GetCustomAttributes(typeInstance.[Friend]mCustomAttributesIdx); return typeInstance.[Friend]GetCustomAttributes(typeInstance.[Friend]mCustomAttributesIdx);
Runtime.NotImplemented(); Runtime.NotImplemented();
} }
[Comptime]
public AttributeInfo.ComptimeTypeCustomAttributeEnumerator GetCustomAttributes()
{
return .((int32)TypeId);
}
public AttributeInfo.CustomAttributeEnumerator<T> GetCustomAttributes<T>() where T : Attribute public AttributeInfo.CustomAttributeEnumerator<T> GetCustomAttributes<T>() where T : Attribute
{ {
if (Compiler.IsComptime)
Runtime.NotImplemented();
if (var typeInstance = this as TypeInstance) if (var typeInstance = this as TypeInstance)
return typeInstance.[Friend]GetCustomAttributes<T>(typeInstance.[Friend]mCustomAttributesIdx); return typeInstance.[Friend]GetCustomAttributes<T>(typeInstance.[Friend]mCustomAttributesIdx);
Runtime.NotImplemented(); Runtime.NotImplemented();
} }
[Comptime]
public AttributeInfo.ComptimeTypeCustomAttributeEnumerator<T> GetCustomAttributes<T>() where T : Attribute
{
return .((int32)TypeId);
}
public override void ToString(String strBuffer) public override void ToString(String strBuffer)
{ {
GetFullName(strBuffer); GetFullName(strBuffer);

View file

@ -2904,6 +2904,13 @@ BfCustomAttribute* BfCustomAttributes::Get(BfType* type)
return NULL; return NULL;
} }
BfCustomAttribute* BfCustomAttributes::Get(int idx)
{
if (idx >= mAttributes.size())
return NULL;
return &mAttributes[idx];
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
BfResolvedTypeSet::~BfResolvedTypeSet() BfResolvedTypeSet::~BfResolvedTypeSet()

View file

@ -2550,6 +2550,7 @@ public:
bool Contains(BfTypeDef* typeDef); bool Contains(BfTypeDef* typeDef);
BfCustomAttribute* Get(BfTypeDef* typeDef); BfCustomAttribute* Get(BfTypeDef* typeDef);
BfCustomAttribute* Get(BfType* type); BfCustomAttribute* Get(BfType* type);
BfCustomAttribute* Get(int idx);
void ReportMemory(MemReporter* memReporter); void ReportMemory(MemReporter* memReporter);
}; };

View file

@ -3472,16 +3472,12 @@ bool CeContext::GetStringFromStringView(addr_ce addr, StringImpl& str)
return true; 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) if (customAttributes == NULL)
return false; return false;
BfType* attributeType = GetBfType(attributeTypeId); auto customAttr = customAttributes->Get(attributeIdx);
if (attributeType == NULL)
return false;
auto customAttr = customAttributes->Get(attributeType);
if (customAttr == NULL) if (customAttr == NULL)
return false; return false;
@ -3504,6 +3500,18 @@ bool CeContext::GetCustomAttribute(BfModule* module, BfIRConstHolder* constHolde
return true; 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*)(addr += sizeof(T)) - 1)
#define CE_GETC(T) *(T*)(mMemory.mVals + addr) #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) else if (checkFunction->mFunctionKind == CeFunctionKind_Type_GetCustomAttribute)
{ {
int32 typeId = *(int32*)((uint8*)stackPtr + 1); 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); addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 4 + 4);
BfType* type = GetBfType(typeId); BfType* type = GetBfType(typeId);
@ -5139,7 +5147,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
{ {
auto typeInst = type->ToTypeInstance(); auto typeInst = type->ToTypeInstance();
if (typeInst != NULL) if (typeInst != NULL)
success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, typeInst->mCustomAttributes, attributeTypeId, resultPtr); success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, typeInst->mCustomAttributes, attributeIdx, resultPtr);
_FixVariables(); _FixVariables();
} }
@ -5149,7 +5157,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
{ {
int32 typeId = *(int32*)((uint8*)stackPtr + 1); int32 typeId = *(int32*)((uint8*)stackPtr + 1);
int32 fieldIdx = *(int32*)((uint8*)stackPtr + 1 + 4); 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); addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 4 + 4 + 4);
BfType* type = GetBfType(typeId); BfType* type = GetBfType(typeId);
@ -5164,7 +5172,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
if ((fieldIdx >= 0) && (fieldIdx < typeInst->mFieldInstances.mSize)) if ((fieldIdx >= 0) && (fieldIdx < typeInst->mFieldInstances.mSize))
{ {
auto& fieldInstance = typeInst->mFieldInstances[fieldIdx]; auto& fieldInstance = typeInst->mFieldInstances[fieldIdx];
success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, fieldInstance.mCustomAttributes, attributeTypeId, resultPtr); success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, fieldInstance.mCustomAttributes, attributeIdx, resultPtr);
_FixVariables(); _FixVariables();
} }
else if (fieldIdx != -1) else if (fieldIdx != -1)
@ -5180,7 +5188,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetCustomAttribute) else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetCustomAttribute)
{ {
int64 methodHandle = *(int64*)((uint8*)stackPtr + 1); 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); addr_ce resultPtr = *(addr_ce*)((uint8*)stackPtr + 1 + 8 + 4);
auto methodInstance = mCeMachine->GetMethodInstance(methodHandle); auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
@ -5189,10 +5197,82 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_Fail("Invalid method instance"); _Fail("Invalid method instance");
return false; 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(); _FixVariables();
*(addr_ce*)(stackPtr + 0) = success; *(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) else if (checkFunction->mFunctionKind == CeFunctionKind_GetMethodCount)
{ {
int32 typeId = *(int32*)((uint8*)stackPtr + 4); int32 typeId = *(int32*)((uint8*)stackPtr + 4);
@ -8151,6 +8231,18 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
{ {
ceFunction->mFunctionKind = CeFunctionKind_Method_GetCustomAttribute; 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") else if (methodDef->mName == "Comptime_GetMethod")
{ {
ceFunction->mFunctionKind = CeFunctionKind_GetMethod; ceFunction->mFunctionKind = CeFunctionKind_GetMethod;

View file

@ -328,6 +328,9 @@ enum CeFunctionKind
CeFunctionKind_Type_GetCustomAttribute, CeFunctionKind_Type_GetCustomAttribute,
CeFunctionKind_Field_GetCustomAttribute, CeFunctionKind_Field_GetCustomAttribute,
CeFunctionKind_Method_GetCustomAttribute, CeFunctionKind_Method_GetCustomAttribute,
CeFunctionKind_Type_GetCustomAttributeType,
CeFunctionKind_Field_GetCustomAttributeType,
CeFunctionKind_Method_GetCustomAttributeType,
CeFunctionKind_GetMethodCount, CeFunctionKind_GetMethodCount,
CeFunctionKind_GetMethod, CeFunctionKind_GetMethod,
CeFunctionKind_Method_ToString, CeFunctionKind_Method_ToString,
@ -908,7 +911,8 @@ 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(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); 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);