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.
209 lines
7.7 KiB
209 lines
7.7 KiB
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 |
|
} |
|
}
|
|
|