2018-02-20 20:09:23 +00:00
|
|
|
using System;
|
|
|
|
|
|
|
|
namespace ChocolArm64
|
|
|
|
{
|
|
|
|
using System.Reflection.Emit;
|
2018-03-20 20:00:00 +00:00
|
|
|
|
2018-02-20 20:09:23 +00:00
|
|
|
static class ILGeneratorEx
|
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
public static void EmitLdc_I4(this ILGenerator generator, int value)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
switch (value)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
case 0: generator.Emit(OpCodes.Ldc_I4_0); break;
|
|
|
|
case 1: generator.Emit(OpCodes.Ldc_I4_1); break;
|
|
|
|
case 2: generator.Emit(OpCodes.Ldc_I4_2); break;
|
|
|
|
case 3: generator.Emit(OpCodes.Ldc_I4_3); break;
|
|
|
|
case 4: generator.Emit(OpCodes.Ldc_I4_4); break;
|
|
|
|
case 5: generator.Emit(OpCodes.Ldc_I4_5); break;
|
|
|
|
case 6: generator.Emit(OpCodes.Ldc_I4_6); break;
|
|
|
|
case 7: generator.Emit(OpCodes.Ldc_I4_7); break;
|
|
|
|
case 8: generator.Emit(OpCodes.Ldc_I4_8); break;
|
|
|
|
case -1: generator.Emit(OpCodes.Ldc_I4_M1); break;
|
|
|
|
default: generator.Emit(OpCodes.Ldc_I4, value); break;
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-31 01:43:02 +00:00
|
|
|
public static void EmitLdarg(this ILGenerator generator, int index)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
switch (index)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
case 0: generator.Emit(OpCodes.Ldarg_0); break;
|
|
|
|
case 1: generator.Emit(OpCodes.Ldarg_1); break;
|
|
|
|
case 2: generator.Emit(OpCodes.Ldarg_2); break;
|
|
|
|
case 3: generator.Emit(OpCodes.Ldarg_3); break;
|
2018-02-20 20:09:23 +00:00
|
|
|
|
|
|
|
default:
|
2018-10-31 01:43:02 +00:00
|
|
|
if ((uint)index <= byte.MaxValue)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
generator.Emit(OpCodes.Ldarg_S, (byte)index);
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
2018-10-31 01:43:02 +00:00
|
|
|
else if ((uint)index < ushort.MaxValue)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
generator.Emit(OpCodes.Ldarg, (short)index);
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
throw new ArgumentOutOfRangeException(nameof(index));
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-31 01:43:02 +00:00
|
|
|
public static void EmitStarg(this ILGenerator generator, int index)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
if ((uint)index <= byte.MaxValue)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
generator.Emit(OpCodes.Starg_S, (byte)index);
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
2018-10-31 01:43:02 +00:00
|
|
|
else if ((uint)index < ushort.MaxValue)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
generator.Emit(OpCodes.Starg, (short)index);
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
throw new ArgumentOutOfRangeException(nameof(index));
|
2018-07-03 06:31:48 +00:00
|
|
|
}
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
|
|
|
|
2018-10-31 01:43:02 +00:00
|
|
|
public static void EmitLdloc(this ILGenerator generator, int index)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
switch (index)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
case 0: generator.Emit(OpCodes.Ldloc_0); break;
|
|
|
|
case 1: generator.Emit(OpCodes.Ldloc_1); break;
|
|
|
|
case 2: generator.Emit(OpCodes.Ldloc_2); break;
|
|
|
|
case 3: generator.Emit(OpCodes.Ldloc_3); break;
|
2018-02-20 20:09:23 +00:00
|
|
|
|
|
|
|
default:
|
2018-10-31 01:43:02 +00:00
|
|
|
if ((uint)index <= byte.MaxValue)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
generator.Emit(OpCodes.Ldloc_S, (byte)index);
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
2018-10-31 01:43:02 +00:00
|
|
|
else if ((uint)index < ushort.MaxValue)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
generator.Emit(OpCodes.Ldloc, (short)index);
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
throw new ArgumentOutOfRangeException(nameof(index));
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
|
|
|
break;
|
2018-07-03 06:31:48 +00:00
|
|
|
}
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
|
|
|
|
2018-10-31 01:43:02 +00:00
|
|
|
public static void EmitStloc(this ILGenerator generator, int index)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
switch (index)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
case 0: generator.Emit(OpCodes.Stloc_0); break;
|
|
|
|
case 1: generator.Emit(OpCodes.Stloc_1); break;
|
|
|
|
case 2: generator.Emit(OpCodes.Stloc_2); break;
|
|
|
|
case 3: generator.Emit(OpCodes.Stloc_3); break;
|
2018-02-20 20:09:23 +00:00
|
|
|
|
|
|
|
default:
|
2018-10-31 01:43:02 +00:00
|
|
|
if ((uint)index <= byte.MaxValue)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
generator.Emit(OpCodes.Stloc_S, (byte)index);
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
2018-10-31 01:43:02 +00:00
|
|
|
else if ((uint)index < ushort.MaxValue)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
generator.Emit(OpCodes.Stloc, (short)index);
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
throw new ArgumentOutOfRangeException(nameof(index));
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-31 01:43:02 +00:00
|
|
|
public static void EmitLdargSeq(this ILGenerator generator, int count)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
for (int index = 0; index < count; index++)
|
2018-02-20 20:09:23 +00:00
|
|
|
{
|
2018-10-31 01:43:02 +00:00
|
|
|
generator.EmitLdarg(index);
|
2018-07-03 06:31:48 +00:00
|
|
|
}
|
2018-02-20 20:09:23 +00:00
|
|
|
}
|
|
|
|
}
|
2018-04-29 23:39:58 +00:00
|
|
|
}
|