VMProtect/core/il.h

855 lines
42 KiB
C
Raw Normal View History

2023-05-14 16:21:09 +03:00
#ifndef IL_H
#define IL_H
enum ILCommandType {
icUnknown, icByte, icWord, icDword, icQword, icComment, icData, icCase,
icNop, icBreak, icLdarg_0, icLdarg_1, icLdarg_2, icLdarg_3, icLdloc_0, icLdloc_1, icLdloc_2, icLdloc_3, icStloc_0, icStloc_1,
icStloc_2, icStloc_3, icLdarg_s, icLdarga_s, icStarg_s, icLdloc_s, icLdloca_s, icStloc_s, icLdnull, icLdc_i4_m1, icLdc_i4_0,
icLdc_i4_1, icLdc_i4_2, icLdc_i4_3, icLdc_i4_4, icLdc_i4_5, icLdc_i4_6, icLdc_i4_7, icLdc_i4_8, icLdc_i4_s, icLdc_i4, icLdc_i8,
icLdc_r4, icLdc_r8, icDup, icPop, icJmp, icCall, icCalli, icRet, icBr_s, icBrfalse_s, icBrtrue_s, icBeq_s, icBge_s, icBgt_s, icBle_s,
icBlt_s, icBne_un_s, icBge_un_s, icBgt_un_s, icBle_un_s, icBlt_un_s, icBr, icBrfalse, icBrtrue, icBeq, icBge, icBgt, icBle, icBlt,
icBne_un, icBge_un, icBgt_un, icBle_un, icBlt_un, icSwitch, icLdind_i1, icLdind_u1, icLdind_i2, icLdind_u2, icLdind_i4, icLdind_u4,
icLdind_i8, icLdind_i, icLdind_r4, icLdind_r8, icLdind_ref, icStind_ref, icStind_i1, icStind_i2, icStind_i4, icStind_i8, icStind_r4,
icStind_r8, icAdd, icSub, icMul, icDiv, icDiv_un, icRem, icRem_un, icAnd, icOr, icXor, icShl, icShr, icShr_un, icNeg, icNot, icConv_i1, icConv_i2,
icConv_i4, icConv_i8, icConv_r4, icConv_r8, icConv_u4, icConv_u8, icCallvirt, icCpobj, icLdobj, icLdstr, icNewobj, icCastclass,
icIsinst, icConv_r_un, icUnbox, icThrow, icLdfld, icLdflda, icStfld, icLdsfld, icLdsflda, icStsfld, icStobj, icConv_ovf_i1_un,
icConv_ovf_i2_un, icConv_ovf_i4_un, icConv_ovf_i8_un, icConv_ovf_u1_un, icConv_ovf_u2_un, icConv_ovf_u4_un, icConv_ovf_u8_un,
icConv_ovf_i_un, icConv_ovf_u_un, icBox, icNewarr, icLdlen, icLdelema, icLdelem_i1, icLdelem_u1, icLdelem_i2, icLdelem_u2,
icLdelem_i4, icLdelem_u4, icLdelem_i8, icLdelem_i, icLdelem_r4, icLdelem_r8, icLdelem_ref, icStelem_i, icStelem_i1, icStelem_i2,
icStelem_i4, icStelem_i8, icStelem_r4, icStelem_r8, icStelem_ref, icLdelem, icStelem, icUnbox_any, icConv_ovf_i1, icConv_ovf_u1,
icConv_ovf_i2, icConv_ovf_u2, icConv_ovf_i4, icConv_ovf_u4, icConv_ovf_i8, icConv_ovf_u8, icRefanyval, icCkfinite, icMkrefany,
icLdtoken, icConv_u2, icConv_u1, icConv_i, icConv_ovf_i, icConv_ovf_u, icAdd_ovf, icAdd_ovf_un, icMul_ovf, icMul_ovf_un, icSub_ovf,
icSub_ovf_un, icEndfinally, icLeave, icLeave_s, icStind_i, icConv_u, icArglist, icCeq, icCgt, icCgt_un, icClt, icClt_un, icLdftn, icLdvirtftn,
icLdarg, icLdarga, icStarg, icLdloc, icLdloca, icStloc, icLocalloc, icEndfilter, icUnaligned, icVolatile, icTail, icInitobj, icConstrained,
icCpblk, icInitblk, icNo, icRethrow, icSizeof, icRefanytype, icReadonly,
icConv, icConv_ovf, icConv_ovf_un, icLdmem_i4, icInitarg, icInitcatchblock, icEntertry, icCallvm, icCallvmvirt,
icCmp, icCmp_un,
icCNT
};
enum ILFlowControl : uint8_t
{
Branch,
Break,
Call,
Cond_Branch,
Meta, // Provides information about a subsequent instruction. For example, the Unaligned instruction of Reflection.Emit.Opcodes has FlowControl.Meta and specifies that the subsequent pointer instruction might be unaligned.
Next, // Normal flow of control
Phi, // Obsolete. This enumerator value is reserved and should not be used.
Return,
Throw
};
enum ILOpCodeType : uint8_t
{
Experimental, // Reserved (ECMA) instruction
Macro, // synonym for other MSIL instructions (ldarg.0 - ldarg)
Reserved, // Reserved (ECMA) instruction
Objmodel, // Instruction that applies to objects
Prefix, // Prefix instruction that modifies the behavior of the following instruction
Primitive // Built-in instruction
};
enum ILOperandType : uint8_t// The operand is a ...
{
InlineBrTarget, // 32-bit integer branch target
InlineField, // 32-bit metadata token
InlineI, // 32-bit integer
InlineI8, // 64-bit integer
InlineMethod, // 32-bit metadata token
InlineNone, // No operand
InlinePhi, // Obsolete. The operand is reserved and should not be used.
InlineR, // 64-bit IEEE floating point number
Inline8, // not used
InlineSig, // 32-bit metadata signature token
InlineString, // 32-bit metadata string token
InlineSwitch, // 32-bit integer argument to a switch instruction
InlineTok, // FieldRef, MethodRef, or TypeRef token
InlineType, // 32-bit metadata token
InlineVar, // 16-bit integer containing the ordinal of a local variable or an argument
ShortInlineBrTarget, // 8-bit integer branch target
ShortInlineI, // 8-bit integer
ShortInlineR, // 32-bit IEEE floating point number
ShortInlineVar, // 8-bit integer containing the ordinal of a local variable or an argument
};
enum ILStackBehaviour : uint8_t
{
Pop0, // No values are popped off the stack.
Pop1, // Pops one value off the stack.
Pop1_pop1, // Pops 1 value off the stack for the first operand, and 1 value of the stack for the second operand.
Popi, // Pops a 32-bit integer off the stack.
Popi_pop1, // Pops a 32-bit integer off the stack for the first operand, and a value off the stack for the second operand.
Popi_popi, // Pops a 32-bit integer off the stack for the first operand, and a 32-bit integer off the stack for the second operand.
Popi_popi8, // Pops a 32-bit integer off the stack for the first operand, and a 64-bit integer off the stack for the second operand.
Popi_popi_popi, // Pops a 32-bit integer off the stack for the first operand, a 32-bit integer off the stack for the second operand, and a 32-bit integer off the stack for the third operand.
Popi_popr4, // Pops a 32-bit integer off the stack for the first operand, and a 32-bit floating point number off the stack for the second operand.
Popi_popr8, // Pops a 32-bit integer off the stack for the first operand, and a 64-bit floating point number off the stack for the second operand.
Popref, // Pops a reference off the stack.
Popref_pop1, // Pops a reference off the stack for the first operand, and a value off the stack for the second operand.
Popref_popi, // Pops a reference off the stack for the first operand, and a 32-bit integer off the stack for the second operand.
Popref_popi_popi, // Pops a reference off the stack for the first operand, a value off the stack for the second operand, and a value off the stack for the third operand.
Popref_popi_popi8, // Pops a reference off the stack for the first operand, a value off the stack for the second operand, and a 64-bit integer off the stack for the third operand.
Popref_popi_popr4, // Pops a reference off the stack for the first operand, a value off the stack for the second operand, and a 32-bit integer off the stack for the third operand.
Popref_popi_popr8, // Pops a reference off the stack for the first operand, a value off the stack for the second operand, and a 64-bit floating point number off the stack for the third operand.
Popref_popi_popref, // Pops a reference off the stack for the first operand, a value off the stack for the second operand, and a reference off the stack for the third operand.
Push0, // No values are pushed onto the stack.
Push1, // Pushes one value onto the stack.
Push1_push1, // Pushes 1 value onto the stack for the first operand, and 1 value onto the stack for the second operand.
Pushi, // Pushes a 32-bit integer onto the stack.
Pushi8, // Pushes a 64-bit integer onto the stack.
Pushr4, // Pushes a 32-bit floating point number onto the stack.
Pushr8, // Pushes a 64-bit floating point number onto the stack.
Pushref, // Pushes a reference onto the stack.
Varpop, // Pops a variable off the stack.
Varpush, // Pushes a variable onto the stack.
Popref_popi_pop1 // Pops a reference off the stack for the first operand, a value off the stack for the second operand, and a 32-bit integer off the stack for the third operand.
};
struct ILOpCode {
const char *name;
ILStackBehaviour pop;
ILStackBehaviour push;
ILOperandType operand_type;
ILOpCodeType opcode_type;
ILFlowControl flow_type;
bool is_ret;
int stack_change;
} const ILOpCodes[icCNT] = {
{".byte ??", Pop0, Push0, InlineNone, Primitive, Next, false, 0},
{".byte", Pop0, Push0, ShortInlineI, Primitive, Next, false, 0},
{".word", Pop0, Push0, InlineVar, Primitive, Next, false, 0},
{".dword", Pop0, Push0, InlineI, Primitive, Next, false, 0},
{".qword", Pop0, Push0, InlineI8, Primitive, Next, false, 0},
{"", Pop0, Push0, InlineNone, Primitive, Next, false, 0},
{".byte", Pop0, Push0, InlineNone, Primitive, Next, false, 0},
{"", Pop0, Push0, InlineI, Primitive, Next, false, 0},
{"nop", Pop0, Push0, InlineNone, Primitive, Next, false, 0},
{"break", Pop0, Push0, InlineNone, Primitive, Break, false, 0},
{"ldarg.0", Pop0, Push1, InlineNone, Macro, Next, false, 1},
{"ldarg.1", Pop0, Push1, InlineNone, Macro, Next, false, 1},
{"ldarg.2", Pop0, Push1, InlineNone, Macro, Next, false, 1},
{"ldarg.3", Pop0, Push1, InlineNone, Macro, Next, false, 1},
{"ldloc.0", Pop0, Push1, InlineNone, Macro, Next, false, 1},
{"ldloc.1", Pop0, Push1, InlineNone, Macro, Next, false, 1},
{"ldloc.2", Pop0, Push1, InlineNone, Macro, Next, false, 1},
{"ldloc.3", Pop0, Push1, InlineNone, Macro, Next, false, 1},
{"stloc.0", Pop1, Push0, InlineNone, Macro, Next, false, -1},
{"stloc.1", Pop1, Push0, InlineNone, Macro, Next, false, -1},
{"stloc.2", Pop1, Push0, InlineNone, Macro, Next, false, -1},
{"stloc.3", Pop1, Push0, InlineNone, Macro, Next, false, -1},
{"ldarg.s", Pop0, Push1, ShortInlineVar, Macro, Next, false, 1},
{"ldarga.s", Pop0, Pushi, ShortInlineVar, Macro, Next, false, 1},
{"starg.s", Pop1, Push0, ShortInlineVar, Macro, Next, false, -1},
{"ldloc.s", Pop0, Push1, ShortInlineVar, Macro, Next, false, 1},
{"ldloca.s", Pop0, Pushi, ShortInlineVar, Macro, Next, false, 1},
{"stloc.s", Pop1, Push0, ShortInlineVar, Macro, Next, false, -1},
{"ldnull", Pop0, Pushref, InlineNone, Primitive, Next, false, 1},
{"ldc.i4.m1", Pop0, Pushi, InlineNone, Macro, Next, false, 1},
{"ldc.i4.0", Pop0, Pushi, InlineNone, Macro, Next, false, 1},
{"ldc.i4.1", Pop0, Pushi, InlineNone, Macro, Next, false, 1},
{"ldc.i4.2", Pop0, Pushi, InlineNone, Macro, Next, false, 1},
{"ldc.i4.3", Pop0, Pushi, InlineNone, Macro, Next, false, 1},
{"ldc.i4.4", Pop0, Pushi, InlineNone, Macro, Next, false, 1},
{"ldc.i4.5", Pop0, Pushi, InlineNone, Macro, Next, false, 1},
{"ldc.i4.6", Pop0, Pushi, InlineNone, Macro, Next, false, 1},
{"ldc.i4.7", Pop0, Pushi, InlineNone, Macro, Next, false, 1},
{"ldc.i4.8", Pop0, Pushi, InlineNone, Macro, Next, false, 1},
{"ldc.i4.s", Pop0, Pushi, ShortInlineI, Macro, Next, false, 1},
{"ldc.i4", Pop0, Pushi, InlineI, Primitive, Next, false, 1},
{"ldc.i8", Pop0, Pushi8, InlineI8, Primitive, Next, false, 1},
{"ldc.r4", Pop0, Pushr4, ShortInlineR, Primitive, Next, false, 1},
{"ldc.r8", Pop0, Pushr8, InlineR, Primitive, Next, false, 1},
{"dup", Pop1, Push1_push1, InlineNone, Primitive, Next, false, 1},
{"pop", Pop1, Push0, InlineNone, Primitive, Next, false, -1},
{"jmp", Pop0, Push0, InlineMethod, Primitive, Call, true, 0},
{"call", Varpop, Varpush, InlineMethod, Primitive, Call, false, 0},
{"calli", Varpop, Varpush, InlineSig, Primitive, Call, false, 0},
{"ret", Varpop, Push0, InlineNone, Primitive, Return, true, 0},
{"br.s", Pop0, Push0, ShortInlineBrTarget, Macro, Branch, true, 0},
{"brfalse.s", Popi, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -1},
{"brtrue.s", Popi, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -1},
{"beq.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2},
{"bge.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2},
{"bgt.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2},
{"ble.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2},
{"blt.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2},
{"bne.un.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2},
{"bge.un.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2},
{"bgt.un.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2},
{"ble.un.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2},
{"blt.un.s", Pop1_pop1, Push0, ShortInlineBrTarget, Macro, Cond_Branch, false, -2},
{"br", Pop0, Push0, InlineBrTarget, Primitive, Branch, true, 0},
{"brfalse", Popi, Push0, InlineBrTarget, Primitive, Cond_Branch, false, -1},
{"brtrue", Popi, Push0, InlineBrTarget, Primitive, Cond_Branch, false, -1},
{"beq", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2},
{"bge", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2},
{"bgt", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2},
{"ble", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2},
{"blt", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2},
{"bne.un", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2},
{"bge.un", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2},
{"bgt.un", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2},
{"ble.un", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2},
{"blt.un", Pop1_pop1, Push0, InlineBrTarget, Macro, Cond_Branch, false, -2},
{"switch", Popi, Push0, InlineSwitch, Primitive, Cond_Branch, false, -1},
{"ldind.i1", Popi, Pushi, InlineNone, Primitive, Next, false, 0},
{"ldind.u1", Popi, Pushi, InlineNone, Primitive, Next, false, 0},
{"ldind.i2", Popi, Pushi, InlineNone, Primitive, Next, false, 0},
{"ldind.u2", Popi, Pushi, InlineNone, Primitive, Next, false, 0},
{"ldind.i4", Popi, Pushi, InlineNone, Primitive, Next, false, 0},
{"ldind.u4", Popi, Pushi, InlineNone, Primitive, Next, false, 0},
{"ldind.i8", Popi, Pushi8, InlineNone, Primitive, Next, false, 0},
{"ldind.i", Popi, Pushi, InlineNone, Primitive, Next, false, 0},
{"ldind.r4", Popi, Pushr4, InlineNone, Primitive, Next, false, 0},
{"ldind.r8", Popi, Pushr8, InlineNone, Primitive, Next, false, 0},
{"ldind.ref", Popi, Pushref, InlineNone, Primitive, Next, false, 0},
{"stind.ref", Popi_popi, Push0, InlineNone, Primitive, Next, false, -2},
{"stind.i1", Popi_popi, Push0, InlineNone, Primitive, Next, false, -2},
{"stind.i2", Popi_popi, Push0, InlineNone, Primitive, Next, false, -2},
{"stind.i4", Popi_popi, Push0, InlineNone, Primitive, Next, false, -2},
{"stind.i8", Popi_popi8, Push0, InlineNone, Primitive, Next, false, -2},
{"stind.r4", Popi_popr4, Push0, InlineNone, Primitive, Next, false, -2},
{"stind.r8", Popi_popr8, Push0, InlineNone, Primitive, Next, false, -2},
{"add", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"sub", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"mul", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"div", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"div.un", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"rem", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"rem.un", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"and", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"or", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"xor", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"shl", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"shr", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"shr.un", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"neg", Pop1, Push1, InlineNone, Primitive, Next, false, 0},
{"not", Pop1, Push1, InlineNone, Primitive, Next, false, 0},
{"conv.i1", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.i2", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.i4", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.i8", Pop1, Pushi8, InlineNone, Primitive, Next, false, 0},
{"conv.r4", Pop1, Pushr4, InlineNone, Primitive, Next, false, 0},
{"conv.r8", Pop1, Pushr8, InlineNone, Primitive, Next, false, 0},
{"conv.u4", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.u8", Pop1, Pushi8, InlineNone, Primitive, Next, false, 0},
{"callvirt", Varpop, Varpush, InlineMethod, Objmodel, Call, false, 0},
{"cpobj", Popi_popi, Push0, InlineType, Objmodel, Next, false, -2},
{"ldobj", Popi, Push1, InlineType, Objmodel, Next, false, 0},
{"ldstr", Pop0, Pushref, InlineString, Objmodel, Next, false, 1},
{"newobj", Varpop, Pushref, InlineMethod, Objmodel, Call, false, 1},
{"castclass", Popref, Pushref, InlineType, Objmodel, Next, false, 0},
{"isinst", Popref, Pushi, InlineType, Objmodel, Next, false, 0},
{"conv.r.un", Pop1, Pushr8, InlineNone, Primitive, Next, false, 0},
{"unbox", Popref, Pushi, InlineType, Primitive, Next, false, 0},
{"throw", Popref, Push0, InlineNone, Objmodel, Throw, true, -1},
{"ldfld", Popref, Push1, InlineField, Objmodel, Next, false, 0},
{"ldflda", Popref, Pushi, InlineField, Objmodel, Next, false, 0},
{"stfld", Popref_pop1, Push0, InlineField, Objmodel, Next, false, -2},
{"ldsfld", Pop0, Push1, InlineField, Objmodel, Next, false, 1},
{"ldsflda", Pop0, Pushi, InlineField, Objmodel, Next, false, 1},
{"stsfld", Pop1, Push0, InlineField, Objmodel, Next, false, -1},
{"stobj", Popi_pop1, Push0, InlineType, Primitive, Next, false, -2},
{"conv.ovf.i1.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.i2.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.i4.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.i8.un", Pop1, Pushi8, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.u1.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.u2.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.u4.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.u8.un", Pop1, Pushi8, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.i.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.u.un", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"box", Pop1, Pushref, InlineType, Primitive, Next, false, 0},
{"newarr", Popi, Pushref, InlineType, Objmodel, Next, false, 0},
{"ldlen", Popref, Pushi, InlineNone, Objmodel, Next, false, 0},
{"ldelema", Popref_popi, Pushi, InlineType, Objmodel, Next, false, -1},
{"ldelem.i1", Popref_popi, Pushi, InlineNone, Objmodel, Next, false, -1},
{"ldelem.u1", Popref_popi, Pushi, InlineNone, Objmodel, Next, false, -1},
{"ldelem.i2", Popref_popi, Pushi, InlineNone, Objmodel, Next, false, -1},
{"ldelem.u2", Popref_popi, Pushi, InlineNone, Objmodel, Next, false, -1},
{"ldelem.i4", Popref_popi, Pushi, InlineNone, Objmodel, Next, false, -1},
{"ldelem.u4", Popref_popi, Pushi, InlineNone, Objmodel, Next, false, -1},
{"ldelem.i8", Popref_popi, Pushi8, InlineNone, Objmodel, Next, false, -1},
{"ldelem.i", Popref_popi, Pushi, InlineNone, Objmodel, Next, false, -1},
{"ldelem.r4", Popref_popi, Pushr4, InlineNone, Objmodel, Next, false, -1},
{"ldelem.r8", Popref_popi, Pushr8, InlineNone, Objmodel, Next, false, -1},
{"ldelem.ref", Popref_popi, Pushref, InlineNone, Objmodel, Next, false, -1},
{"stelem.i", Popref_popi_popi, Push0, InlineNone, Objmodel, Next, false, -3},
{"stelem.i1", Popref_popi_popi, Push0, InlineNone, Objmodel, Next, false, -3},
{"stelem.i2", Popref_popi_popi, Push0, InlineNone, Objmodel, Next, false, -3},
{"stelem.i4", Popref_popi_popi, Push0, InlineNone, Objmodel, Next, false, -3},
{"stelem.i8", Popref_popi_popi8, Push0, InlineNone, Objmodel, Next, false, -3},
{"stelem.r4", Popref_popi_popr4, Push0, InlineNone, Objmodel, Next, false, -3},
{"stelem.r8", Popref_popi_popr8, Push0, InlineNone, Objmodel, Next, false, -3},
{"stelem.ref", Popref_popi_popref, Push0, InlineNone, Objmodel, Next, false, -3},
{"ldelem", Popref_popi, Push1, InlineType, Objmodel, Next, false, -1},
{"stelem", Popref_popi_pop1, Push0, InlineType, Objmodel, Next, false, 0},
{"unbox.any", Popref, Push1, InlineType, Objmodel, Next, false, 0},
{"conv.ovf.i1", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.u1", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.i2", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.u2", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.i4", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.u4", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.i8", Pop1, Pushi8, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.u8", Pop1, Pushi8, InlineNone, Primitive, Next, false, 0},
{"refanyval", Pop1, Pushi, InlineType, Primitive, Next, false, 0},
{"ckfinite", Pop1, Pushr8, InlineNone, Primitive, Next, false, 0},
{"mkrefany", Popi, Push1, InlineType, Primitive, Next, false, 0},
{"ldtoken", Pop0, Pushi, InlineTok, Primitive, Next, false, 1},
{"conv.u2", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.u1", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.i", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.i", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"conv.ovf.u", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"add.ovf", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"add.ovf.un", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"mul.ovf", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"mul.ovf.un", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"sub.ovf", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"sub.ovf.un", Pop1_pop1, Push1, InlineNone, Primitive, Next, false, -1},
{"endfinally", Pop0, Push0, InlineNone, Primitive, Return, true, 0},
{"leave", Pop0, Push0, InlineBrTarget, Primitive, Branch, true, 0},
{"leave.s", Pop0, Push0, ShortInlineBrTarget, Primitive, Branch, true, 0},
{"stind.i", Popi_popi, Push0, InlineNone, Primitive, Next, false, -2},
{"conv.u", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"arglist", Pop0, Pushi, InlineNone, Primitive, Next, false, 1},
{"ceq", Pop1_pop1, Pushi, InlineNone, Primitive, Next, false, -1},
{"cgt", Pop1_pop1, Pushi, InlineNone, Primitive, Next, false, -1},
{"cgt.un", Pop1_pop1, Pushi, InlineNone, Primitive, Next, false, -1},
{"clt", Pop1_pop1, Pushi, InlineNone, Primitive, Next, false, -1},
{"clt.un", Pop1_pop1, Pushi, InlineNone, Primitive, Next, false, -1},
{"ldftn", Pop0, Pushi, InlineMethod, Primitive, Next, false, 1},
{"ldvirtftn", Popref, Pushi, InlineMethod, Primitive, Next, false, 0},
{"ldarg", Pop0, Push1, InlineVar, Primitive, Next, false, 1},
{"ldarga", Pop0, Pushi, InlineVar, Primitive, Next, false, 1},
{"starg", Pop1, Push0, InlineVar, Primitive, Next, false, -1},
{"ldloc", Pop0, Push1, InlineVar, Primitive, Next, false, 1},
{"ldloca", Pop0, Pushi, InlineVar, Primitive, Next, false, 1},
{"stloc", Pop1, Push0, InlineVar, Primitive, Next, false, -1},
{"localloc", Popi, Pushi, InlineNone, Primitive, Next, false, 0},
{"endfilter", Popi, Push0, InlineNone, Primitive, Return, true, -1},
{"unaligned.", Pop0, Push0, ShortInlineI, Prefix, Meta, false, 0},
{"volatile.", Pop0, Push0, InlineNone, Prefix, Meta, false, 0},
{"tail.", Pop0, Push0, InlineNone, Prefix, Meta, false, 0},
{"initobj", Popi, Push0, InlineType, Objmodel, Next, false, -1},
{"constrained.", Pop0, Push0, InlineType, Prefix, Meta, false, 0},
{"cpblk", Popi_popi_popi, Push0, InlineNone, Primitive, Next, false, -3},
{"initblk", Popi_popi_popi, Push0, InlineNone, Primitive, Next, false, -3},
{"no.", Pop0, Push0, InlineNone, Prefix, Meta, false, 0},
{"rethrow", Pop0, Push0, InlineNone, Objmodel, Throw, true, 0},
{"sizeof", Pop0, Pushi, InlineType, Primitive, Next, false, 1},
{"refanytype", Pop1, Pushi, InlineNone, Primitive, Next, false, 0},
{"readonly.", Pop0, Push0, InlineNone, Prefix, Meta, false, 0},
{"", Pop0, Push0, InlineNone, Primitive, Next, false, 0},
{"", Pop0, Push0, InlineNone, Primitive, Next, false, 0},
{"", Pop0, Push0, InlineNone, Primitive, Next, false, 0},
{"", Pop0, Push0, InlineNone, Primitive, Next, false, 0},
{"", Pop0, Push0, InlineNone, Primitive, Next, false, 0},
{"", Pop0, Push0, InlineNone, Primitive, Next, false, 0},
{"", Pop0, Push0, InlineNone, Primitive, Next, false, 0},
{"", Pop0, Push0, InlineNone, Primitive, Next, false, 0},
{"", Pop0, Push0, InlineNone, Primitive, Next, false, 0},
{"", Pop0, Push0, InlineNone, Primitive, Next, false, 0},
{"", Pop0, Push0, InlineNone, Primitive, Next, false, 0}
};
class TokenReference;
class ILCommand;
class ILVMCommand : public BaseVMCommand
{
public:
explicit ILVMCommand(ILCommand *owner, ILCommandType command_type, uint64_t value, TokenReference *token_reference);
virtual uint64_t address() const { return address_; }
virtual void set_address(uint64_t address) { address_ = address; }
virtual void Compile();
ILCommandType command_type() const { return command_type_; }
uint64_t value() const { return value_; }
void set_value(uint64_t value) { value_ = value; }
void set_dump(const Data &dump) { dump_ = dump; }
bool is_data() const { return (command_type_ == icByte || command_type_ == icWord || command_type_ == icDword); }
virtual bool is_end() const { return false; }
virtual void WriteToFile(IArchitecture &file);
virtual size_t dump_size() const { return dump_.size(); }
TokenReference *token_reference() const { return token_reference_; }
ILCommandType crypt_command() const { return crypt_command_; }
OperandSize crypt_size() const { return crypt_size_; }
uint64_t crypt_key() const { return crypt_key_; }
ILVMCommand *link_command() const { return link_command_; }
void set_token_reference(TokenReference *token_reference) { token_reference_ = token_reference; }
void set_crypt_command(ILCommandType crypt_command, OperandSize crypt_size, uint64_t crypt_key) { crypt_command_ = crypt_command; crypt_size_ = crypt_size; crypt_key_ = crypt_key; }
void set_link_command(ILVMCommand *command) { link_command_ = command; }
private:
uint64_t address_;
ILCommandType command_type_;
uint64_t value_;
Data dump_;
TokenReference *token_reference_;
ILCommandType crypt_command_;
OperandSize crypt_size_;
uint64_t crypt_key_;
ILVMCommand *link_command_;
};
class ILCommand: public BaseCommand
{
public:
explicit ILCommand(IFunction *owner, OperandSize size, ILCommandType type, uint64_t operand_value, IFixup *fixup = NULL);
explicit ILCommand(IFunction *owner, OperandSize size, uint64_t address = 0);
explicit ILCommand(IFunction *owner, OperandSize size, const std::string &value);
explicit ILCommand(IFunction *owner, OperandSize size, const Data &value);
explicit ILCommand(IFunction *owner, const ILCommand &source);
void Init(ILCommandType type, uint64_t operand_value = 0, TokenReference *token_reference = NULL);
virtual void clear();
ILVMCommand *item(size_t index) const { return reinterpret_cast<ILVMCommand *>(BaseCommand::item(index)); }
virtual uint64_t ext_vm_address() const { return (ext_vm_entry_) ? ext_vm_entry_->address() : vm_address(); }
virtual ISEHandler *seh_handler() const;
virtual void set_seh_handler(ISEHandler *handler);
virtual uint64_t address() const { return address_; }
virtual CommandType type() const { return type_; }
virtual std::string text() const;
virtual uint32_t section_options() const { return section_options_; }
virtual void include_section_option(SectionOption option) { section_options_ |= option; }
virtual void exclude_section_option(SectionOption option) { section_options_ &= ~option; }
virtual size_t original_dump_size() const { return (original_dump_size_) ? original_dump_size_ : dump_size(); }
virtual void CompileToNative();
virtual void CompileLink(const CompileContext &ctx);
virtual void PrepareLink(const CompileContext &ctx);
virtual void set_operand_value(size_t operand_index, uint64_t value);
virtual void set_link_value(size_t link_index, uint64_t value);
virtual void set_jmp_value(size_t link_index, uint64_t value) {};
virtual void set_address(uint64_t address);
void set_operand_fixup(IFixup *fixup);
virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file);
virtual void Rebase(uint64_t delta_base);
virtual ILCommand *Clone(IFunction *owner) const;
virtual bool Merge(ICommand *command);
void InitUnknown();
void InitComment(const std::string &comment);
virtual bool is_data() const;
virtual bool is_end() const;
bool is_prefix() const;
virtual std::string display_address() const;
virtual std::string dump_str() const;
OperandSize size() const { return size_; }
virtual CommentInfo comment();
size_t ReadFromFile(IArchitecture & file);
void WriteToFile(IArchitecture &file);
uint64_t operand_value() const { return operand_value_; }
size_t operand_pos() const { return operand_pos_; }
uint64_t ReadValueFromFile(IArchitecture &file, OperandSize value_size, bool is_token = false);
void ReadString(IArchitecture &file, size_t len);
void ReadCaseCommand(IArchitecture &file);
TokenReference *token_reference() const { return token_reference_; }
void set_token_reference(TokenReference *token_reference) { token_reference_ = token_reference; }
void CompileToVM(const CompileContext &ctx);
ILVMCommand *AddVMCommand(const CompileContext &ctx, ILCommandType command_type, uint64_t value, uint32_t options = 0, TokenReference *token_reference = NULL, ILCommand *to_command = NULL);
void AddExtSection(const CompileContext &ctx);
void set_param(uint32_t param) { param_ = param; }
int GetStackLevel(size_t *pop_ref = NULL) const;
private:
void AddCmpSection(const CompileContext &ctx, ILCommandType jmp_command);
void AddJmpWithFlagSection(const CompileContext &ctx, bool is_true);
void AddCryptorSection(const CompileContext &ctx, ValueCryptor *cryptor, bool is_decrypt);
uint64_t address_;
OperandSize size_;
ILCommandType type_;
uint64_t operand_value_;
size_t original_dump_size_;
uint32_t section_options_;
size_t operand_pos_;
TokenReference *token_reference_;
std::vector<ILVMCommand *> vm_links_;
InternalLinkList internal_links_;
ILVMCommand *ext_vm_entry_;
uint32_t param_;
IFixup *fixup_;
};
class ILFunction : public BaseFunction
{
public:
explicit ILFunction(IFunctionList *owner, const FunctionName &name, CompilationType compilation_type, uint32_t compilation_options, bool need_compile, Folder *folder);
explicit ILFunction(IFunctionList *owner = NULL);
explicit ILFunction(IFunctionList *owner, OperandSize cpu_address_size, IFunction *parent = NULL);
explicit ILFunction(IFunctionList *owner, const ILFunction &src);
virtual ILFunction *Clone(IFunctionList *owner) const;
ILCommand *item(size_t index) const { return reinterpret_cast<ILCommand *>(IFunction::item(index)); }
virtual bool Compile(const CompileContext &ctx);
virtual void AfterCompile(const CompileContext &ctx);
virtual void CompileLinks(const CompileContext &ctx);
virtual bool Prepare(const CompileContext &ctx);
virtual void CompileInfo(const CompileContext &ctx);
ILCommand *AddCommand(OperandSize value_size, uint64_t value);
ILCommand *AddCommand(const std::string &value);
ILCommand *AddCommand(const Data &value);
ILCommand *AddCommand(ILCommandType type, uint64_t operand_value, IFixup *fixup = NULL);
ILCommand *Add(uint64_t address);
ILCommand *GetCommandByAddress(uint64_t address) const;
ILCommand *GetCommandByNearAddress(uint64_t address) const;
virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file);
virtual ILCommand *ParseCommand(IArchitecture &file, uint64_t address, bool dump_mode = false);
void CreateBlocks();
protected:
virtual ILCommand *CreateCommand();
virtual ILCommand *ParseString(IArchitecture &file, uint64_t address, size_t len);
virtual void ParseBeginCommands(IArchitecture &file);
virtual void ParseEndCommands(IArchitecture &file);
virtual IFunction *CreateFunction(IFunction *parent) { return new ILFunction(NULL, cpu_address_size(), parent); }
void CalcStack(std::map<ILCommand *, int> &stack_map);
void Mutate(const CompileContext &ctx);
void CompileToNative(const CompileContext &ctx);
void CompileToVM(const CompileContext &ctx);
};
class ILFileHelper : public IObject
{
public:
explicit ILFileHelper();
~ILFileHelper();
void Parse(NETArchitecture &file);
private:
void AddString(NETArchitecture &file, uint32_t token, uint64_t reference);
std::vector<MapFunction *> string_list_;
MapFunctionList *marker_name_list_;
size_t marker_index_;
// no copy ctr or assignment op
ILFileHelper(const ILFileHelper &);
ILFileHelper &operator =(const ILFileHelper &);
};
class ILCommandBlock;
class ILToken;
class ILMethodDef;
class ILCommandNode : public IObject
{
public:
ILCommandNode(ILCommandBlock *owner, ILCommand *command);
~ILCommandNode();
ILCommand *command() const { return command_; }
std::vector<ILCommandNode*> stack() const { return stack_; }
void set_stack(std::vector<ILCommandNode*> &stack) { stack_ = stack; }
std::string token_name() const;
private:
ILCommandBlock *owner_;
ILCommand *command_;
std::vector<ILCommandNode*> stack_;
};
class ILCommandBlock : public ObjectList<ILCommandNode>
{
public:
ILCommandBlock();
bool Parse(ILFunction &func);
ILCommandNode *GetNodeByCommand(ILCommand *command) const;
ILToken *GetTypeOf(ILCommandNode *node) const;
ILToken *GetTypeFromStack(ILCommandNode *node) const;
protected:
void AddObject(ILCommandNode *node);
private:
ILCommandNode *Add(ILCommand *command);
std::map<ILCommand *, ILCommandNode *> map_;
ILMethodDef *method_;
};
class NETLoader : public ILFunction
{
public:
explicit NETLoader(IFunctionList *owner, OperandSize cpu_address_size);
virtual bool Prepare(const CompileContext &ctx);
virtual bool Compile(const CompileContext &ctx);
virtual size_t WriteToFile(IArchitecture &file);
ILCommand *file_crc_entry() const { return file_crc_entry_; }
uint32_t file_crc_size() const { return file_crc_size_; }
ILCommand *file_crc_size_entry() const { return file_crc_size_entry_; }
ILCommand *loader_crc_entry() const { return loader_crc_entry_; }
uint32_t loader_crc_size() const { return loader_crc_size_; }
ILCommand *loader_crc_size_entry() const { return loader_crc_size_entry_; }
ILCommand *loader_crc_hash_entry() const { return loader_crc_hash_entry_; }
ILCommand *import_entry() const { return import_entry_; }
uint32_t import_size() const { return import_size_; }
ILCommand *iat_entry() const { return iat_entry_; }
uint32_t iat_size() const { return iat_size_; }
ILCommand *pe_entry() const { return pe_entry_; }
ILCommand *strong_name_signature_entry() const { return strong_name_signature_entry_; }
ILCommand *vtable_fixups_entry() const { return vtable_fixups_entry_; }
ILCommand *tls_entry() const { return tls_entry_; }
uint32_t tls_size() const { return tls_size_; }
private:
void AddAVBuffer(const CompileContext &ctx);
struct ImportInfo {
ILCommand *original_first_thunk;
ILCommand *name;
ILCommand *first_thunk;
//IntelCommand *loader_name;
};
struct ImportFunctionInfo {
PEImportFunction *import_function;
ILCommand *name;
ILCommand *thunk;
ILCommand *loader_name;
ImportFunctionInfo(PEImportFunction *import_function_)
: import_function(import_function_), name(NULL), thunk(NULL), loader_name(NULL) {}
bool operator == (PEImportFunction *import_function_) const
{
return (import_function == import_function_);
}
};
struct LoaderInfo {
ILCommand *data;
size_t size;
LoaderInfo(ILCommand *data_, size_t size_)
: data(data_), size(size_) {}
};
struct PackerInfo {
PESegment *section;
uint64_t address;
size_t size;
ILCommand *data;
bool operator == (PESegment *section_) const
{
return (section == section_);
}
};
ILCommand *import_entry_;
uint32_t import_size_;
ILCommand *iat_entry_;
uint32_t iat_size_;
ILCommand *file_crc_entry_;
ILCommand *file_crc_size_entry_;
uint32_t file_crc_size_;
ILCommand *loader_crc_entry_;
ILCommand *loader_crc_size_entry_;
ILCommand *loader_crc_hash_entry_;
uint32_t loader_crc_size_;
ILCommand *pe_entry_;
ILCommand *strong_name_signature_entry_;
ILCommand *vtable_fixups_entry_;
ILCommand *tls_entry_;
ILCommand *tls_call_back_entry_;
uint32_t tls_size_;
};
class ILSDK : public ILFunction
{
public:
explicit ILSDK(IFunctionList *owner, OperandSize cpu_address_size);
bool Init(const CompileContext &ctx);
};
class ILCRCTable : public ILFunction
{
public:
explicit ILCRCTable(IFunctionList *owner, OperandSize cpu_address_size);
bool Init(const CompileContext &ctx);
size_t table_size() const { return (count() - 2) * OperandSizeToValue(osDWord); }
ILCommand *table_entry() const { return item(0); }
ILCommand *size_entry() const { return size_entry_; }
ILCommand *hash_entry() const { return hash_entry_; }
private:
ILCommand *size_entry_;
ILCommand *hash_entry_;
};
class ILRuntimeData : public ILFunction
{
public:
explicit ILRuntimeData(IFunctionList *owner, OperandSize cpu_address_size);
bool Init(const CompileContext &ctx);
virtual size_t WriteToFile(IArchitecture &file);
private:
struct CommandCompareHelper {
bool operator () (const ILCommand *left, ILCommand *right) const;
};
RC5Key rc5_key_;
ILCommand *resources_entry_;
uint32_t resources_size_;
ILCommand *strings_entry_;
uint32_t strings_size_;
ILCommand *trial_hwid_entry_;
uint32_t trial_hwid_size_;
#ifdef ULTIMATE
ILCommand *license_data_entry_;
uint32_t license_data_size_;
#endif
};
class ILRuntimeCRCTable : public ILFunction
{
public:
explicit ILRuntimeCRCTable(IFunctionList *owner, OperandSize cpu_address_size);
virtual void clear();
virtual bool Compile(const CompileContext &ctx);
virtual size_t WriteToFile(IArchitecture &file);
size_t region_count() const { return region_info_list_.size(); }
private:
struct RegionInfo {
uint64_t address;
uint32_t size;
bool is_self_crc;
RegionInfo(uint64_t address_, uint32_t size_, bool is_self_crc_)
: address(address_), size(size_), is_self_crc(is_self_crc_)
{
}
};
std::vector<RegionInfo> region_info_list_;
ValueCryptor *cryptor_;
};
class ILToken;
struct ImportDelegateInfo
{
ILToken *method;
ILToken *invoke;
uint32_t call_type;
ImportDelegateInfo(ILToken *method_, ILToken *invoke_, uint32_t call_type_)
: method(method_), invoke(invoke_), call_type(call_type_)
{
}
};
class ILImport : public ILFunction
{
public:
explicit ILImport(IFunctionList *owner, OperandSize cpu_address_size);
bool Init(const CompileContext &ctx);
std::vector<ImportDelegateInfo> info_list() const { return info_list_; }
private:
std::vector<ImportDelegateInfo> info_list_;
};
class ILVirtualMachineProcessor;
class ILFunctionList : public BaseFunctionList
{
public:
explicit ILFunctionList(IArchitecture *owner);
explicit ILFunctionList(IArchitecture *owner, const ILFunctionList &src);
~ILFunctionList();
ILFunction *item(size_t index) const;
ILFunction *GetFunctionByAddress(uint64_t address) const;
virtual bool Prepare(const CompileContext &ctx);
virtual bool Compile(const CompileContext &ctx);
virtual void CompileLinks(const CompileContext &ctx);
virtual void CompileInfo(const CompileContext &ctx);
virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file);
virtual ILFunction *Add(const std::string &name, CompilationType compilation_type, uint32_t compilation_options, bool need_compile, Folder *folder);
virtual ILFunctionList *Clone(IArchitecture *owner) const;
virtual ILCRCTable *crc_table() const { return crc_table_; }
virtual ValueCryptor *crc_cryptor() const { return crc_cryptor_; }
ILImport *import() const { return import_; }
ILRuntimeCRCTable *runtime_crc_table() const { return runtime_crc_table_; }
virtual IFunction *CreateFunction(OperandSize cpu_address_size = osDefault);
virtual bool GetRuntimeOptions() const { return true; }
ILVirtualMachineProcessor *AddProcessor(OperandSize cpu_address_size);
protected:
ILSDK *AddSDK(OperandSize cpu_address_size);
ILRuntimeData *AddRuntimeData(OperandSize cpu_address_size);
ILCRCTable *AddCRCTable(OperandSize cpu_address_size);
ILFunction *AddWatermark(OperandSize cpu_address_size, Watermark *watermark, int copy_count);
ILRuntimeCRCTable *AddRuntimeCRCTable(OperandSize cpu_address_size);
ILImport *AddImport(OperandSize cpu_address_size);
ValueCryptor *crc_cryptor_;
ILCRCTable *crc_table_;
ILRuntimeCRCTable *runtime_crc_table_;
ILImport *import_;
// no copy ctr or assignment op
ILFunctionList(const ILFunctionList &);
ILFunctionList &operator =(const ILFunctionList &);
};
class ILVirtualMachineProcessor : public ILFunction
{
public:
ILVirtualMachineProcessor(ILFunctionList *owner, OperandSize cpu_address_size);
void InitCommands(const CompileContext &ctx);
virtual void AfterCompile(const CompileContext &ctx);
virtual void CompileLinks(const CompileContext &ctx);
virtual void CompileInfo(const CompileContext &ctx);
virtual size_t WriteToFile(IArchitecture &file);
};
class ILVirtualMachineList : public IVirtualMachineList
{
public:
virtual IVirtualMachineList * Clone() const;
virtual void Prepare(const CompileContext &ctx);
virtual IFunction *processor() const { return NULL; }
};
class ILOpcodeList;
class ILToken;
class ILOpcodeInfo : public IObject
{
public:
ILOpcodeInfo(ILOpcodeList *owner, ILCommandType command_type, ILToken *entry);
~ILOpcodeInfo();
ILCommandType command_type() const { return command_type_; }
ILToken *entry() const { return entry_; }
uint8_t opcode() const { return opcode_; }
void set_opcode(uint8_t opcode) { opcode_ = opcode; }
uint64_t Key() const { return command_type_; }
class circular_queue : public std::vector<ILOpcodeInfo *>
{
size_t position_;
public:
circular_queue() : std::vector<ILOpcodeInfo *>(), position_(0) {}
ILOpcodeInfo *Next();
};
private:
ILOpcodeList *owner_;
ILCommandType command_type_;
ILToken *entry_;
uint8_t opcode_;
};
class ILOpcodeList : public ObjectList<ILOpcodeInfo>
{
public:
ILOpcodeList();
ILOpcodeInfo *Add(ILCommandType command_type, ILToken *entry);
ILOpcodeInfo *GetOpcodeInfo(ILCommandType command_type) const;
};
class ILMethodDef;
class ILVirtualMachine : public BaseVirtualMachine
{
public:
ILVirtualMachine(ILVirtualMachineList *owner, uint8_t id, ILVirtualMachineProcessor *processor);
void Init(const CompileContext &ctx);
virtual ByteList *registr_order() { return NULL; }
virtual bool backward_direction() const { return false; }
virtual ILFunction *processor() const { return processor_; }
ILMethodDef *ctor() const { return ctor_; }
ILMethodDef *invoke() const { return invoke_; }
void CompileCommand(ILVMCommand &vm_command);
private:
ILOpcodeInfo *GetOpcode(ILCommandType command_type);
ILVirtualMachineProcessor *processor_;
ILMethodDef *ctor_;
ILMethodDef *invoke_;
ILOpcodeList opcode_list_;
std::unordered_map<uint64_t, ILOpcodeInfo::circular_queue> opcode_stack_;
};
#endif