mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 12:30:32 +00:00
1044 lines
33 KiB
C#
1044 lines
33 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
|
|
using SysReflection = System.Reflection;
|
|
|
|
namespace Cosmos.IL2CPU.ILOpCodes
|
|
{
|
|
public class OpNone : ILOpCode
|
|
{
|
|
|
|
public OpNone(Code aOpCode, int aPos, int aNextPos, ExceptionHandlingClause aCurrentExceptionHandler)
|
|
: base(aOpCode, aPos, aNextPos, aCurrentExceptionHandler)
|
|
{
|
|
}
|
|
|
|
public override int GetNumberOfStackPops(MethodBase aMethod)
|
|
{
|
|
switch (OpCode)
|
|
{
|
|
case Code.Pop:
|
|
return 1;
|
|
case Code.Nop:
|
|
return 0;
|
|
case Code.Ret:
|
|
var methodInfo = aMethod as SysReflection.MethodInfo;
|
|
if (methodInfo != null && methodInfo.ReturnType != typeof(void))
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
case Code.Conv_I:
|
|
case Code.Conv_I1:
|
|
case Code.Conv_I2:
|
|
case Code.Conv_I4:
|
|
case Code.Conv_I8:
|
|
case Code.Conv_U:
|
|
case Code.Conv_U1:
|
|
case Code.Conv_U2:
|
|
case Code.Conv_U4:
|
|
case Code.Conv_U8:
|
|
case Code.Conv_R4:
|
|
case Code.Conv_R8:
|
|
case Code.Conv_R_Un:
|
|
case Code.Conv_Ovf_I:
|
|
case Code.Conv_Ovf_I1:
|
|
case Code.Conv_Ovf_I1_Un:
|
|
case Code.Conv_Ovf_I2:
|
|
case Code.Conv_Ovf_I2_Un:
|
|
case Code.Conv_Ovf_I4:
|
|
case Code.Conv_Ovf_I4_Un:
|
|
case Code.Conv_Ovf_I8:
|
|
case Code.Conv_Ovf_I8_Un:
|
|
case Code.Conv_Ovf_I_Un:
|
|
case Code.Conv_Ovf_U:
|
|
case Code.Conv_Ovf_U1:
|
|
case Code.Conv_Ovf_U1_Un:
|
|
case Code.Conv_Ovf_U2:
|
|
case Code.Conv_Ovf_U2_Un:
|
|
case Code.Conv_Ovf_U4:
|
|
case Code.Conv_Ovf_U4_Un:
|
|
case Code.Conv_Ovf_U8:
|
|
case Code.Conv_Ovf_U8_Un:
|
|
case Code.Conv_Ovf_U_Un:
|
|
return 1;
|
|
case Code.Add:
|
|
case Code.Add_Ovf:
|
|
case Code.Mul:
|
|
case Code.Mul_Ovf:
|
|
case Code.Mul_Ovf_Un:
|
|
case Code.Div:
|
|
case Code.Div_Un:
|
|
case Code.Sub:
|
|
case Code.Rem:
|
|
case Code.Rem_Un:
|
|
case Code.And:
|
|
case Code.Or:
|
|
case Code.Xor:
|
|
return 2;
|
|
case Code.Not:
|
|
return 1;
|
|
case Code.Ldind_I:
|
|
case Code.Ldind_I1:
|
|
case Code.Ldind_I2:
|
|
case Code.Ldind_I4:
|
|
case Code.Ldind_I8:
|
|
case Code.Ldind_U1:
|
|
case Code.Ldind_U2:
|
|
case Code.Ldind_U4:
|
|
case Code.Ldind_R4:
|
|
case Code.Ldind_R8:
|
|
case Code.Ldind_Ref:
|
|
return 1;
|
|
case Code.Stind_I:
|
|
case Code.Stind_I1:
|
|
case Code.Stind_I2:
|
|
case Code.Stind_I4:
|
|
case Code.Stind_I8:
|
|
case Code.Stind_Ref:
|
|
return 2;
|
|
case Code.Clt:
|
|
return 2;
|
|
case Code.Clt_Un:
|
|
return 2;
|
|
case Code.Cgt:
|
|
return 2;
|
|
case Code.Cgt_Un:
|
|
return 2;
|
|
case Code.Ceq:
|
|
return 2;
|
|
case Code.Throw:
|
|
return 1;
|
|
case Code.Rethrow:
|
|
return 0;
|
|
case Code.Stelem_Ref:
|
|
case Code.Stelem_I:
|
|
case Code.Stelem_I1:
|
|
case Code.Stelem_I2:
|
|
case Code.Stelem_I4:
|
|
case Code.Stelem_I8:
|
|
return 3;
|
|
case Code.Shr:
|
|
case Code.Shr_Un:
|
|
case Code.Shl:
|
|
return 2;
|
|
case Code.Neg:
|
|
return 1;
|
|
case Code.Localloc:
|
|
return 1;
|
|
case Code.Ldlen:
|
|
return 1;
|
|
case Code.Ldelem:
|
|
case Code.Ldelem_Ref:
|
|
case Code.Ldelem_I:
|
|
case Code.Ldelem_I1:
|
|
case Code.Ldelem_I2:
|
|
case Code.Ldelem_I4:
|
|
case Code.Ldelem_I8:
|
|
case Code.Ldelem_U1:
|
|
case Code.Ldelem_U2:
|
|
case Code.Ldelem_U4:
|
|
return 2;
|
|
case Code.Ldnull:
|
|
return 0;
|
|
case Code.Dup:
|
|
return 1;
|
|
case Code.Volatile:
|
|
return 0;
|
|
case Code.Endfilter:
|
|
case Code.Endfinally:
|
|
return 0;
|
|
default:
|
|
throw new NotImplementedException("OpCode '" + OpCode + "' not implemented!");
|
|
}
|
|
}
|
|
|
|
public override int GetNumberOfStackPushes(MethodBase aMethod)
|
|
{
|
|
switch (OpCode)
|
|
{
|
|
case Code.Pop:
|
|
return 0;
|
|
case Code.Ret:
|
|
return 0;
|
|
case Code.Nop:
|
|
return 0;
|
|
case Code.Conv_I:
|
|
case Code.Conv_I1:
|
|
case Code.Conv_I2:
|
|
case Code.Conv_I4:
|
|
case Code.Conv_I8:
|
|
case Code.Conv_U:
|
|
case Code.Conv_U1:
|
|
case Code.Conv_U2:
|
|
case Code.Conv_U4:
|
|
case Code.Conv_U8:
|
|
case Code.Conv_R4:
|
|
case Code.Conv_R8:
|
|
case Code.Conv_R_Un:
|
|
case Code.Conv_Ovf_I:
|
|
case Code.Conv_Ovf_I1:
|
|
case Code.Conv_Ovf_I1_Un:
|
|
case Code.Conv_Ovf_I2:
|
|
case Code.Conv_Ovf_I2_Un:
|
|
case Code.Conv_Ovf_I4:
|
|
case Code.Conv_Ovf_I4_Un:
|
|
case Code.Conv_Ovf_I8:
|
|
case Code.Conv_Ovf_I8_Un:
|
|
case Code.Conv_Ovf_I_Un:
|
|
case Code.Conv_Ovf_U:
|
|
case Code.Conv_Ovf_U1:
|
|
case Code.Conv_Ovf_U1_Un:
|
|
case Code.Conv_Ovf_U2:
|
|
case Code.Conv_Ovf_U2_Un:
|
|
case Code.Conv_Ovf_U4:
|
|
case Code.Conv_Ovf_U4_Un:
|
|
case Code.Conv_Ovf_U8:
|
|
case Code.Conv_Ovf_U8_Un:
|
|
case Code.Conv_Ovf_U_Un:
|
|
return 1;
|
|
case Code.Add:
|
|
case Code.Add_Ovf:
|
|
case Code.Mul:
|
|
case Code.Mul_Ovf:
|
|
case Code.Mul_Ovf_Un:
|
|
case Code.Div:
|
|
case Code.Div_Un:
|
|
case Code.Sub:
|
|
case Code.Rem:
|
|
case Code.Rem_Un:
|
|
case Code.And:
|
|
case Code.Not:
|
|
case Code.Or:
|
|
case Code.Xor:
|
|
return 1;
|
|
case Code.Ldind_I:
|
|
case Code.Ldind_I1:
|
|
case Code.Ldind_I2:
|
|
case Code.Ldind_I4:
|
|
case Code.Ldind_I8:
|
|
case Code.Ldind_U1:
|
|
case Code.Ldind_U2:
|
|
case Code.Ldind_U4:
|
|
case Code.Ldind_R4:
|
|
case Code.Ldind_R8:
|
|
case Code.Ldind_Ref:
|
|
return 1;
|
|
case Code.Stind_I:
|
|
case Code.Stind_I1:
|
|
case Code.Stind_I2:
|
|
case Code.Stind_I4:
|
|
case Code.Stind_I8:
|
|
case Code.Stind_Ref:
|
|
return 0;
|
|
case Code.Clt:
|
|
return 1;
|
|
case Code.Clt_Un:
|
|
return 1;
|
|
case Code.Cgt:
|
|
return 1;
|
|
case Code.Cgt_Un:
|
|
return 1;
|
|
case Code.Ceq:
|
|
return 1;
|
|
case Code.Throw:
|
|
case Code.Rethrow:
|
|
return 0;
|
|
case Code.Stelem_I:
|
|
case Code.Stelem_I1:
|
|
case Code.Stelem_I2:
|
|
case Code.Stelem_I4:
|
|
case Code.Stelem_I8:
|
|
case Code.Stelem_Ref:
|
|
return 0;
|
|
case Code.Shr:
|
|
case Code.Shr_Un:
|
|
case Code.Shl:
|
|
return 1;
|
|
case Code.Neg:
|
|
return 1;
|
|
case Code.Localloc:
|
|
return 1;
|
|
case Code.Ldlen:
|
|
return 1;
|
|
case Code.Ldelem:
|
|
case Code.Ldelem_Ref:
|
|
case Code.Ldelem_I:
|
|
case Code.Ldelem_I1:
|
|
case Code.Ldelem_I2:
|
|
case Code.Ldelem_I4:
|
|
case Code.Ldelem_I8:
|
|
case Code.Ldelem_U1:
|
|
case Code.Ldelem_U2:
|
|
case Code.Ldelem_U4:
|
|
return 1;
|
|
case Code.Ldnull:
|
|
return 1;
|
|
case Code.Dup:
|
|
return 2;
|
|
case Code.Volatile:
|
|
return 0;
|
|
case Code.Endfilter:
|
|
case Code.Endfinally:
|
|
return 0;
|
|
default:
|
|
throw new NotImplementedException("OpCode '" + OpCode + "' not implemented!");
|
|
}
|
|
}
|
|
|
|
protected override void DoInitStackAnalysis(MethodBase aMethod)
|
|
{
|
|
base.DoInitStackAnalysis(aMethod);
|
|
|
|
switch (OpCode)
|
|
{
|
|
case Code.Ldind_U1:
|
|
StackPushTypes[0] = typeof(byte);
|
|
return;
|
|
|
|
case Code.Ldind_U2:
|
|
StackPushTypes[0] = typeof(ushort);
|
|
return;
|
|
|
|
case Code.Ldind_U4:
|
|
StackPushTypes[0] = typeof(UInt32);
|
|
return;
|
|
|
|
case Code.Ldind_R4:
|
|
StackPushTypes[0] = typeof(Single);
|
|
return;
|
|
|
|
case Code.Ldind_R8:
|
|
StackPushTypes[0] = typeof(Double);
|
|
return;
|
|
|
|
case Code.Conv_I:
|
|
StackPushTypes[0] = typeof(IntPtr);
|
|
break;
|
|
|
|
case Code.Conv_I1:
|
|
StackPushTypes[0] = typeof(sbyte);
|
|
break;
|
|
|
|
case Code.Conv_I2:
|
|
StackPushTypes[0] = typeof(short);
|
|
break;
|
|
|
|
case Code.Conv_I4:
|
|
StackPushTypes[0] = typeof(int);
|
|
break;
|
|
|
|
case Code.Conv_I8:
|
|
StackPushTypes[0] = typeof(long);
|
|
break;
|
|
|
|
case Code.Conv_U:
|
|
StackPushTypes[0] = typeof(UIntPtr);
|
|
break;
|
|
|
|
case Code.Conv_U1:
|
|
StackPushTypes[0] = typeof(byte);
|
|
break;
|
|
|
|
case Code.Conv_U2:
|
|
StackPushTypes[0] = typeof(ushort);
|
|
break;
|
|
|
|
case Code.Conv_U4:
|
|
StackPushTypes[0] = typeof(uint);
|
|
break;
|
|
|
|
case Code.Conv_U8:
|
|
StackPushTypes[0] = typeof(ulong);
|
|
break;
|
|
|
|
case Code.Conv_R4:
|
|
StackPushTypes[0] = typeof(Single);
|
|
break;
|
|
|
|
case Code.Conv_R8:
|
|
StackPushTypes[0] = typeof(Double);
|
|
break;
|
|
case Code.Conv_Ovf_I:
|
|
StackPushTypes[0] = typeof(IntPtr);
|
|
break;
|
|
case Code.Conv_Ovf_I1:
|
|
StackPushTypes[0] = typeof(sbyte);
|
|
break;
|
|
case Code.Conv_Ovf_I1_Un:
|
|
StackPushTypes[0] = typeof(sbyte);
|
|
break;
|
|
case Code.Conv_Ovf_I2:
|
|
StackPushTypes[0] = typeof(short);
|
|
break;
|
|
case Code.Conv_Ovf_I2_Un:
|
|
StackPushTypes[0] = typeof(short);
|
|
break;
|
|
case Code.Conv_Ovf_I4:
|
|
StackPushTypes[0] = typeof(int);
|
|
break;
|
|
case Code.Conv_Ovf_I4_Un:
|
|
StackPushTypes[0] = typeof(int);
|
|
break;
|
|
case Code.Conv_Ovf_I8:
|
|
StackPushTypes[0] = typeof(long);
|
|
break;
|
|
case Code.Conv_Ovf_I8_Un:
|
|
StackPushTypes[0] = typeof(long);
|
|
break;
|
|
case Code.Conv_Ovf_I_Un:
|
|
StackPushTypes[0] = typeof(IntPtr);
|
|
break;
|
|
case Code.Conv_Ovf_U:
|
|
StackPushTypes[0] = typeof(UIntPtr);
|
|
break;
|
|
case Code.Conv_Ovf_U1:
|
|
StackPushTypes[0] = typeof(byte);
|
|
break;
|
|
case Code.Conv_Ovf_U1_Un:
|
|
StackPushTypes[0] = typeof(byte);
|
|
break;
|
|
case Code.Conv_Ovf_U2:
|
|
StackPushTypes[0] = typeof(ushort);
|
|
break;
|
|
case Code.Conv_Ovf_U2_Un:
|
|
StackPushTypes[0] = typeof(ushort);
|
|
break;
|
|
case Code.Conv_Ovf_U4:
|
|
StackPushTypes[0] = typeof(uint);
|
|
break;
|
|
case Code.Conv_Ovf_U4_Un:
|
|
StackPushTypes[0] = typeof(uint);
|
|
break;
|
|
case Code.Conv_Ovf_U8:
|
|
StackPushTypes[0] = typeof(ulong);
|
|
break;
|
|
case Code.Conv_Ovf_U8_Un:
|
|
StackPushTypes[0] = typeof(ulong);
|
|
break;
|
|
case Code.Conv_Ovf_U_Un:
|
|
StackPushTypes[0] = typeof(UIntPtr);
|
|
break;
|
|
|
|
case Code.Clt:
|
|
StackPushTypes[0] = typeof(int);
|
|
return;
|
|
case Code.Clt_Un:
|
|
StackPushTypes[0] = typeof(int);
|
|
return;
|
|
case Code.Cgt:
|
|
StackPushTypes[0] = typeof(int);
|
|
return;
|
|
case Code.Cgt_Un:
|
|
StackPushTypes[0] = typeof(int);
|
|
return;
|
|
case Code.Ceq:
|
|
StackPushTypes[0] = typeof(int);
|
|
return;
|
|
case Code.Throw:
|
|
StackPopTypes[0] = typeof(object);
|
|
return;
|
|
case Code.Ldlen:
|
|
StackPushTypes[0] = typeof(UIntPtr);
|
|
return;
|
|
|
|
case Code.Ldelem_I:
|
|
StackPushTypes[0] = typeof(IntPtr);
|
|
return;
|
|
case Code.Ldelem_I1:
|
|
StackPushTypes[0] = typeof(sbyte);
|
|
return;
|
|
case Code.Ldelem_I2:
|
|
StackPushTypes[0] = typeof(short);
|
|
return;
|
|
case Code.Ldelem_I4:
|
|
StackPushTypes[0] = typeof(int);
|
|
return;
|
|
case Code.Ldelem_I8:
|
|
StackPushTypes[0] = typeof(long);
|
|
return;
|
|
case Code.Ldelem_U1:
|
|
StackPushTypes[0] = typeof(byte);
|
|
return;
|
|
case Code.Ldelem_U2:
|
|
StackPushTypes[0] = typeof(ushort);
|
|
return;
|
|
case Code.Ldelem_U4:
|
|
StackPushTypes[0] = typeof(uint);
|
|
return;
|
|
case Code.Ldnull:
|
|
StackPushTypes[0] = typeof(NullRef);
|
|
return;
|
|
|
|
case Code.Ldind_I:
|
|
StackPushTypes[0] = typeof(IntPtr);
|
|
return;
|
|
|
|
case Code.Ldind_I1:
|
|
StackPushTypes[0] = typeof(sbyte);
|
|
return;
|
|
|
|
case Code.Ldind_I2:
|
|
StackPushTypes[0] = typeof(short);
|
|
return;
|
|
|
|
case Code.Ldind_I4:
|
|
StackPushTypes[0] = typeof(Int32);
|
|
return;
|
|
|
|
case Code.Ldind_I8:
|
|
StackPushTypes[0] = typeof(long);
|
|
return;
|
|
|
|
case Code.Stelem_I4:
|
|
StackPopTypes[0] = typeof(int);
|
|
return;
|
|
|
|
case Code.Stelem_I8:
|
|
StackPopTypes[0] = typeof(long);
|
|
return;
|
|
case Code.Conv_R_Un:
|
|
StackPushTypes[0] = typeof(Double);
|
|
return;
|
|
}
|
|
}
|
|
|
|
protected override void DoInterpretStackTypes(ref bool aSituationChanged)
|
|
{
|
|
base.DoInterpretStackTypes(ref aSituationChanged);
|
|
switch (OpCode)
|
|
{
|
|
case Code.Add:
|
|
case Code.Mul:
|
|
case Code.Mul_Ovf:
|
|
case Code.Mul_Ovf_Un:
|
|
case Code.Div:
|
|
case Code.Div_Un:
|
|
case Code.Sub:
|
|
case Code.Rem:
|
|
case Code.Rem_Un:
|
|
case Code.Xor:
|
|
case Code.And:
|
|
case Code.Or:
|
|
if (StackPushTypes[0] != null)
|
|
{
|
|
return;
|
|
}
|
|
if (!StackPopTypes.Contains(null))
|
|
{
|
|
// PopTypes set, but PushType not yet, so fill it.
|
|
|
|
if (StackPopTypes[0] == typeof(bool) && StackPopTypes[1] == typeof(bool))
|
|
{
|
|
StackPushTypes[0] = typeof(bool);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
|
|
if ((StackPopTypes[0] == typeof(bool) && StackPopTypes[1] == typeof(Int32)) ||
|
|
(StackPopTypes[0] == typeof(Int32) && StackPopTypes[1] == typeof(bool)))
|
|
{
|
|
StackPushTypes[0] = typeof(Int32);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
|
|
if ((StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(uint*))
|
|
|| (StackPopTypes[0] == typeof(uint*) && StackPopTypes[1] == typeof(IntPtr)))
|
|
{
|
|
StackPushTypes[0] = typeof(uint*);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(UIntPtr) && StackPopTypes[1] == typeof(uint*))
|
|
|| (StackPopTypes[0] == typeof(uint*) && StackPopTypes[1] == typeof(UIntPtr)))
|
|
{
|
|
StackPushTypes[0] = typeof(uint*);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(byte*))
|
|
|| (StackPopTypes[0] == typeof(byte*) && StackPopTypes[1] == typeof(uint)))
|
|
{
|
|
StackPushTypes[0] = typeof(byte*);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(byte*))
|
|
|| (StackPopTypes[0] == typeof(byte*) && StackPopTypes[1] == typeof(int)))
|
|
{
|
|
StackPushTypes[0] = typeof(byte*);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(byte*))
|
|
|| (StackPopTypes[0] == typeof(byte*) && StackPopTypes[1] == typeof(IntPtr)))
|
|
{
|
|
StackPushTypes[0] = typeof(byte*);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(uint))
|
|
|| (StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(IntPtr)))
|
|
{
|
|
StackPushTypes[0] = typeof(UIntPtr);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(UIntPtr))
|
|
|| (StackPopTypes[0] == typeof(UIntPtr) && StackPopTypes[1] == typeof(int)))
|
|
{
|
|
StackPushTypes[0] = typeof(UIntPtr);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(IntPtr))
|
|
|| (StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(int)))
|
|
{
|
|
StackPushTypes[0] = typeof(IntPtr);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(uint))
|
|
|| (StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(int)))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(short) && StackPopTypes[1] == typeof(ushort))
|
|
|| (StackPopTypes[0] == typeof(ushort) && StackPopTypes[1] == typeof(short)))
|
|
{
|
|
StackPushTypes[0] = typeof(short);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(byte))
|
|
|| (StackPopTypes[0] == typeof(byte) && StackPopTypes[1] == typeof(int)))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(short))
|
|
|| (StackPopTypes[0] == typeof(short) && StackPopTypes[1] == typeof(int)))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(long) && StackPopTypes[1] == typeof(ulong))
|
|
|| (StackPopTypes[0] == typeof(ulong) && StackPopTypes[1] == typeof(long)))
|
|
{
|
|
StackPushTypes[0] = typeof(long);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(ushort))
|
|
|| (StackPopTypes[0] == typeof(ushort) && StackPopTypes[1] == typeof(int)))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(byte) && StackPopTypes[1] == typeof(uint))
|
|
|| (StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(byte)))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(ushort) && StackPopTypes[1] == typeof(uint))
|
|
|| (StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(ushort)))
|
|
{
|
|
StackPushTypes[0] = typeof(uint);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(char))
|
|
|| (StackPopTypes[0] == typeof(char) && StackPopTypes[1] == typeof(int)))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(UIntPtr))
|
|
|| (StackPopTypes[0] == typeof(UIntPtr) && StackPopTypes[1] == typeof(IntPtr)))
|
|
{
|
|
StackPushTypes[0] = typeof(UIntPtr);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(IntPtr))
|
|
{
|
|
StackPushTypes[0] = typeof(IntPtr);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(uint))
|
|
{
|
|
StackPushTypes[0] = typeof(uint);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(char))
|
|
{
|
|
StackPushTypes[0] = typeof(uint);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] == typeof(byte) && StackPopTypes[1] == typeof(byte))
|
|
{
|
|
StackPushTypes[0] = typeof(byte);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(int))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(bool))
|
|
|| (StackPopTypes[0] == typeof(bool) && StackPopTypes[1] == typeof(int)))
|
|
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] == typeof(ushort) && StackPopTypes[1] == typeof(ushort))
|
|
{
|
|
StackPushTypes[0] = typeof(ushort);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
//Changed
|
|
if (StackPopTypes[0] == typeof(short) && StackPopTypes[1] == typeof(short))
|
|
{
|
|
StackPushTypes[0] = typeof(short);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] == typeof(long) && StackPopTypes[1] == typeof(long))
|
|
{
|
|
StackPushTypes[0] = typeof(long);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] == typeof(ulong) && StackPopTypes[1] == typeof(ulong))
|
|
{
|
|
StackPushTypes[0] = typeof(ulong);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] == typeof(Double) && StackPopTypes[1] == typeof(Double))
|
|
{
|
|
StackPushTypes[0] = typeof(Double);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] == typeof(Single) && StackPopTypes[1] == typeof(Single))
|
|
{
|
|
StackPushTypes[0] = typeof(Single);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
|
|
if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(sbyte))
|
|
|| (StackPopTypes[0] == typeof(sbyte) && StackPopTypes[1] == typeof(int)))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] == StackPopTypes[1] && StackPopTypes[0].IsPointer)
|
|
{
|
|
StackPushTypes[0] = StackPopTypes[0];
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] == typeof(int) &&
|
|
StackPopTypes[1].IsPointer)
|
|
{
|
|
StackPushTypes[0] = StackPopTypes[1];
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if ((StackPopTypes[0] == typeof(IntPtr) || StackPopTypes[0] == typeof(UIntPtr)) &&
|
|
StackPopTypes[1].IsPointer)
|
|
{
|
|
StackPushTypes[0] = StackPopTypes[1];
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (OpCode == Code.Add &&
|
|
((StackPopTypes[0] == typeof(IntPtr) && (StackPopTypes[1].IsPointer || StackPopTypes[1].IsByRef))
|
|
|| ((StackPopTypes[0].IsPointer || StackPopTypes[0].IsByRef) && StackPopTypes[1] == typeof(IntPtr))))
|
|
{
|
|
if (StackPopTypes[0] == typeof(IntPtr))
|
|
{
|
|
StackPushTypes[0] = StackPopTypes[1];
|
|
}
|
|
else
|
|
{
|
|
StackPushTypes[0] = StackPopTypes[0];
|
|
}
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
|
|
throw new NotImplementedException(string.Format("{0} on types '{1}' and '{2}' not yet implemented!", OpCode, StackPopTypes[0], StackPopTypes[1]));
|
|
}
|
|
break;
|
|
case Code.Localloc:
|
|
StackPushTypes[0] = typeof(void*);
|
|
aSituationChanged = true;
|
|
return;
|
|
case Code.Stelem_I2:
|
|
var xTypeValue = StackPopTypes[0];
|
|
if (xTypeValue == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (xTypeValue == typeof(byte)
|
|
|| xTypeValue == typeof(char)
|
|
|| xTypeValue == typeof(short)
|
|
|| xTypeValue == typeof(ushort)
|
|
|| xTypeValue == typeof(int))
|
|
{
|
|
return;
|
|
}
|
|
throw new NotImplementedException(String.Format("Stelem_I2 storing type '{0}' is not implemented!", xTypeValue));
|
|
case Code.Shl:
|
|
case Code.Shr:
|
|
case Code.Shr_Un:
|
|
xTypeValue = StackPopTypes[1];
|
|
var xTypeShift = StackPopTypes[0];
|
|
if (xTypeValue == null || xTypeShift == null)
|
|
{
|
|
return;
|
|
}
|
|
if (xTypeValue == typeof(int) && xTypeShift == typeof(int))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (xTypeValue == typeof(byte) && xTypeShift == typeof(int))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (xTypeValue == typeof(long) && xTypeShift == typeof(int))
|
|
{
|
|
StackPushTypes[0] = typeof(long);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (xTypeValue == typeof(IntPtr) && xTypeShift == typeof(int))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (xTypeValue == typeof(int) && xTypeShift == typeof(IntPtr))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (xTypeValue == typeof(ushort) && xTypeShift == typeof(int))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (xTypeValue == typeof(char) && xTypeShift == typeof(int))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (xTypeValue == typeof(uint) && xTypeShift == typeof(int))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (xTypeValue == typeof(long) && xTypeShift == typeof(IntPtr))
|
|
{
|
|
StackPushTypes[0] = typeof(long);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (xTypeValue == typeof(IntPtr) && xTypeShift == typeof(IntPtr))
|
|
{
|
|
StackPushTypes[0] = typeof(IntPtr);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (xTypeValue == typeof(IntPtr) && xTypeShift == typeof(IntPtr))
|
|
{
|
|
StackPushTypes[0] = typeof(IntPtr);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (xTypeValue == typeof(ulong) && xTypeShift == typeof(int))
|
|
{
|
|
StackPushTypes[0] = typeof(ulong);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (xTypeValue == typeof(sbyte) && xTypeShift == typeof(int))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
if (xTypeValue == typeof(short) && xTypeShift == typeof(int))
|
|
{
|
|
StackPushTypes[0] = typeof(int);
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
throw new NotImplementedException(String.Format("{0} with types {1} and {2} is not implemented!", OpCode, xTypeValue.FullName, xTypeShift.FullName));
|
|
case Code.Ldelem_Ref:
|
|
if (StackPushTypes[0] != null)
|
|
{
|
|
return;
|
|
}
|
|
var xTypeArray = StackPopTypes[1];
|
|
if (xTypeArray == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!xTypeArray.IsArray)
|
|
{
|
|
throw new Exception("Ldelem Array type is not an array (Actual = " + xTypeArray.FullName + ")");
|
|
}
|
|
StackPushTypes[0] = xTypeArray.GetElementType();
|
|
aSituationChanged = true;
|
|
break;
|
|
case Code.Not:
|
|
case Code.Neg:
|
|
if (StackPushTypes[0] != null)
|
|
{
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] != null)
|
|
{
|
|
StackPushTypes[0] = StackPopTypes[0];
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
break;
|
|
case Code.Dup:
|
|
if (StackPushTypes[0] != null && StackPushTypes[1] != null)
|
|
{
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] != null)
|
|
{
|
|
StackPushTypes[0] = StackPopTypes[0];
|
|
StackPushTypes[1] = StackPopTypes[0];
|
|
aSituationChanged = true;
|
|
return;
|
|
}
|
|
return;
|
|
case Code.Stind_I1:
|
|
if (StackPopTypes[1] == null || StackPopTypes[0] == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!IsIntegralType(StackPopTypes[0]))
|
|
{
|
|
throw new Exception("Wrong value type: " + StackPopTypes[0].FullName);
|
|
}
|
|
if (!IsPointer(StackPopTypes[1]))
|
|
{
|
|
throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName);
|
|
}
|
|
break;
|
|
case Code.Stind_I2:
|
|
if (StackPopTypes[1] == null || StackPopTypes[0] == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!IsIntegralType(StackPopTypes[0]))
|
|
{
|
|
throw new Exception("Wrong value type: " + StackPopTypes[0].FullName);
|
|
}
|
|
if (!IsPointer(StackPopTypes[1]))
|
|
{
|
|
throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName);
|
|
}
|
|
break;
|
|
case Code.Stind_I4:
|
|
if (StackPopTypes[1] == null || StackPopTypes[0] == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!IsIntegralType(StackPopTypes[0]))
|
|
{
|
|
throw new Exception("Wrong value type: " + StackPopTypes[0].FullName);
|
|
}
|
|
if (!IsPointer(StackPopTypes[1]))
|
|
{
|
|
throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName);
|
|
}
|
|
break;
|
|
case Code.Stind_I8:
|
|
if (StackPopTypes[1] == null || StackPopTypes[0] == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!IsIntegralType(StackPopTypes[0]))
|
|
{
|
|
throw new Exception("Wrong value type: " + StackPopTypes[0].FullName);
|
|
}
|
|
if (!IsPointer(StackPopTypes[1]))
|
|
{
|
|
throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName);
|
|
}
|
|
break;
|
|
case Code.Stind_I:
|
|
if (StackPopTypes[1] == null || StackPopTypes[0] == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!IsIntegralTypeOrPointer(StackPopTypes[0]))
|
|
{
|
|
throw new Exception("Wrong value type: " + StackPopTypes[0].FullName);
|
|
}
|
|
if (!IsPointer(StackPopTypes[1]))
|
|
{
|
|
throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName);
|
|
}
|
|
break;
|
|
case Code.Ldind_Ref:
|
|
if (StackPushTypes[0] != null)
|
|
{
|
|
return;
|
|
}
|
|
if (StackPopTypes[0] == null)
|
|
{
|
|
return;
|
|
}
|
|
if (!StackPopTypes[0].IsByRef)
|
|
{
|
|
throw new Exception("Invalid ref type: " + StackPopTypes[0].FullName);
|
|
}
|
|
StackPushTypes[0] = StackPopTypes[0].GetElementType();
|
|
aSituationChanged = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|