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

Added '->' operator, static indexer fix, RefCounted<T>

This commit is contained in:
Brian Fiete 2022-06-22 08:35:25 -07:00
parent dd7986aaa9
commit abd511a93d
14 changed files with 302 additions and 20 deletions

View file

@ -6,7 +6,7 @@ namespace System
interface IRefCounted
{
void AddRef();
void ReleaseRef();
void Release();
}
class RefCounted : IRefCounted
@ -63,5 +63,167 @@ namespace System
Debug.Assert(refCount >= 0);
return refCount;
}
void IRefCounted.Release()
{
ReleaseRef();
}
struct Alloc
{
public void* Alloc(Type type, int size, int align)
{
int sizeAdd = size + Math.Max(align, sizeof(int));
void* data = Internal.Malloc(sizeAdd);
return (uint8*)data + sizeAdd;
}
}
}
class RefCounted<T> : IRefCounted where T : class, delete
{
public T mVal;
public int mRefCount = 1;
public int RefCount => mRefCount;
public T Value => mVal;
protected this()
{
}
protected ~this()
{
Debug.Assert(mRefCount == 0);
delete mVal;
}
[OnCompile(.TypeInit), Comptime]
static void Init()
{
String emitStr = scope .();
for (var methodInfo in typeof(T).GetMethods(.Public))
{
if (methodInfo.IsStatic)
continue;
if (!methodInfo.IsConstructor)
continue;
emitStr.AppendF("public static RefCounted<T> Create(");
methodInfo.GetParamsDecl(emitStr);
emitStr.AppendF(")\n");
emitStr.AppendF("{{\n");
emitStr.AppendF("\treturn new [Friend] RefCountedAppend<T>(");
methodInfo.GetArgsList(emitStr);
emitStr.AppendF(");\n}}\n");
}
Compiler.EmitTypeBody(typeof(Self), emitStr);
}
public static RefCounted<T> Attach(T val)
{
return new Self() { mVal = val };
}
public virtual void DeleteSelf()
{
delete this;
}
public void DeleteUnchecked()
{
mRefCount = 0;
DeleteSelf();
}
public void AddRef()
{
Interlocked.Increment(ref mRefCount);
}
public void Release()
{
int refCount = Interlocked.Decrement(ref mRefCount);
Debug.Assert(refCount >= 0);
if (refCount == 0)
DeleteSelf();
}
public void ReleaseLastRef()
{
int refCount = Interlocked.Decrement(ref mRefCount);
Debug.Assert(refCount == 0);
if (refCount == 0)
DeleteSelf();
}
public int ReleaseRefNoDelete()
{
int refCount = Interlocked.Decrement(ref mRefCount);
Debug.Assert(refCount >= 0);
return refCount;
}
public virtual T Detach()
{
var val = mVal;
mVal = null;
return val;
}
public static T operator->(Self self)
{
return self.mVal;
}
public static T operator implicit(Self self)
{
return self.mVal;
}
}
class RefCountedAppend<T> : RefCounted<T> where T : class, new, delete
{
protected ~this()
{
Debug.Assert(mRefCount == 0);
delete:append mVal;
mVal = null;
}
[OnCompile(.TypeInit), Comptime]
static void Init()
{
String emitStr = scope .();
for (var methodInfo in typeof(T).GetMethods(.Public))
{
if (methodInfo.IsStatic)
continue;
if (!methodInfo.IsConstructor)
continue;
emitStr.AppendF("[AllowAppend]\nprotected this(");
methodInfo.GetParamsDecl(emitStr);
emitStr.AppendF(")\n");
emitStr.AppendF("{{\n");
emitStr.AppendF("\tvar val = append T(");
methodInfo.GetArgsList(emitStr);
emitStr.AppendF(");\n");
emitStr.AppendF("\tmVal = val;\n");
emitStr.AppendF("}}\n");
}
Compiler.EmitTypeBody(typeof(Self), emitStr);
}
public override T Detach()
{
Runtime.FatalError("Can only detach from objects created via RefCounted<T>.Attach");
}
}
}

View file

@ -50,6 +50,9 @@ namespace System.Reflection
public bool IsReadOnly => Compiler.IsComptime ?
Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mMethodFlags.HasFlag(.ReadOnly) :
mData.mMethodData.[Friend]mFlags.HasFlag(.ReadOnly);
public bool IsStatic => Compiler.IsComptime ?
Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mMethodFlags.HasFlag(.Static) :
mData.mMethodData.[Friend]mFlags.HasFlag(.Static);
public StringView Name => Compiler.IsComptime ?
Type.[Friend]Comptime_Method_GetName(mData.mComptimeMethodInstance) :
@ -112,6 +115,19 @@ namespace System.Reflection
}
}
public TypeInstance.ParamFlags GetParamFlags(int paramIdx)
{
if (Compiler.IsComptime)
{
return Type.[Friend]Comptime_Method_GetParamInfo(mData.mComptimeMethodInstance, (.)paramIdx).mParamFlags;
}
else
{
Debug.Assert((uint)paramIdx < (uint)mData.mMethodData.mParamCount);
return mData.mMethodData.mParamData[paramIdx].mParamFlags;
}
}
public Result<T> GetParamCustomAttribute<T>(int paramIdx) where T : Attribute
{
if (Compiler.IsComptime)
@ -967,19 +983,60 @@ namespace System.Reflection
strBuffer.Append(' ');
strBuffer.Append(mData.mMethodData.mName);
strBuffer.Append('(');
int useParamIdx = 0;
for (int paramIdx < mData.mMethodData.mParamCount)
{
if (paramIdx > 0)
strBuffer.Append(", ");
let paramData = mData.mMethodData.mParamData[paramIdx];
let paramType = Type.[Friend]GetType(paramData.mType);
if (paramData.mParamFlags.HasFlag(.Implicit))
continue;
if (useParamIdx > 0)
strBuffer.Append(", ");
paramType.ToString(strBuffer);
strBuffer.Append(' ');
strBuffer.Append(paramData.mName);
useParamIdx++;
}
strBuffer.Append(')');
}
public void GetParamsDecl(String strBuffer)
{
int useParamIdx = 0;
for (int paramIdx < ParamCount)
{
var flag = GetParamFlags(paramIdx);
if (flag.HasFlag(.Implicit))
continue;
if (useParamIdx > 0)
strBuffer.Append(", ");
if (flag.HasFlag(.Params))
strBuffer.Append("params ");
strBuffer.Append(GetParamType(paramIdx));
strBuffer.Append(" ");
strBuffer.Append(GetParamName(paramIdx));
useParamIdx++;
}
}
public void GetArgsList(String strBuffer)
{
int useParamIdx = 0;
for (int paramIdx < ParamCount)
{
var flag = GetParamFlags(paramIdx);
if (flag.HasFlag(.Implicit))
continue;
if (useParamIdx > 0)
strBuffer.Append(", ");
if (flag.HasFlag(.Params))
strBuffer.Append("params ");
strBuffer.Append(GetParamName(paramIdx));
useParamIdx++;
}
}
public struct Enumerator : IEnumerator<MethodInfo>
{
BindingFlags mBindingFlags;

View file

@ -40,7 +40,7 @@ namespace System
[Ordered]
class String : IHashable, IFormattable, IPrintable
{
enum CreateFlags
public enum CreateFlags
{
None = 0,
NullTerminate = 1

View file

@ -852,7 +852,8 @@ namespace System.Reflection
None = 0,
Splat = 1,
Implicit = 2,
AppendIdx = 4
AppendIdx = 4,
Params = 8
}
[CRepr, AlwaysInclude]