1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-30 21:36:00 +02:00

Comptime method reflection, method entry/exit emission

This commit is contained in:
Brian Fiete 2021-01-13 05:09:09 -08:00
parent bc8758bbac
commit 8f3060fd3c
18 changed files with 944 additions and 117 deletions

View file

@ -1,3 +1,4 @@
using System.Reflection;
namespace System
{
public struct Attribute
@ -542,6 +543,6 @@ namespace System
interface IComptimeMethodApply
{
void ApplyToMethod(Type type);
void ApplyToMethod(ComptimeMethodInfo methodInfo);
}
}

View file

@ -69,7 +69,10 @@ namespace System
static extern void* Comptime_MethodBuilder_EmitStr(void* native, StringView str);
static extern void* Comptime_CreateMethod(int32 typeId, StringView methodName, Type returnType, MethodFlags methodFlags);
static extern void Comptime_EmitDefinition(int32 typeId, StringView text);
static extern void Comptime_EmitTypeBody(int32 typeId, StringView text);
static extern void Comptime_EmitMethodEntry(int64 methodHandle, StringView text);
static extern void Comptime_EmitMethodExit(int64 methodHandle, StringView text);
static extern void Comptime_EmitMixin(StringView text);
[Comptime(OnlyFromComptime=true)]
public static MethodBuilder CreateMethod(Type owner, StringView methodName, Type returnType, MethodFlags methodFlags)
@ -80,9 +83,28 @@ namespace System
}
[Comptime(OnlyFromComptime=true)]
public static void EmitDefinition(Type owner, StringView text)
public static void EmitTypeBody(Type owner, StringView text)
{
Comptime_EmitDefinition((.)owner.TypeId, text);
}
Comptime_EmitTypeBody((.)owner.TypeId, text);
}
[Comptime(OnlyFromComptime=true)]
public static void EmitMethodEntry(ComptimeMethodInfo methodHandle, StringView text)
{
Comptime_EmitMethodEntry(methodHandle.mNativeMethodInstance, text);
}
[Comptime(OnlyFromComptime=true)]
public static void EmitMethodExit(ComptimeMethodInfo methodHandle, StringView text)
{
Comptime_EmitMethodExit(methodHandle.mNativeMethodInstance, text);
}
[Comptime]
public static void Mixin(StringView text)
{
if (Compiler.IsComptime)
Comptime_EmitMixin(text);
}
}
}

View file

@ -0,0 +1,153 @@
using System.Diagnostics;
using System.Collections;
namespace System.Reflection
{
struct ComptimeMethodInfo
{
[CRepr, Packed]
public struct Info
{
public int32 mReturnTypeId;
public int32 mParamCount;
public MethodFlags mMethodFlags;
}
[CRepr, Packed]
public struct ParamInfo
{
public int32 mParamTypeId;
public TypeInstance.ParamFlags mParamFlags;
public String mName;
}
public int64 mNativeMethodInstance;
public bool IsInitialized => true;
public StringView Name
{
get
{
if (Compiler.IsComptime)
Type.[Friend]Comptime_Method_GetName(mNativeMethodInstance);
return "";
}
}
public int ParamCount
{
get
{
if (Compiler.IsComptime)
return Type.[Friend]Comptime_Method_GetInfo(mNativeMethodInstance).mParamCount;
return 0;
}
}
public bool IsConstructor => Name == "__BfCtor" || Name == "__BfStaticCtor";
public bool IsDestructor => Name == "__BfStaticDtor" || Name == "__BfStaticDtor";
public Type ReturnType
{
get
{
if (Compiler.IsComptime)
Type.[Friend]GetType((.)Type.[Friend]Comptime_Method_GetInfo(mNativeMethodInstance).mReturnTypeId);
return null;
}
}
public this(int64 nativeMethodInstance)
{
mNativeMethodInstance = nativeMethodInstance;
}
public Type GetParamType(int paramIdx)
{
if (Compiler.IsComptime)
return Type.[Friend]GetType((.)Type.[Friend]Comptime_Method_GetParamInfo(mNativeMethodInstance, (.)paramIdx).mParamTypeId);
return null;
}
public StringView GetParamName(int paramIdx)
{
if (Compiler.IsComptime)
return Type.[Friend]Comptime_Method_GetParamInfo(mNativeMethodInstance, (.)paramIdx).mName;
return default;
}
public override void ToString(String strBuffer)
{
if (Compiler.IsComptime)
{
String str = Type.[Friend]Comptime_Method_ToString(mNativeMethodInstance);
strBuffer.Append(str);
}
}
public struct Enumerator : IEnumerator<ComptimeMethodInfo>
{
BindingFlags mBindingFlags;
TypeInstance mTypeInstance;
int32 mIdx;
int32 mCount;
public this(TypeInstance typeInst, BindingFlags bindingFlags)
{
//Debug.WriteLine($"this {typeInst}");
mTypeInstance = typeInst;
mBindingFlags = bindingFlags;
mIdx = -1;
if ((mTypeInstance == null) || (!Compiler.IsComptime))
mCount = 0;
else
mCount = Type.[Friend]Comptime_GetMethodCount((.)mTypeInstance.TypeId);
}
public void Reset() mut
{
mIdx = -1;
}
public void Dispose()
{
}
public bool MoveNext() mut
{
if (mTypeInstance == null)
return false;
for (;;)
{
mIdx++;
if (mIdx == mCount)
return false;
int64 nativeMethodHandle = Type.[Friend]Comptime_GetMethod((int32)mTypeInstance.TypeId, mIdx);
let info = Type.[Friend]Comptime_Method_GetInfo(nativeMethodHandle);
bool matches = (mBindingFlags.HasFlag(BindingFlags.Static) && (info.mMethodFlags.HasFlag(.Static)));
matches |= (mBindingFlags.HasFlag(BindingFlags.Instance) && (!info.mMethodFlags.HasFlag(.Static)));
if (matches)
break;
}
return true;
}
public ComptimeMethodInfo Current
{
get
{
int64 nativeMethodHandle = Type.[Friend]Comptime_GetMethod((int32)mTypeInstance.TypeId, mIdx);
return ComptimeMethodInfo(nativeMethodHandle);
}
}
public Result<ComptimeMethodInfo> GetNext() mut
{
if (!MoveNext())
return .Err;
return Current;
}
}
}
}

View file

@ -16,6 +16,12 @@ namespace System
return MethodInfo.Enumerator(null, bindingFlags);
}
[Comptime]
public virtual ComptimeMethodInfo.Enumerator GetMethods(BindingFlags bindingFlags = cDefaultLookup)
{
return ComptimeMethodInfo.Enumerator(null, bindingFlags);
}
public virtual Result<MethodInfo, MethodError> GetMethod(StringView methodName, BindingFlags bindingFlags = cDefaultLookup)
{
MethodInfo matched = default;
@ -40,6 +46,16 @@ namespace System
return .Err(.NoResults);
}
[Comptime]
public virtual Result<ComptimeMethodInfo, MethodError> GetMethod(int methodIdx)
{
int64 nativeMethod = Comptime_GetMethod((.)TypeId, (.)methodIdx);
if (nativeMethod == 0)
return .Err(.NoResults);
return ComptimeMethodInfo(nativeMethod);
}
public virtual Result<Object> CreateObject()
{
return .Err;
@ -66,6 +82,12 @@ namespace System.Reflection
return MethodInfo.Enumerator(this, bindingFlags);
}
[Comptime]
public override ComptimeMethodInfo.Enumerator GetMethods(BindingFlags bindingFlags = cDefaultLookup)
{
return ComptimeMethodInfo.Enumerator(this, bindingFlags);
}
public override Result<MethodInfo, MethodError> GetMethod(int methodIdx)
{
if ((methodIdx < 0) || (methodIdx >= mMethodDataCount))

View file

@ -475,6 +475,12 @@ namespace System
static extern Type Comptime_GetTypeByName(StringView name);
static extern Type Comptime_GetSpecializedType(Type unspecializedType, Span<Type> typeArgs);
static extern bool Comptime_Type_GetCustomAttribute(int32 typeId, int32 attributeId, void* dataPtr);
static extern int32 Comptime_GetMethodCount(int32 typeId);
static extern int64 Comptime_GetMethod(int32 typeId, int32 methodIdx);
static extern String Comptime_Method_ToString(int64 methodHandle);
static extern String Comptime_Method_GetName(int64 methodHandle);
static extern ComptimeMethodInfo.Info Comptime_Method_GetInfo(int64 methodHandle);
static extern ComptimeMethodInfo.ParamInfo Comptime_Method_GetParamInfo(int64 methodHandle, int32 paramIdx);
protected static Type GetType(TypeId typeId)
{