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:
parent
dd7986aaa9
commit
abd511a93d
14 changed files with 302 additions and 20 deletions
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace System
|
|||
[Ordered]
|
||||
class String : IHashable, IFormattable, IPrintable
|
||||
{
|
||||
enum CreateFlags
|
||||
public enum CreateFlags
|
||||
{
|
||||
None = 0,
|
||||
NullTerminate = 1
|
||||
|
|
|
@ -852,7 +852,8 @@ namespace System.Reflection
|
|||
None = 0,
|
||||
Splat = 1,
|
||||
Implicit = 2,
|
||||
AppendIdx = 4
|
||||
AppendIdx = 4,
|
||||
Params = 8
|
||||
}
|
||||
|
||||
[CRepr, AlwaysInclude]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue