You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
7.7 KiB
210 lines
7.7 KiB
3 years ago
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
using System.Text;
|
||
|
|
||
|
using ILRuntime.CLR.TypeSystem;
|
||
|
using ILRuntime.Runtime.Enviorment;
|
||
|
using ILRuntime.Runtime.Intepreter;
|
||
|
namespace ILRuntime.Runtime.Stack
|
||
|
{
|
||
|
#pragma warning disable CS0660
|
||
|
#pragma warning disable CS0661
|
||
|
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
|
||
|
public struct StackObject
|
||
|
{
|
||
|
public static StackObject Null = new StackObject() { ObjectType = ObjectTypes.Null, Value = -1, ValueLow = 0 };
|
||
|
public ObjectTypes ObjectType;
|
||
|
public int Value;
|
||
|
public int ValueLow;
|
||
|
|
||
|
public static bool operator ==(StackObject a, StackObject b)
|
||
|
{
|
||
|
return (a.ObjectType == b.ObjectType) && (a.Value == b.Value) && (a.ValueLow == b.ValueLow);
|
||
|
}
|
||
|
|
||
|
public static bool operator !=(StackObject a, StackObject b)
|
||
|
{
|
||
|
return (a.ObjectType != b.ObjectType) || (a.Value != b.Value) || (a.ValueLow == b.ValueLow);
|
||
|
}
|
||
|
|
||
|
//IL2CPP can't process esp->ToObject() properly, so I can only use static function for this
|
||
|
public static unsafe object ToObject(StackObject* esp, ILRuntime.Runtime.Enviorment.AppDomain appdomain, IList<object> mStack)
|
||
|
{
|
||
|
switch (esp->ObjectType)
|
||
|
{
|
||
|
case ObjectTypes.Integer:
|
||
|
return esp->Value;
|
||
|
case ObjectTypes.Long:
|
||
|
{
|
||
|
return *(long*)&esp->Value;
|
||
|
}
|
||
|
case ObjectTypes.Float:
|
||
|
{
|
||
|
return *(float*)&esp->Value;
|
||
|
}
|
||
|
case ObjectTypes.Double:
|
||
|
{
|
||
|
return *(double*)&esp->Value;
|
||
|
}
|
||
|
case ObjectTypes.Object:
|
||
|
return mStack[esp->Value];
|
||
|
case ObjectTypes.FieldReference:
|
||
|
{
|
||
|
ILTypeInstance instance = mStack[esp->Value] as ILTypeInstance;
|
||
|
if (instance != null)
|
||
|
{
|
||
|
return instance[esp->ValueLow];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
var obj = mStack[esp->Value];
|
||
|
IType t = null;
|
||
|
if (obj is CrossBindingAdaptorType)
|
||
|
{
|
||
|
t = appdomain.GetType(((CrossBindingAdaptor)((CrossBindingAdaptorType)obj).ILInstance.Type.FirstCLRBaseType).BaseCLRType);
|
||
|
}
|
||
|
else
|
||
|
t = appdomain.GetType(obj.GetType());
|
||
|
|
||
|
return ((CLRType)t).GetFieldValue(esp->ValueLow, obj);
|
||
|
}
|
||
|
}
|
||
|
case ObjectTypes.ArrayReference:
|
||
|
{
|
||
|
Array instance = mStack[esp->Value] as Array;
|
||
|
return instance.GetValue(esp->ValueLow);
|
||
|
}
|
||
|
case ObjectTypes.StaticFieldReference:
|
||
|
{
|
||
|
var t = appdomain.GetType(esp->Value);
|
||
|
if (t is CLR.TypeSystem.ILType)
|
||
|
{
|
||
|
CLR.TypeSystem.ILType type = (CLR.TypeSystem.ILType)t;
|
||
|
return type.StaticInstance[esp->ValueLow];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CLR.TypeSystem.CLRType type = (CLR.TypeSystem.CLRType)t;
|
||
|
return type.GetFieldValue(esp->ValueLow, null);
|
||
|
}
|
||
|
}
|
||
|
case ObjectTypes.StackObjectReference:
|
||
|
{
|
||
|
return ToObject((ILIntepreter.ResolveReference(esp)), appdomain, mStack);
|
||
|
}
|
||
|
case ObjectTypes.ValueTypeObjectReference:
|
||
|
{
|
||
|
StackObject* dst = ILIntepreter.ResolveReference(esp);
|
||
|
IType type = appdomain.GetTypeByIndex(dst->Value);
|
||
|
if (type is ILType)
|
||
|
{
|
||
|
ILType iltype = (ILType)type;
|
||
|
var ins = iltype.Instantiate(false);
|
||
|
for (int i = 0; i < dst->ValueLow; i++)
|
||
|
{
|
||
|
var addr = ILIntepreter.Minus(dst, i + 1);
|
||
|
ins.AssignFromStack(i, addr, appdomain, mStack);
|
||
|
}
|
||
|
return ins;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return ((CLRType)type).ValueTypeBinder.ToObject(dst, mStack);
|
||
|
}
|
||
|
}
|
||
|
case ObjectTypes.Null:
|
||
|
return null;
|
||
|
default:
|
||
|
throw new NotImplementedException();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public unsafe static void Initialized(ref StackObject esp, int idx, IType fieldType, IList<object> mStack)
|
||
|
{
|
||
|
if (fieldType.IsPrimitive)
|
||
|
{
|
||
|
esp = fieldType.DefaultObject;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (fieldType.IsValueType)
|
||
|
{
|
||
|
esp.ObjectType = ObjectTypes.Object;
|
||
|
esp.Value = idx;
|
||
|
if (fieldType is CLRType)
|
||
|
{
|
||
|
if (fieldType.TypeForCLR.IsEnum)
|
||
|
{
|
||
|
esp.ObjectType = ObjectTypes.Integer;
|
||
|
esp.Value = 0;
|
||
|
esp.ValueLow = 0;
|
||
|
mStack[idx] = null;
|
||
|
}
|
||
|
else
|
||
|
mStack[idx] = ((CLRType)fieldType).CreateDefaultInstance();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (((ILType)fieldType).IsEnum)
|
||
|
{
|
||
|
esp.ObjectType = ObjectTypes.Integer;
|
||
|
esp.Value = 0;
|
||
|
esp.ValueLow = 0;
|
||
|
mStack[idx] = null;
|
||
|
}
|
||
|
else
|
||
|
mStack[idx] = ((ILType)fieldType).Instantiate();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
esp = Null;
|
||
|
mStack[idx] = null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//IL2CPP can't process esp->Initialized() properly, so I can only use static function for this
|
||
|
public unsafe static void Initialized(StackObject* esp, IType type)
|
||
|
{
|
||
|
if (type.IsPrimitive)
|
||
|
{
|
||
|
*esp = type.DefaultObject;
|
||
|
}
|
||
|
else if (type.IsEnum)
|
||
|
{
|
||
|
ILType ilType = type as ILType;
|
||
|
if (ilType != null)
|
||
|
{
|
||
|
Initialized(esp, ilType.FieldTypes[0]);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Initialized(esp, ((CLRType)type).OrderedFieldTypes[0]);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*esp = Null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public enum ObjectTypes
|
||
|
{
|
||
|
Null,
|
||
|
Integer,
|
||
|
Long,
|
||
|
Float,
|
||
|
Double,
|
||
|
StackObjectReference,//Value = pointer,
|
||
|
StaticFieldReference,
|
||
|
ValueTypeObjectReference,
|
||
|
ValueTypeDescriptor,
|
||
|
Object,
|
||
|
FieldReference,//Value = objIdx, ValueLow = fieldIdx
|
||
|
ArrayReference,//Value = objIdx, ValueLow = elemIdx
|
||
|
}
|
||
|
}
|