123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- 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
- }
- }
|