mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Added GetFieldReference, ability to explicitly reference in Variant
This commit is contained in:
parent
5cfe9e6196
commit
78dd56d6c5
11 changed files with 279 additions and 54 deletions
|
@ -216,6 +216,30 @@ namespace System.Reflection
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Result<Variant> GetValueReference(Object target)
|
||||||
|
{
|
||||||
|
Variant value = Variant();
|
||||||
|
|
||||||
|
Type tTarget;
|
||||||
|
void* targetDataAddr = GetDataPtrAndType(target, out tTarget);
|
||||||
|
|
||||||
|
if (!tTarget.IsSubtypeOf(mTypeInstance))
|
||||||
|
Runtime.FatalError("Invalid type");
|
||||||
|
|
||||||
|
targetDataAddr = (uint8*)targetDataAddr + mFieldData.mDataOffset;
|
||||||
|
|
||||||
|
Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId);
|
||||||
|
|
||||||
|
TypeCode typeCode = fieldType.[Friend]mTypeCode;
|
||||||
|
if (typeCode == TypeCode.Enum)
|
||||||
|
typeCode = fieldType.UnderlyingType.[Friend]mTypeCode;
|
||||||
|
|
||||||
|
value = Variant.CreateReference(fieldType, targetDataAddr);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Result<Variant> GetValue()
|
public Result<Variant> GetValue()
|
||||||
{
|
{
|
||||||
Variant value = Variant();
|
Variant value = Variant();
|
||||||
|
|
|
@ -137,7 +137,16 @@ namespace System.Reflection
|
||||||
added = true;
|
added = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if ((Type)argType != refParamType.UnderlyingType)
|
||||||
isValid = false;
|
isValid = false;
|
||||||
|
|
||||||
|
ffiParamList.Add(&FFIType.Pointer);
|
||||||
|
int* stackDataPtr = scope:mixin int();
|
||||||
|
*stackDataPtr = (int)dataPtr;
|
||||||
|
ffiArgList.Add(stackDataPtr);
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (paramType.IsValueType)
|
else if (paramType.IsValueType)
|
||||||
{
|
{
|
||||||
|
@ -412,8 +421,23 @@ namespace System.Reflection
|
||||||
added = true;
|
added = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
var elemType = argType.UnderlyingType;
|
||||||
|
if (elemType != refParamType.UnderlyingType)
|
||||||
|
{
|
||||||
|
if (elemType.IsTypedPrimitive)
|
||||||
|
elemType = elemType.UnderlyingType;
|
||||||
|
if (elemType != refParamType.UnderlyingType)
|
||||||
isValid = false;
|
isValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ffiParamList.Add(&FFIType.Pointer);
|
||||||
|
int* stackDataPtr = scope:mixin int();
|
||||||
|
*stackDataPtr = (int)dataPtr;
|
||||||
|
ffiArgList.Add(stackDataPtr);
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (paramType.IsValueType)
|
else if (paramType.IsValueType)
|
||||||
{
|
{
|
||||||
bool handled = true;
|
bool handled = true;
|
||||||
|
|
|
@ -757,6 +757,12 @@ namespace System.Reflection
|
||||||
}
|
}
|
||||||
strBuffer.Append(')');
|
strBuffer.Append(')');
|
||||||
}
|
}
|
||||||
|
else if (mTypeFlags.HasFlag(.Boxed))
|
||||||
|
{
|
||||||
|
strBuffer.Append("boxed ");
|
||||||
|
let ut = UnderlyingType;
|
||||||
|
ut.GetFullName(strBuffer);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mOuterType != 0)
|
if (mOuterType != 0)
|
||||||
|
@ -770,6 +776,7 @@ namespace System.Reflection
|
||||||
strBuffer.Append(mNamespace, ".");
|
strBuffer.Append(mNamespace, ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mName != null)
|
||||||
strBuffer.Append(mName);
|
strBuffer.Append(mName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,21 @@ namespace System
|
||||||
{
|
{
|
||||||
struct Variant
|
struct Variant
|
||||||
{
|
{
|
||||||
int mStructType; // 0 = unowned object, 1 = owned object, 2 = null value (mData is type), otherwise is struct type
|
enum ObjectType
|
||||||
|
{
|
||||||
|
UnownedObject,
|
||||||
|
OwnedObject,
|
||||||
|
NullObject
|
||||||
|
}
|
||||||
|
|
||||||
|
enum StructFlag
|
||||||
|
{
|
||||||
|
InternalValue,
|
||||||
|
OwnedPtr,
|
||||||
|
ExternalPtr
|
||||||
|
}
|
||||||
|
|
||||||
|
int mStructType; // 0 = unowned object, 1 = owned object, 2 = null value (mData is type), otherwise is struct type (|0 is internal, |1 is owned ptr, |2 is external ptr)
|
||||||
int mData; // This is either an Object reference, struct data, or a pointer to struct data
|
int mData; // This is either an Object reference, struct data, or a pointer to struct data
|
||||||
|
|
||||||
public bool OwnsMemory
|
public bool OwnsMemory
|
||||||
|
@ -13,7 +27,7 @@ namespace System
|
||||||
{
|
{
|
||||||
if (mStructType <= 2)
|
if (mStructType <= 2)
|
||||||
return mStructType == 1;
|
return mStructType == 1;
|
||||||
return VariantType.Size > sizeof(int);
|
return (mStructType & 1) != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +35,11 @@ namespace System
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return mStructType <= 2;
|
if (mStructType <= 2)
|
||||||
|
return true;
|
||||||
|
if ((mStructType & 3) == (int)StructFlag.ExternalPtr)
|
||||||
|
return VariantType.IsObject;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +55,7 @@ namespace System
|
||||||
{
|
{
|
||||||
return Internal.UnsafeCastToObject((void*)mData).GetType();
|
return Internal.UnsafeCastToObject((void*)mData).GetType();
|
||||||
}
|
}
|
||||||
return (Type)Internal.UnsafeCastToObject((void*)mStructType);
|
return (Type)Internal.UnsafeCastToObject((void*)(mStructType & ~3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +71,7 @@ namespace System
|
||||||
{
|
{
|
||||||
get mut
|
get mut
|
||||||
{
|
{
|
||||||
if (IsObject)
|
if (mStructType <= 3)
|
||||||
{
|
{
|
||||||
if (mStructType == 2)
|
if (mStructType == 2)
|
||||||
return null;
|
return null;
|
||||||
|
@ -61,8 +79,7 @@ namespace System
|
||||||
return (uint8*)Internal.UnsafeCastToPtr(obj) + obj.GetType().[Friend]mMemberDataOffset;
|
return (uint8*)Internal.UnsafeCastToPtr(obj) + obj.GetType().[Friend]mMemberDataOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
var type = VariantType;
|
if ((mStructType & 3) == (int)StructFlag.InternalValue)
|
||||||
if (type.Size <= sizeof(int))
|
|
||||||
return (void*)&mData;
|
return (void*)&mData;
|
||||||
else
|
else
|
||||||
return (void*)mData;
|
return (void*)mData;
|
||||||
|
@ -71,7 +88,7 @@ namespace System
|
||||||
|
|
||||||
protected override void GCMarkMembers()
|
protected override void GCMarkMembers()
|
||||||
{
|
{
|
||||||
if ((mStructType == 1) || (mStructType == 0))
|
if ((mStructType == (int)ObjectType.UnownedObject) || (mStructType == (int)ObjectType.OwnedObject))
|
||||||
{
|
{
|
||||||
var obj = Internal.UnsafeCastToObject((void*)mData);
|
var obj = Internal.UnsafeCastToObject((void*)mData);
|
||||||
GC.Mark(obj);
|
GC.Mark(obj);
|
||||||
|
@ -80,7 +97,7 @@ namespace System
|
||||||
|
|
||||||
public void Dispose() mut
|
public void Dispose() mut
|
||||||
{
|
{
|
||||||
if (mStructType == 1)
|
if (mStructType == (int)ObjectType.OwnedObject)
|
||||||
{
|
{
|
||||||
delete Internal.UnsafeCastToObject((void*)mData);
|
delete Internal.UnsafeCastToObject((void*)mData);
|
||||||
}
|
}
|
||||||
|
@ -97,12 +114,12 @@ namespace System
|
||||||
Variant variant;
|
Variant variant;
|
||||||
if (val == null)
|
if (val == null)
|
||||||
{
|
{
|
||||||
variant.mStructType = 2;
|
variant.mStructType = (int)ObjectType.NullObject;
|
||||||
variant.mData = (int)Internal.UnsafeCastToPtr(typeof(T));
|
variant.mData = (int)Internal.UnsafeCastToPtr(typeof(T));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
variant.mStructType = (int)(owns ? 1 : 0);
|
variant.mStructType = (int)(owns ? (int)ObjectType.OwnedObject : (int)ObjectType.UnownedObject);
|
||||||
variant.mData = (int)Internal.UnsafeCastToPtr(val);
|
variant.mData = (int)Internal.UnsafeCastToPtr(val);
|
||||||
}
|
}
|
||||||
return variant;
|
return variant;
|
||||||
|
@ -112,14 +129,15 @@ namespace System
|
||||||
{
|
{
|
||||||
Variant variant;
|
Variant variant;
|
||||||
Type type = typeof(T);
|
Type type = typeof(T);
|
||||||
variant.mStructType = (int)Internal.UnsafeCastToPtr(type);
|
|
||||||
if (sizeof(T) <= sizeof(int))
|
if (sizeof(T) <= sizeof(int))
|
||||||
{
|
{
|
||||||
|
variant.mStructType = (int)Internal.UnsafeCastToPtr(type);
|
||||||
variant.mData = 0;
|
variant.mData = 0;
|
||||||
*(T*)&variant.mData = val;
|
*(T*)&variant.mData = val;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
variant.mStructType = (int)Internal.UnsafeCastToPtr(type) | 1;
|
||||||
T* newVal = (T*)new uint8[sizeof(T)]*;
|
T* newVal = (T*)new uint8[sizeof(T)]*;
|
||||||
*newVal = val;
|
*newVal = val;
|
||||||
variant.mData = (int)(void*)newVal;
|
variant.mData = (int)(void*)newVal;
|
||||||
|
@ -131,14 +149,15 @@ namespace System
|
||||||
{
|
{
|
||||||
Variant variant;
|
Variant variant;
|
||||||
Type type = typeof(T);
|
Type type = typeof(T);
|
||||||
variant.mStructType = (int)Internal.UnsafeCastToPtr(type);
|
|
||||||
if (type.Size <= sizeof(int))
|
if (type.Size <= sizeof(int))
|
||||||
{
|
{
|
||||||
|
variant.mStructType = (int)Internal.UnsafeCastToPtr(type);
|
||||||
variant.mData = 0;
|
variant.mData = 0;
|
||||||
*(T*)&variant.mData = val;
|
*(T*)&variant.mData = val;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
variant.mStructType = (int)Internal.UnsafeCastToPtr(type) | 1;
|
||||||
T* newVal = (T*)new uint8[sizeof(T)]*;
|
T* newVal = (T*)new uint8[sizeof(T)]*;
|
||||||
*newVal = val;
|
*newVal = val;
|
||||||
variant.mData = (int)(void*)newVal;
|
variant.mData = (int)(void*)newVal;
|
||||||
|
@ -146,18 +165,53 @@ namespace System
|
||||||
return variant;
|
return variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Variant Create<T>(ref T val) where T : struct
|
||||||
|
{
|
||||||
|
Variant variant;
|
||||||
|
Type type = typeof(T);
|
||||||
|
variant.mStructType = (int)Internal.UnsafeCastToPtr(type) | 2;
|
||||||
|
variant.mData = 0;
|
||||||
|
variant.mData = (int)(void*)&val;
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Variant CreateOwned<T>(T val) where T : struct
|
||||||
|
{
|
||||||
|
Variant variant;
|
||||||
|
Type type = typeof(T);
|
||||||
|
variant.mStructType = (int)Internal.UnsafeCastToPtr(type) | 1;
|
||||||
|
T* newVal = (T*)new uint8[sizeof(T)]*;
|
||||||
|
*newVal = val;
|
||||||
|
variant.mData = (int)(void*)newVal;
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EnsureReference() mut
|
||||||
|
{
|
||||||
|
if ((mStructType <= 2) && (mStructType & 3 == (int)StructFlag.InternalValue))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var val = mData;
|
||||||
|
|
||||||
|
mStructType |= (int)StructFlag.OwnedPtr;
|
||||||
|
int* newVal = (int*)new uint8[sizeof(int)]*;
|
||||||
|
*newVal = val;
|
||||||
|
mData = (int)(void*)newVal;
|
||||||
|
}
|
||||||
|
|
||||||
public static Variant Create(Type type, void* val)
|
public static Variant Create(Type type, void* val)
|
||||||
{
|
{
|
||||||
Variant variant;
|
Variant variant;
|
||||||
Debug.Assert(!type.IsObject);
|
Debug.Assert(!type.IsObject);
|
||||||
variant.mStructType = (int)Internal.UnsafeCastToPtr(type);
|
|
||||||
if (type.Size <= sizeof(int))
|
if (type.Size <= sizeof(int))
|
||||||
{
|
{
|
||||||
|
variant.mStructType = (int)Internal.UnsafeCastToPtr(type);
|
||||||
variant.mData = 0;
|
variant.mData = 0;
|
||||||
Internal.MemCpy(&variant.mData, val, type.[Friend]mSize);
|
Internal.MemCpy(&variant.mData, val, type.[Friend]mSize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
variant.mStructType = (int)Internal.UnsafeCastToPtr(type) | 1;
|
||||||
void* data = new uint8[type.[Friend]mSize]*;
|
void* data = new uint8[type.[Friend]mSize]*;
|
||||||
Internal.MemCpy(data, val, type.[Friend]mSize);
|
Internal.MemCpy(data, val, type.[Friend]mSize);
|
||||||
variant.mData = (int)data;
|
variant.mData = (int)data;
|
||||||
|
@ -165,6 +219,14 @@ namespace System
|
||||||
return variant;
|
return variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Variant CreateReference(Type type, void* val)
|
||||||
|
{
|
||||||
|
Variant variant;
|
||||||
|
variant.mStructType = (int)Internal.UnsafeCastToPtr(type) | 2;
|
||||||
|
variant.mData = (int)val;
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
|
||||||
public static void* Alloc(Type type, out Variant variant)
|
public static void* Alloc(Type type, out Variant variant)
|
||||||
{
|
{
|
||||||
variant = .();
|
variant = .();
|
||||||
|
@ -175,14 +237,15 @@ namespace System
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
variant.mStructType = (int)Internal.UnsafeCastToPtr(type);
|
|
||||||
if (type.Size <= sizeof(int))
|
if (type.Size <= sizeof(int))
|
||||||
{
|
{
|
||||||
|
variant.mStructType = (int)Internal.UnsafeCastToPtr(type);
|
||||||
variant.mData = 0;
|
variant.mData = 0;
|
||||||
return &variant.mData;
|
return &variant.mData;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
variant.mStructType = (int)Internal.UnsafeCastToPtr(type) | 1;
|
||||||
void* data = new uint8[type.[Friend]mSize]*;
|
void* data = new uint8[type.[Friend]mSize]*;
|
||||||
variant.mData = (int)data;
|
variant.mData = (int)data;
|
||||||
return data;
|
return data;
|
||||||
|
@ -196,7 +259,11 @@ namespace System
|
||||||
if (mStructType == 2)
|
if (mStructType == 2)
|
||||||
return (T)null;
|
return (T)null;
|
||||||
Type type = typeof(T);
|
Type type = typeof(T);
|
||||||
T obj = (T)Internal.UnsafeCastToObject((void*)mData);
|
T obj;
|
||||||
|
if (mStructType >= 3)
|
||||||
|
obj = (T)Internal.UnsafeCastToObject(*(void**)(void*)mData);
|
||||||
|
else
|
||||||
|
obj = (T)Internal.UnsafeCastToObject((void*)mData);
|
||||||
Debug.Assert(obj.GetType().IsSubtypeOf(type));
|
Debug.Assert(obj.GetType().IsSubtypeOf(type));
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
@ -204,9 +271,9 @@ namespace System
|
||||||
public T Get<T>() where T : struct
|
public T Get<T>() where T : struct
|
||||||
{
|
{
|
||||||
Debug.Assert(!IsObject);
|
Debug.Assert(!IsObject);
|
||||||
var type = VariantType;
|
//var type = VariantType;
|
||||||
//Debug.Assert((typeof(T) == type) || (typeof(T) == type.GetUnderlyingType()));
|
//Debug.Assert((typeof(T) == type) || (typeof(T) == type.GetUnderlyingType()));
|
||||||
if (type.Size <= sizeof(int))
|
if ((mStructType & 3) == (int)StructFlag.InternalValue)
|
||||||
{
|
{
|
||||||
int data = mData;
|
int data = mData;
|
||||||
return *(T*)&data;
|
return *(T*)&data;
|
||||||
|
@ -218,9 +285,9 @@ namespace System
|
||||||
public T Get<T>() where T : struct*
|
public T Get<T>() where T : struct*
|
||||||
{
|
{
|
||||||
Debug.Assert(!IsObject);
|
Debug.Assert(!IsObject);
|
||||||
var type = VariantType;
|
//var type = VariantType;
|
||||||
//Debug.Assert((typeof(T) == type) || (typeof(T) == type.GetUnderlyingType()));
|
//Debug.Assert((typeof(T) == type) || (typeof(T) == type.GetUnderlyingType()));
|
||||||
if (type.Size <= sizeof(int))
|
if ((mStructType & 3) == (int)StructFlag.InternalValue)
|
||||||
{
|
{
|
||||||
int data = mData;
|
int data = mData;
|
||||||
return *(T*)&data;
|
return *(T*)&data;
|
||||||
|
@ -248,7 +315,7 @@ namespace System
|
||||||
}
|
}
|
||||||
|
|
||||||
var type = VariantType;
|
var type = VariantType;
|
||||||
if (type.Size <= sizeof(int))
|
if ((mStructType & 3) == (int)StructFlag.InternalValue)
|
||||||
{
|
{
|
||||||
int data = mData;
|
int data = mData;
|
||||||
Internal.MemCpy(dest, &data, type.Size);
|
Internal.MemCpy(dest, &data, type.Size);
|
||||||
|
@ -262,8 +329,7 @@ namespace System
|
||||||
public void* GetValueData() mut
|
public void* GetValueData() mut
|
||||||
{
|
{
|
||||||
Debug.Assert(!IsObject);
|
Debug.Assert(!IsObject);
|
||||||
var type = VariantType;
|
if ((mStructType & 3) == (int)StructFlag.InternalValue)
|
||||||
if (type.Size <= sizeof(int))
|
|
||||||
{
|
{
|
||||||
return (void*)&mData;
|
return (void*)&mData;
|
||||||
}
|
}
|
||||||
|
@ -284,18 +350,19 @@ namespace System
|
||||||
return v1.mData == v2.mData;
|
return v1.mData == v2.mData;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v1.mStructType != v2.mStructType)
|
if (v1.mStructType & 3 != v2.mStructType & 3)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
let type = v1.VariantType;
|
if ((v1.mStructType & 3 == 0) && (v2.mStructType & 3 == 0))
|
||||||
if (type.[Friend]mSize <= sizeof(int))
|
|
||||||
return v1.mData == v2.mData;
|
return v1.mData == v2.mData;
|
||||||
for (int i < type.[Friend]mSize)
|
|
||||||
{
|
var v1;
|
||||||
if (((uint8*)(void*)v1.mData)[i] != ((uint8*)(void*)v2.mData)[i])
|
var v2;
|
||||||
return false;
|
|
||||||
}
|
let type = v1.VariantType;
|
||||||
return true;
|
let ptr1 = v1.DataPtr;
|
||||||
|
let ptr2 = v2.DataPtr;
|
||||||
|
return Internal.MemCmp(ptr1, ptr2, type.[Friend]mSize) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static mixin Equals<T>(var v1, var v2)
|
public static mixin Equals<T>(var v1, var v2)
|
||||||
|
@ -303,16 +370,19 @@ namespace System
|
||||||
v1.Get<T>() == v2.Get<T>()
|
v1.Get<T>() == v2.Get<T>()
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result<Variant> CreateFromVariant(Variant varFrom)
|
public static Variant CreateFromVariant(Variant varFrom)
|
||||||
{
|
{
|
||||||
Variant varTo = varFrom;
|
Variant varTo = varFrom;
|
||||||
if (varTo.mStructType == 1)
|
if (varTo.mStructType == 1)
|
||||||
varTo.mStructType = 0;
|
varTo.mStructType = 0;
|
||||||
if (varTo.mStructType > 2)
|
if (varTo.mStructType > 2)
|
||||||
{
|
{
|
||||||
let type = (Type)Internal.UnsafeCastToObject((void*)varFrom.mStructType);
|
varTo.mStructType &= ~3;
|
||||||
|
|
||||||
|
let type = (Type)Internal.UnsafeCastToObject((void*)(varFrom.mStructType & ~3));
|
||||||
if (type.[Friend]mSize > sizeof(int))
|
if (type.[Friend]mSize > sizeof(int))
|
||||||
{
|
{
|
||||||
|
varTo.mStructType |= (int)StructFlag.OwnedPtr;
|
||||||
void* data = new uint8[type.[Friend]mSize]*;
|
void* data = new uint8[type.[Friend]mSize]*;
|
||||||
Internal.MemCpy(data, (void*)varFrom.mData, type.[Friend]mSize);
|
Internal.MemCpy(data, (void*)varFrom.mData, type.[Friend]mSize);
|
||||||
varTo.mData = (int)data;
|
varTo.mData = (int)data;
|
||||||
|
@ -322,6 +392,22 @@ namespace System
|
||||||
return varTo;
|
return varTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Variant CreateFromVariantRef(ref Variant varFrom)
|
||||||
|
{
|
||||||
|
Variant varTo = varFrom;
|
||||||
|
if (varTo.mStructType == 1)
|
||||||
|
varTo.mStructType = 0;
|
||||||
|
if (varTo.mStructType > 2)
|
||||||
|
{
|
||||||
|
varTo.mStructType &= ~3;
|
||||||
|
|
||||||
|
varTo.mStructType |= (int)StructFlag.ExternalPtr;
|
||||||
|
varTo.mData = (int)varFrom.DataPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return varTo;
|
||||||
|
}
|
||||||
|
|
||||||
public static Result<Variant> CreateFromBoxed(Object objectFrom)
|
public static Result<Variant> CreateFromBoxed(Object objectFrom)
|
||||||
{
|
{
|
||||||
if (objectFrom == null)
|
if (objectFrom == null)
|
||||||
|
@ -342,6 +428,7 @@ namespace System
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
variant.mStructType |= (int)StructFlag.OwnedPtr;
|
||||||
void* data = new uint8[underlying.[Friend]mSize]*;
|
void* data = new uint8[underlying.[Friend]mSize]*;
|
||||||
Internal.MemCpy(data, srcDataPtr, underlying.[Friend]mSize);
|
Internal.MemCpy(data, srcDataPtr, underlying.[Friend]mSize);
|
||||||
variant.mData = (int)data;
|
variant.mData = (int)data;
|
||||||
|
|
17
IDE/dist/BeefDbgVis.toml
vendored
17
IDE/dist/BeefDbgVis.toml
vendored
|
@ -105,10 +105,13 @@ String = "{{ OwnedObj: {(System.Object)mData} }}"
|
||||||
Condition = "mStructType == 2"
|
Condition = "mStructType == 2"
|
||||||
String = "{{ Null: {__cast((System.Type)mData, null)} }}"
|
String = "{{ Null: {__cast((System.Type)mData, null)} }}"
|
||||||
[[Type.DisplayString]]
|
[[Type.DisplayString]]
|
||||||
Condition = "((System.Type)mStructType).mSize <= sizeof(int)"
|
Condition = "mStructType & 3 == 0"
|
||||||
String = "{{ InlineValue: {__bitcast((System.Type)mStructType, mData)} }}"
|
String = "{{ InlineValue: {__bitcast((System.Type)(mStructType & ~3), mData)} }}"
|
||||||
[[Type.DisplayString]]
|
[[Type.DisplayString]]
|
||||||
String = "{{ AllocValue: {*__cast((System.Type)mStructType, \"*\", mData)} }}"
|
Condition = "mStructType & 3 == 1"
|
||||||
|
String = "{{ AllocValue: {*__cast((System.Type)(mStructType & ~3), \"*\", mData)} }}"
|
||||||
|
[[Type.DisplayString]]
|
||||||
|
String = "{{ RefValue: {*__cast((System.Type)(mStructType & ~3), \"*\", mData)} }}"
|
||||||
[[Type.Expand.Item]]
|
[[Type.Expand.Item]]
|
||||||
Condition = "mStructType == 0"
|
Condition = "mStructType == 0"
|
||||||
Name = "[UnownedObj]"
|
Name = "[UnownedObj]"
|
||||||
|
@ -122,13 +125,13 @@ Condition = "mStructType == 3"
|
||||||
Name = "[Null]"
|
Name = "[Null]"
|
||||||
Value = "__cast((System.Type)mData, null)"
|
Value = "__cast((System.Type)mData, null)"
|
||||||
[[Type.Expand.Item]]
|
[[Type.Expand.Item]]
|
||||||
Condition = "(mStructType != 0) && ((System.Type)mStructType).mSize <= sizeof(int)"
|
Condition = "(mStructType != 0) && (mStructType & 3 == 0)"
|
||||||
Name = "[InlineValue]"
|
Name = "[InlineValue]"
|
||||||
Value = "__bitcast((System.Type)mStructType, mData)"
|
Value = "__bitcast((System.Type)(mStructType & ~3), mData)"
|
||||||
[[Type.Expand.Item]]
|
[[Type.Expand.Item]]
|
||||||
Condition = "(mStructType != 0) && ((System.Type)mStructType).mSize > sizeof(int)"
|
Condition = "(mStructType != 0) && (mStructType & 3 != 0)"
|
||||||
Name = "[AllocValue]"
|
Name = "[AllocValue]"
|
||||||
Value = "*__cast((System.Type)mStructType, \"*\", mData)"
|
Value = "*__cast((System.Type)(mStructType & ~3), \"*\", mData)"
|
||||||
|
|
||||||
[[Type]]
|
[[Type]]
|
||||||
Name = "*?"
|
Name = "*?"
|
||||||
|
|
|
@ -1266,7 +1266,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
|
||||||
|
|
||||||
bool needsTypeList = bfModule->IsMethodImplementedAndReified(typeDefType, "GetType");
|
bool needsTypeList = bfModule->IsMethodImplementedAndReified(typeDefType, "GetType");
|
||||||
bool needsObjectTypeData = needsTypeList || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "RawGetType") || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "GetType");
|
bool needsObjectTypeData = needsTypeList || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "RawGetType") || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "GetType");
|
||||||
bool needsTypeNames = bfModule->IsMethodImplementedAndReified(typeDefType, "GetName");
|
bool needsTypeNames = bfModule->IsMethodImplementedAndReified(typeDefType, "GetName") || bfModule->IsMethodImplementedAndReified(typeDefType, "GetFullName");
|
||||||
bool needsStringLiteralList = (mOptions.mAllowHotSwapping) || (bfModule->IsMethodImplementedAndReified(stringType, "Intern"));
|
bool needsStringLiteralList = (mOptions.mAllowHotSwapping) || (bfModule->IsMethodImplementedAndReified(stringType, "Intern"));
|
||||||
|
|
||||||
Dictionary<int, int> usedStringIdMap;
|
Dictionary<int, int> usedStringIdMap;
|
||||||
|
|
|
@ -6312,6 +6312,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
{
|
{
|
||||||
typeDataVar = mBfIRBuilder->CreateGlobalVariable(typeInstanceDataType, true,
|
typeDataVar = mBfIRBuilder->CreateGlobalVariable(typeInstanceDataType, true,
|
||||||
BfIRLinkageType_External, typeInstanceData, typeDataName);
|
BfIRLinkageType_External, typeInstanceData, typeDataName);
|
||||||
|
mBfIRBuilder->GlobalVar_SetAlignment(typeDataVar, mSystem->mPtrSize);
|
||||||
|
|
||||||
if (mBfIRBuilder->DbgHasInfo())
|
if (mBfIRBuilder->DbgHasInfo())
|
||||||
{
|
{
|
||||||
|
|
|
@ -7190,12 +7190,12 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto castedType = mDbgModule->FindType(typeName, NULL, GetLanguage());
|
auto castedType = mDbgModule->FindType(typeName, NULL, GetLanguage(), true);
|
||||||
if (castedType == NULL)
|
if (castedType == NULL)
|
||||||
{
|
{
|
||||||
if (typeName.EndsWith('*'))
|
if (typeName.EndsWith('*'))
|
||||||
{
|
{
|
||||||
auto noPtrTypeEntry = mDbgModule->FindType(typeName.Substring(0, typeName.length() - 1), NULL, DbgLanguage_Beef);
|
auto noPtrTypeEntry = mDbgModule->FindType(typeName.Substring(0, typeName.length() - 1), NULL, DbgLanguage_Beef, true);
|
||||||
if (noPtrTypeEntry != NULL)
|
if (noPtrTypeEntry != NULL)
|
||||||
castedType = mDbgModule->GetPointerType(noPtrTypeEntry);
|
castedType = mDbgModule->GetPointerType(noPtrTypeEntry);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7382,7 +7382,7 @@ DbgType* DbgModule::FindTypeHelper(const String& typeName, DbgType* checkType)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgType* DbgModule::FindType(const String& typeName, DbgType* contextType, DbgLanguage language)
|
DbgType* DbgModule::FindType(const String& typeName, DbgType* contextType, DbgLanguage language, bool bfObjectPtr)
|
||||||
{
|
{
|
||||||
if ((language == DbgLanguage_Unknown) && (contextType != NULL))
|
if ((language == DbgLanguage_Unknown) && (contextType != NULL))
|
||||||
language = contextType->mLanguage;
|
language = contextType->mLanguage;
|
||||||
|
@ -7391,7 +7391,7 @@ DbgType* DbgModule::FindType(const String& typeName, DbgType* contextType, DbgLa
|
||||||
{
|
{
|
||||||
if (typeName[typeName.length() - 1] == '*')
|
if (typeName[typeName.length() - 1] == '*')
|
||||||
{
|
{
|
||||||
DbgType* dbgType = FindType(typeName.Substring(0, typeName.length() - 1), contextType, language);
|
DbgType* dbgType = FindType(typeName.Substring(0, typeName.length() - 1), contextType, language, bfObjectPtr);
|
||||||
if (dbgType == NULL)
|
if (dbgType == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return GetPointerType(dbgType);
|
return GetPointerType(dbgType);
|
||||||
|
@ -7400,7 +7400,11 @@ DbgType* DbgModule::FindType(const String& typeName, DbgType* contextType, DbgLa
|
||||||
|
|
||||||
auto entry = GetLinkedModule()->mTypeMap.Find(typeName.c_str(), language);
|
auto entry = GetLinkedModule()->mTypeMap.Find(typeName.c_str(), language);
|
||||||
if (entry != NULL)
|
if (entry != NULL)
|
||||||
|
{
|
||||||
|
if ((bfObjectPtr) && (entry->mValue->IsBfObject()))
|
||||||
|
return GetPointerType(entry->mValue);
|
||||||
return entry->mValue;
|
return entry->mValue;
|
||||||
|
}
|
||||||
|
|
||||||
if (contextType != NULL)
|
if (contextType != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1298,7 +1298,7 @@ public:
|
||||||
//const uint8* CopyOrigImageData(addr_target address, int length);
|
//const uint8* CopyOrigImageData(addr_target address, int length);
|
||||||
|
|
||||||
DbgType* FindTypeHelper(const String& typeName, DbgType* checkType);
|
DbgType* FindTypeHelper(const String& typeName, DbgType* checkType);
|
||||||
DbgType* FindType(const String& typeName, DbgType* contextType = NULL, DbgLanguage language = DbgLanguage_Unknown);
|
DbgType* FindType(const String& typeName, DbgType* contextType = NULL, DbgLanguage language = DbgLanguage_Unknown, bool bfObjectPtr = false);
|
||||||
DbgTypeMap::Entry* FindType(const char* typeName, DbgLanguage language);
|
DbgTypeMap::Entry* FindType(const char* typeName, DbgLanguage language);
|
||||||
|
|
||||||
DbgType* GetPointerType(DbgType* innerType);
|
DbgType* GetPointerType(DbgType* innerType);
|
||||||
|
|
|
@ -53,6 +53,9 @@ namespace Tests
|
||||||
[Reflect]
|
[Reflect]
|
||||||
class ClassA
|
class ClassA
|
||||||
{
|
{
|
||||||
|
int32 mA = 123;
|
||||||
|
String mStr = "A";
|
||||||
|
|
||||||
[AlwaysInclude, AttrC(71, 72)]
|
[AlwaysInclude, AttrC(71, 72)]
|
||||||
static float StaticMethodA(int32 a, int32 b, float c, ref int32 d, ref StructA sa)
|
static float StaticMethodA(int32 a, int32 b, float c, ref int32 d, ref StructA sa)
|
||||||
{
|
{
|
||||||
|
@ -62,6 +65,18 @@ namespace Tests
|
||||||
return a + b + c;
|
return a + b + c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AlwaysInclude]
|
||||||
|
static StructA StaticMethodB(ref int32 a, ref String b)
|
||||||
|
{
|
||||||
|
a += 1000;
|
||||||
|
b = "B";
|
||||||
|
|
||||||
|
StructA sa;
|
||||||
|
sa.mA = 12;
|
||||||
|
sa.mB = 34;
|
||||||
|
return sa;
|
||||||
|
}
|
||||||
|
|
||||||
[AlwaysInclude]
|
[AlwaysInclude]
|
||||||
float MemberMethodA(int32 a, int32 b, float c)
|
float MemberMethodA(int32 a, int32 b, float c)
|
||||||
{
|
{
|
||||||
|
@ -168,6 +183,21 @@ namespace Tests
|
||||||
Test.Assert(result.Get<float>() == 123);
|
Test.Assert(result.Get<float>() == 123);
|
||||||
result.Dispose();
|
result.Dispose();
|
||||||
|
|
||||||
|
Object aObj = a;
|
||||||
|
Object saObj = sa;
|
||||||
|
Test.Assert(methodInfo.Name == "StaticMethodA");
|
||||||
|
result = methodInfo.Invoke(null, 100, (int32)20, 3.0f, aObj, saObj).Get();
|
||||||
|
Test.Assert(a == 120);
|
||||||
|
Test.Assert(sa.mA == 101);
|
||||||
|
Test.Assert(sa.mB == 22);
|
||||||
|
int32 a2 = (int32)aObj;
|
||||||
|
StructA sa2 = (StructA)saObj;
|
||||||
|
Test.Assert(a2 == 240);
|
||||||
|
Test.Assert(sa2.mA == 201);
|
||||||
|
Test.Assert(sa2.mB == 42);
|
||||||
|
Test.Assert(result.Get<float>() == 123);
|
||||||
|
result.Dispose();
|
||||||
|
|
||||||
result = methodInfo.Invoke(.(), .Create(100), .Create((int32)20), .Create(3.0f), .Create(&a), .Create(&sa)).Get();
|
result = methodInfo.Invoke(.(), .Create(100), .Create((int32)20), .Create(3.0f), .Create(&a), .Create(&sa)).Get();
|
||||||
Test.Assert(a == 240);
|
Test.Assert(a == 240);
|
||||||
Test.Assert(sa.mA == 201);
|
Test.Assert(sa.mA == 201);
|
||||||
|
@ -175,10 +205,55 @@ namespace Tests
|
||||||
Test.Assert(result.Get<float>() == 123);
|
Test.Assert(result.Get<float>() == 123);
|
||||||
result.Dispose();
|
result.Dispose();
|
||||||
|
|
||||||
|
Variant aV = .CreateOwned(a);
|
||||||
|
Variant saV = .CreateOwned(sa);
|
||||||
|
result = methodInfo.Invoke(.(), .Create(100), .Create((int32)20), .Create(3.0f), aV, saV).Get();
|
||||||
|
Test.Assert(a == 240);
|
||||||
|
Test.Assert(sa.mA == 201);
|
||||||
|
Test.Assert(sa.mB == 42);
|
||||||
|
a2 = aV.Get<int32>();
|
||||||
|
sa2 = saV.Get<StructA>();
|
||||||
|
Test.Assert(a2 == 360);
|
||||||
|
Test.Assert(sa2.mA == 301);
|
||||||
|
Test.Assert(sa2.mB == 62);
|
||||||
|
Test.Assert(result.Get<float>() == 123);
|
||||||
|
aV.Dispose();
|
||||||
|
saV.Dispose();
|
||||||
|
result.Dispose();
|
||||||
|
|
||||||
let attrC = methodInfo.GetCustomAttribute<AttrCAttribute>().Get();
|
let attrC = methodInfo.GetCustomAttribute<AttrCAttribute>().Get();
|
||||||
Test.Assert(attrC.mA == 71);
|
Test.Assert(attrC.mA == 71);
|
||||||
Test.Assert(attrC.mB == 72);
|
Test.Assert(attrC.mB == 72);
|
||||||
case 1:
|
case 1:
|
||||||
|
Test.Assert(methodInfo.Name == "StaticMethodB");
|
||||||
|
|
||||||
|
var fieldA = typeInfo.GetField("mA").Value;
|
||||||
|
var fieldStr = typeInfo.GetField("mStr").Value;
|
||||||
|
|
||||||
|
var fieldAV = fieldA.GetValueReference(ca).Value;
|
||||||
|
var fieldStrV = fieldStr.GetValueReference(ca).Value;
|
||||||
|
|
||||||
|
Test.Assert(fieldAV.Get<int32>() == 123);
|
||||||
|
Test.Assert(fieldStrV.Get<String>() == "A");
|
||||||
|
|
||||||
|
var res = methodInfo.Invoke(.(), fieldAV, fieldStrV).Value;
|
||||||
|
var sa = res.Get<StructA>();
|
||||||
|
Test.Assert(sa.mA == 12);
|
||||||
|
Test.Assert(sa.mB == 34);
|
||||||
|
res.Dispose();
|
||||||
|
|
||||||
|
Test.Assert(fieldAV.Get<int32>() == 1123);
|
||||||
|
Test.Assert(fieldStrV.Get<String>() == "B");
|
||||||
|
fieldAV.Dispose();
|
||||||
|
fieldStrV.Dispose();
|
||||||
|
|
||||||
|
fieldAV = fieldA.GetValue(ca).Value;
|
||||||
|
fieldStrV = fieldStr.GetValue(ca).Value;
|
||||||
|
Test.Assert(fieldAV.Get<int32>() == 1123);
|
||||||
|
Test.Assert(fieldStrV.Get<String>() == "B");
|
||||||
|
fieldAV.Dispose();
|
||||||
|
fieldStrV.Dispose();
|
||||||
|
case 2:
|
||||||
Test.Assert(methodInfo.Name == "MemberMethodA");
|
Test.Assert(methodInfo.Name == "MemberMethodA");
|
||||||
var result = methodInfo.Invoke(ca, 100, (int32)20, 3.0f).Get();
|
var result = methodInfo.Invoke(ca, 100, (int32)20, 3.0f).Get();
|
||||||
Test.Assert(result.Get<float>() == 123);
|
Test.Assert(result.Get<float>() == 123);
|
||||||
|
@ -187,7 +262,7 @@ namespace Tests
|
||||||
result = methodInfo.Invoke(.Create(ca), .Create(100), .Create((int32)20), .Create(3.0f)).Get();
|
result = methodInfo.Invoke(.Create(ca), .Create(100), .Create((int32)20), .Create(3.0f)).Get();
|
||||||
Test.Assert(result.Get<float>() == 123);
|
Test.Assert(result.Get<float>() == 123);
|
||||||
result.Dispose();
|
result.Dispose();
|
||||||
case 2:
|
case 3:
|
||||||
Test.Assert(methodInfo.Name == "GetA");
|
Test.Assert(methodInfo.Name == "GetA");
|
||||||
var result = methodInfo.Invoke(ca, 123).Get();
|
var result = methodInfo.Invoke(ca, 123).Get();
|
||||||
Test.Assert(result.Get<int>() == 1123);
|
Test.Assert(result.Get<int>() == 1123);
|
||||||
|
@ -198,10 +273,10 @@ namespace Tests
|
||||||
result = methodInfo.Invoke(.Create(ca2), .Create(123)).Get();
|
result = methodInfo.Invoke(.Create(ca2), .Create(123)).Get();
|
||||||
Test.Assert(result.Get<int>() == 2123);
|
Test.Assert(result.Get<int>() == 2123);
|
||||||
result.Dispose();
|
result.Dispose();
|
||||||
case 3:
|
case 4:
|
||||||
Test.Assert(methodInfo.Name == "__BfCtor");
|
Test.Assert(methodInfo.Name == "__BfCtor");
|
||||||
Test.Assert(methodInfo.IsConstructor);
|
Test.Assert(methodInfo.IsConstructor);
|
||||||
case 4:
|
case 5:
|
||||||
Test.FatalError(); // Shouldn't have any more
|
Test.FatalError(); // Shouldn't have any more
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue