and you thought you'd never see the day.. sysreq.n verified!

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40117
This commit is contained in:
David Anderson 2006-10-11 23:47:04 +00:00
parent c06a526165
commit fb7942ee4d
7 changed files with 162 additions and 300 deletions

View File

@ -60,20 +60,24 @@ inline void WriteOp_Zero(JitWriter *jit)
//mov [ebp+<val>], 0 //mov [ebp+<val>], 0
cell_t val = jit->read_cell(); cell_t val = jit->read_cell();
if (val < SCHAR_MAX && val > SCHAR_MIN) if (val < SCHAR_MAX && val > SCHAR_MIN)
{
IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_DAT, 0, (jit_int8_t)val); IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_DAT, 0, (jit_int8_t)val);
else } else {
IA32_Mov_Rm_Imm32_Disp32(jit, AMX_REG_DAT, 0, val); IA32_Mov_Rm_Imm32_Disp32(jit, AMX_REG_DAT, 0, val);
} }
}
inline void WriteOp_Zero_S(JitWriter *jit) inline void WriteOp_Zero_S(JitWriter *jit)
{ {
//mov [ebx+<val>], 0 //mov [ebx+<val>], 0
cell_t val = jit->read_cell(); cell_t val = jit->read_cell();
if (val < SCHAR_MAX && val > SCHAR_MIN) if (val < SCHAR_MAX && val > SCHAR_MIN)
{
IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_FRM, 0, (jit_int8_t)val); IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_FRM, 0, (jit_int8_t)val);
else } else {
IA32_Mov_Rm_Imm32_Disp32(jit, AMX_REG_FRM, 0, val); IA32_Mov_Rm_Imm32_Disp32(jit, AMX_REG_FRM, 0, val);
} }
}
inline void WriteOp_Push_S(JitWriter *jit) inline void WriteOp_Push_S(JitWriter *jit)
{ {
@ -85,9 +89,11 @@ inline void WriteOp_Push_S(JitWriter *jit)
IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG); IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
//optimize encoding a bit... //optimize encoding a bit...
if (val < SCHAR_MAX && val > SCHAR_MIN) if (val < SCHAR_MAX && val > SCHAR_MIN)
{
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_FRM, (jit_int8_t)val); IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_FRM, (jit_int8_t)val);
else } else {
IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val); IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val);
}
IA32_Mov_Rm_Reg(jit, AMX_REG_STK, AMX_REG_TMP, MOD_MEM_REG); IA32_Mov_Rm_Reg(jit, AMX_REG_STK, AMX_REG_TMP, MOD_MEM_REG);
} }
@ -1406,8 +1412,14 @@ inline void WriteOp_Sysreq_N_NoInline(JitWriter *jit)
/* store the number of parameters on the stack, /* store the number of parameters on the stack,
* and store the native index as well. * and store the native index as well.
*/ */
cell_t num_params = jit->read_cell();
cell_t native_index = jit->read_cell(); cell_t native_index = jit->read_cell();
cell_t num_params = jit->read_cell();
if ((uint32_t)native_index >= ((CompData*)jit->data)->plugin->info.natives_num)
{
((CompData *)jit->data)->error_set = SP_ERR_INSTRUCTION_PARAM;
return;
}
//mov eax, <num_params> //mov eax, <num_params>
//mov ecx, <native_index> //mov ecx, <native_index>
@ -1421,10 +1433,16 @@ inline void WriteOp_Sysreq_N_NoInline(JitWriter *jit)
inline void WriteOp_Sysreq_N(JitWriter *jit) inline void WriteOp_Sysreq_N(JitWriter *jit)
{ {
/* The big daddy of opcodes. */ /* The big daddy of opcodes. */
cell_t num_params = jit->read_cell();
cell_t native_index = jit->read_cell(); cell_t native_index = jit->read_cell();
cell_t num_params = jit->read_cell();
CompData *data = (CompData *)jit->data; CompData *data = (CompData *)jit->data;
if ((uint32_t)native_index >= data->plugin->info.natives_num)
{
data->error_set = SP_ERR_INSTRUCTION_PARAM;
return;
}
/* store the number of parameters on the stack */ /* store the number of parameters on the stack */
//mov [edi-4], num_params //mov [edi-4], num_params
//sub edi, 4 //sub edi, 4
@ -1463,7 +1481,15 @@ inline void WriteOp_Sysreq_N(JitWriter *jit)
//call NativeCallback //call NativeCallback
IA32_Push_Reg(jit, REG_EAX); IA32_Push_Reg(jit, REG_EAX);
jitoffs_t call = IA32_Call_Imm32(jit, 0); jitoffs_t call = IA32_Call_Imm32(jit, 0);
IA32_Write_Jump32(jit, call, (jitoffs_t)(char *)&NativeCallback); IA32_Write_Jump32_Abs(jit, call, NativeCallback);
/* check for errors */
//mov ecx, [esi+context]
//cmp [ecx+err], 0
//jnz :error
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
IA32_Cmp_Rm_Imm32_Disp8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
/* restore what we damaged */ /* restore what we damaged */
//add esp, 4*3 //add esp, 4*3
@ -1473,12 +1499,6 @@ inline void WriteOp_Sysreq_N(JitWriter *jit)
IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG); IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
IA32_Pop_Reg(jit, AMX_REG_ALT); IA32_Pop_Reg(jit, AMX_REG_ALT);
/* check for errors */
//test eax, eax
//jne :error
IA32_Test_Rm_Reg(jit, REG_EAX, REG_EAX, MOD_REG);
IA32_Jump_Cond_Imm32_Abs(jit, CC_NE, data->jit_return);
/* pop the stack. do not check the margins. /* pop the stack. do not check the margins.
* Note that this is not a true macro - we don't bother to * Note that this is not a true macro - we don't bother to
* set ALT here because nothing will be using it. * set ALT here because nothing will be using it.
@ -1503,11 +1523,18 @@ inline void WriteOp_Sysreq_N(JitWriter *jit)
cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params) cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
{ {
/* :TODO: fill this out... */ sp_native_t *native = &ctx->natives[native_idx];
/* Technically both aren't needed, I guess */
if (native->status == SP_NATIVE_NONE)
{
ctx->err = SP_ERR_NATIVE_PENDING;
return 0; return 0;
} }
return native->pfn(ctx, params);
}
jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative) jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative)
{ {
if (jit->outptr) if (jit->outptr)
@ -1529,6 +1556,33 @@ jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative)
} }
} }
void WriteErrorRoutines(CompData *data, JitWriter *jit)
{
data->jit_error_divzero = jit->get_outputpos();
Write_SetError(jit, SP_ERR_DIVIDE_BY_ZERO);
data->jit_error_stacklow = jit->get_outputpos();
Write_SetError(jit, SP_ERR_STACKLOW);
data->jit_error_stackmin = jit->get_outputpos();
Write_SetError(jit, SP_ERR_STACKMIN);
data->jit_error_bounds = jit->get_outputpos();
Write_SetError(jit, SP_ERR_ARRAY_BOUNDS);
data->jit_error_memaccess = jit->get_outputpos();
Write_SetError(jit, SP_ERR_MEMACCESS);
data->jit_error_heaplow = jit->get_outputpos();
Write_SetError(jit, SP_ERR_HEAPLOW);
data->jit_error_heapmin = jit->get_outputpos();
Write_SetError(jit, SP_ERR_HEAPMIN);
data->jit_extern_error = jit->get_outputpos();
Write_GetError(jit);
}
sp_context_t *JITX86::CompileToContext(ICompilation *co, int *err) sp_context_t *JITX86::CompileToContext(ICompilation *co, int *err)
{ {
CompData *data = (CompData *)co; CompData *data = (CompData *)co;
@ -1536,61 +1590,17 @@ sp_context_t *JITX86::CompileToContext(ICompilation *co, int *err)
/* The first phase is to browse */ /* The first phase is to browse */
uint8_t *code = plugin->pcode; uint8_t *code = plugin->pcode;
uint8_t *cip;
uint8_t *end_cip = plugin->pcode + plugin->pcode_size; uint8_t *end_cip = plugin->pcode + plugin->pcode_size;
OPCODE op; OPCODE op;
int op_c;
/* FIRST PASS (light load) - Get initial opcode information
* :TODO: remove this pass soon, it's not needed anymore!
*/
for (cip = code; cip < end_cip;)
{
op = (OPCODE)*(ucell_t *)cip;
if ((unsigned)op >= OP_NUM_OPCODES)
{
AbortCompilation(co);
*err = SP_ERR_INVALID_INSTRUCTION;
return NULL;
}
cip += sizeof(cell_t);
op_c = OpAdvTable[op];
if (op_c >= 0)
{
cip += op_c;
} else if (op_c == -3) {
AbortCompilation(co);
*err = SP_ERR_INVALID_INSTRUCTION;
return NULL;
} else if (op_c == -1) {
switch (op)
{
case OP_CASETBL:
{
ucell_t num = *(ucell_t *)cip;
cip += sizeof(cell_t);
cip += ((2*num) + 1) * sizeof(cell_t);
break;
}
default:
{
AbortCompilation(co);
*err = SP_ERR_INVALID_INSTRUCTION;
return NULL;
}
}
}
}
/********************************************* /*********************************************
* SECOND PASS (medium load): writer.outbase is NULL, getting size only * FIRST PASS (medium load): writer.outbase is NULL, getting size only
* THIRD PASS (heavy load!!): writer.outbase is valid and output is written * SECOND PASS (heavy load!!): writer.outbase is valid and output is written
*********************************************/ *********************************************/
JitWriter writer; JitWriter writer;
JitWriter *jit = &writer; JitWriter *jit = &writer;
cell_t *endptr = (cell_t *)(end_cip); cell_t *endptr = (cell_t *)(end_cip);
cell_t jitpos;
/* Initial code is written "blank," /* Initial code is written "blank,"
* so we can check the exact memory usage. * so we can check the exact memory usage.
@ -1602,58 +1612,37 @@ sp_context_t *JITX86::CompileToContext(ICompilation *co, int *err)
writer.outbase = NULL; writer.outbase = NULL;
data->rebase = (jitcode_t)engine->BaseAlloc(plugin->pcode_size); data->rebase = (jitcode_t)engine->BaseAlloc(plugin->pcode_size);
/* Jump back here for second pass */ /* We will jump back here for second pass */
jit_rewind: jit_rewind:
/* Initialize pass vars */ /* Initialize pass vars */
writer.inptr = writer.inbase; writer.inptr = writer.inbase;
data->jit_verify_addr_eax = 0; data->jit_verify_addr_eax = 0;
data->jit_verify_addr_edx = 0; data->jit_verify_addr_edx = 0;
/* Start writing the actual code */ /* Write the prologue of the JIT */
data->jit_return = Write_Execute_Function(jit); data->jit_return = Write_Execute_Function(jit);
/* Write error checking routines that are jumped to */ /* Write the SYSREQ.N opcode if we need to */
if (!(data->inline_level & JIT_INLINE_ERRORCHECKS)) if (!(data->inline_level & JIT_INLINE_NATIVES))
{ {
jitpos = jit->get_outputpos(); data->jit_sysreq_n = jit->get_outputpos();
Write_Check_VerifyAddr(jit, REG_EAX); WriteOp_Sysreq_N_Function(jit);
data->jit_verify_addr_eax = jitpos;
jitpos = jit->get_outputpos();
Write_Check_VerifyAddr(jit, REG_EDX);
data->jit_verify_addr_edx = jitpos;
} }
/* Write error codes we need */ /* Write error checking routines that are called to */
if (!(data->inline_level & JIT_INLINE_ERRORCHECKS))
{ {
data->jit_error_divzero = jit->get_outputpos(); data->jit_verify_addr_eax = jit->get_outputpos();
Write_SetError(jit, true, SP_ERR_DIVIDE_BY_ZERO); Write_Check_VerifyAddr(jit, REG_EAX);
data->jit_error_stacklow = jit->get_outputpos(); data->jit_verify_addr_edx = jit->get_outputpos();
Write_SetError(jit, true, SP_ERR_STACKLOW); Write_Check_VerifyAddr(jit, REG_EDX);
data->jit_error_stackmin = jit->get_outputpos();
Write_SetError(jit, true, SP_ERR_STACKMIN);
data->jit_error_bounds = jit->get_outputpos();
Write_SetError(jit, true, SP_ERR_ARRAY_BOUNDS);
data->jit_error_memaccess = jit->get_outputpos();
Write_SetError(jit, true, SP_ERR_MEMACCESS);
data->jit_error_heaplow = jit->get_outputpos();
Write_SetError(jit, true, SP_ERR_HEAPLOW);
data->jit_error_heapmin = jit->get_outputpos();
Write_SetError(jit, true, SP_ERR_HEAPMIN);
} }
/* Actual code generation! */ /* Actual code generation! */
if (writer.outbase == NULL) if (writer.outbase == NULL)
{ {
/******* /* First Pass - find codesize and resolve relocation */
* SECOND PASS - get opcode sizes+info
*******/
jitoffs_t pcode_offs; jitoffs_t pcode_offs;
jitoffs_t native_offs; jitoffs_t native_offs;
@ -1673,7 +1662,16 @@ jit_rewind:
{ {
#include "opcode_switch.inc" #include "opcode_switch.inc"
} }
/* Check for errors. This should only happen in the first pass. */
if (data->error_set != SP_ERR_NONE)
{
*err = data->error_set;
AbortCompilation(co);
return NULL;
} }
}
/* Write these last because error jumps should be unpredicted, and thus forward */
WriteErrorRoutines(data, jit);
/* the total codesize is now known! */ /* the total codesize is now known! */
uint32_t mem = writer.get_outputpos(); uint32_t mem = writer.get_outputpos();
@ -1693,6 +1691,8 @@ jit_rewind:
#include "opcode_switch.inc" #include "opcode_switch.inc"
} }
} }
/* Write these last because error jumps should be unpredicted, and thus forward */
WriteErrorRoutines(data, jit);
} }
/************* /*************
@ -1810,8 +1810,7 @@ jit_rewind:
} }
/* clean up relocation+compilation memory */ /* clean up relocation+compilation memory */
engine->BaseFree(data->rebase); AbortCompilation(co);
delete data;
*err = SP_ERR_NONE; *err = SP_ERR_NONE;
@ -1848,13 +1847,18 @@ ICompilation *JITX86::StartCompilation(sp_plugin_t *plugin)
CompData *data = new CompData; CompData *data = new CompData;
data->plugin = plugin; data->plugin = plugin;
data->inline_level = JIT_INLINE_ERRORCHECKS; data->inline_level = JIT_INLINE_ERRORCHECKS|JIT_INLINE_NATIVES;
data->error_set = SP_ERR_NONE;
return data; return data;
} }
void JITX86::AbortCompilation(ICompilation *co) void JITX86::AbortCompilation(ICompilation *co)
{ {
if (((CompData *)co)->rebase)
{
engine->BaseFree(((CompData *)co)->rebase);
}
delete (CompData *)co; delete (CompData *)co;
} }

View File

@ -33,15 +33,15 @@ public:
jitoffs_t jit_error_memaccess; jitoffs_t jit_error_memaccess;
jitoffs_t jit_error_heaplow; jitoffs_t jit_error_heaplow;
jitoffs_t jit_error_heapmin; jitoffs_t jit_error_heapmin;
jitoffs_t jit_extern_error;
uint32_t codesize; uint32_t codesize;
int inline_level; int inline_level;
int error_set;
bool debug; bool debug;
}; };
class JITX86 : public IVirtualMachine class JITX86 : public IVirtualMachine
{ {
public:
JITX86();
public: public:
const char *GetVMName(); const char *GetVMName();
ICompilation *StartCompilation(sp_plugin_t *plugin); ICompilation *StartCompilation(sp_plugin_t *plugin);

View File

@ -4,8 +4,6 @@
#include "opcode_helpers.h" #include "opcode_helpers.h"
#include "x86_macros.h" #include "x86_macros.h"
int OpAdvTable[OP_NUM_OPCODES];
#define NUM_INFO_PARAMS 7 #define NUM_INFO_PARAMS 7
jitoffs_t Write_Execute_Function(JitWriter *jit) jitoffs_t Write_Execute_Function(JitWriter *jit)
@ -165,16 +163,26 @@ void Write_BreakDebug(JitWriter *jit)
IA32_Return(jit); IA32_Return(jit);
} }
void Write_SetError(JitWriter *jit, bool always_inline, int error) void Write_GetError(JitWriter *jit)
{
CompData *data = (CompData *)jit->data;
//mov eax, [esi+info.context]
//mov eax, [eax+ctx.error]
//jmp [jit_return]
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EAX, offsetof(sp_context_t, err));
IA32_Jump_Imm32_Abs(jit, data->jit_return);
}
void Write_SetError(JitWriter *jit, int error)
{ {
CompData *data = (CompData *)jit->data; CompData *data = (CompData *)jit->data;
/* These are so small that we always inline them! */
//mov eax, <error> //mov eax, <error>
//jmp [...jit_return] //jmp [jit_return]
IA32_Mov_Reg_Imm32(jit, REG_EAX, error); IA32_Mov_Reg_Imm32(jit, REG_EAX, error);
jitoffs_t jmp = IA32_Jump_Imm32(jit, 0); IA32_Jump_Imm32_Abs(jit, data->jit_return);
IA32_Write_Jump32(jit, jmp, data->jit_return);
} }
void Write_Check_DivZero(JitWriter *jit, jit_uint8_t reg) void Write_Check_DivZero(JitWriter *jit, jit_uint8_t reg)
@ -426,11 +434,18 @@ void WriteOp_Sysreq_N_Function(JitWriter *jit)
/* finally, push the last parameter and make the call */ /* finally, push the last parameter and make the call */
//push eax ; context //push eax ; context
//mov eax, [eax+context]
//call NativeCallback //call NativeCallback
IA32_Push_Reg(jit, REG_EAX); IA32_Push_Reg(jit, REG_EAX);
jitoffs_t call = IA32_Call_Imm32(jit, 0); jitoffs_t call = IA32_Call_Imm32(jit, 0);
IA32_Write_Jump32(jit, call, (jitoffs_t)(char *)&NativeCallback); IA32_Write_Jump32_Abs(jit, call, (void *)&NativeCallback);
/* Test for error */
//mov ecx, [esi+context]
//cmp [ecx+err], 0
//jnz :error
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
IA32_Cmp_Rm_Imm32_Disp8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
/* restore what we damaged */ /* restore what we damaged */
//add esp, 4*3 //add esp, 4*3
@ -442,12 +457,6 @@ void WriteOp_Sysreq_N_Function(JitWriter *jit)
IA32_Pop_Reg(jit, AMX_REG_ALT); IA32_Pop_Reg(jit, AMX_REG_ALT);
IA32_Pop_Reg(jit, REG_ECX); IA32_Pop_Reg(jit, REG_ECX);
//Note: always safe, we're in a call
//test eax, eax
//jne :error
IA32_Test_Rm_Reg(jit, REG_EAX, REG_EAX, MOD_REG);
IA32_Jump_Cond_Imm32_Abs(jit, CC_NE, data->jit_return);
/* pop the AMX stack. do not check the margins. /* pop the AMX stack. do not check the margins.
* Note that this is not a true macro - we don't bother to * Note that this is not a true macro - we don't bother to
* set ALT here because nothing will be using it. * set ALT here because nothing will be using it.
@ -459,183 +468,3 @@ void WriteOp_Sysreq_N_Function(JitWriter *jit)
IA32_Return(jit); IA32_Return(jit);
} }
JITX86::JITX86()
{
memset(OpAdvTable, -1, sizeof(OpAdvTable));
/* instructions with 5 parameters */
OpAdvTable[OP_PUSH5_C] = sizeof(cell_t)*5;
OpAdvTable[OP_PUSH5] = sizeof(cell_t)*5;
OpAdvTable[OP_PUSH5_S] = sizeof(cell_t)*5;
OpAdvTable[OP_PUSH5_ADR] = sizeof(cell_t)*5;
/* instructions with 4 parameters */
OpAdvTable[OP_PUSH4_C] = sizeof(cell_t)*4;
OpAdvTable[OP_PUSH4] = sizeof(cell_t)*4;
OpAdvTable[OP_PUSH4_S] = sizeof(cell_t)*4;
OpAdvTable[OP_PUSH4_ADR] = sizeof(cell_t)*4;
/* instructions with 3 parameters */
OpAdvTable[OP_PUSH3_C] = sizeof(cell_t)*3;
OpAdvTable[OP_PUSH3] = sizeof(cell_t)*3;
OpAdvTable[OP_PUSH3_S] = sizeof(cell_t)*3;
OpAdvTable[OP_PUSH3_ADR] = sizeof(cell_t)*3;
/* instructions with 2 parameters */
OpAdvTable[OP_PUSH2_C] = sizeof(cell_t)*2;
OpAdvTable[OP_PUSH2] = sizeof(cell_t)*2;
OpAdvTable[OP_PUSH2_S] = sizeof(cell_t)*2;
OpAdvTable[OP_PUSH2_ADR] = sizeof(cell_t)*2;
OpAdvTable[OP_LOAD_BOTH] = sizeof(cell_t)*2;
OpAdvTable[OP_LOAD_S_BOTH] = sizeof(cell_t)*2;
OpAdvTable[OP_CONST] = sizeof(cell_t)*2;
OpAdvTable[OP_CONST_S] = sizeof(cell_t)*2;
OpAdvTable[OP_SYSREQ_N] = sizeof(cell_t)*2;
/* instructions with 1 parameter */
OpAdvTable[OP_LOAD_PRI] = sizeof(cell_t);
OpAdvTable[OP_LOAD_ALT] = sizeof(cell_t);
OpAdvTable[OP_LOAD_S_PRI] = sizeof(cell_t);
OpAdvTable[OP_LOAD_S_ALT] = sizeof(cell_t);
OpAdvTable[OP_LREF_PRI] = sizeof(cell_t);
OpAdvTable[OP_LREF_ALT] = sizeof(cell_t);
OpAdvTable[OP_LREF_S_PRI] = sizeof(cell_t);
OpAdvTable[OP_LREF_S_ALT] = sizeof(cell_t);
OpAdvTable[OP_CONST_PRI] = sizeof(cell_t);
OpAdvTable[OP_CONST_ALT] = sizeof(cell_t);
OpAdvTable[OP_ADDR_PRI] = sizeof(cell_t);
OpAdvTable[OP_ADDR_ALT] = sizeof(cell_t);
OpAdvTable[OP_STOR_PRI] = sizeof(cell_t);
OpAdvTable[OP_STOR_ALT] = sizeof(cell_t);
OpAdvTable[OP_STOR_S_PRI] = sizeof(cell_t);
OpAdvTable[OP_STOR_S_ALT] = sizeof(cell_t);
OpAdvTable[OP_SREF_PRI] = sizeof(cell_t);
OpAdvTable[OP_SREF_ALT] = sizeof(cell_t);
OpAdvTable[OP_SREF_S_PRI] = sizeof(cell_t);
OpAdvTable[OP_SREF_S_ALT] = sizeof(cell_t);
OpAdvTable[OP_LIDX_B] = sizeof(cell_t);
OpAdvTable[OP_IDXADDR_B] = sizeof(cell_t);
OpAdvTable[OP_PUSH_C] = sizeof(cell_t);
OpAdvTable[OP_PUSH] = sizeof(cell_t);
OpAdvTable[OP_PUSH_S] = sizeof(cell_t);
OpAdvTable[OP_STACK] = sizeof(cell_t);
OpAdvTable[OP_HEAP] = sizeof(cell_t);
OpAdvTable[OP_SHL_C_PRI] = sizeof(cell_t);
OpAdvTable[OP_SHL_C_ALT] = sizeof(cell_t);
OpAdvTable[OP_SHR_C_PRI] = sizeof(cell_t);
OpAdvTable[OP_SHR_C_ALT] = sizeof(cell_t);
OpAdvTable[OP_ADD_C] = sizeof(cell_t);
OpAdvTable[OP_SMUL_C] = sizeof(cell_t);
OpAdvTable[OP_ZERO] = sizeof(cell_t);
OpAdvTable[OP_ZERO_S] = sizeof(cell_t);
OpAdvTable[OP_EQ_C_PRI] = sizeof(cell_t);
OpAdvTable[OP_EQ_C_ALT] = sizeof(cell_t);
OpAdvTable[OP_INC] = sizeof(cell_t);
OpAdvTable[OP_INC_S] = sizeof(cell_t);
OpAdvTable[OP_DEC] = sizeof(cell_t);
OpAdvTable[OP_DEC_S] = sizeof(cell_t);
OpAdvTable[OP_MOVS] = sizeof(cell_t);
OpAdvTable[OP_FILL] = sizeof(cell_t);
OpAdvTable[OP_HALT] = sizeof(cell_t);
OpAdvTable[OP_BOUNDS] = sizeof(cell_t);
OpAdvTable[OP_PUSH_ADR] = sizeof(cell_t);
OpAdvTable[OP_PUSH_HEAP_C] = sizeof(cell_t);
OpAdvTable[OP_SYSREQ_C] = sizeof(cell_t);
OpAdvTable[OP_CALL] = sizeof(cell_t);
OpAdvTable[OP_JUMP] = sizeof(cell_t);
OpAdvTable[OP_JZER] = sizeof(cell_t);
OpAdvTable[OP_JNZ] = sizeof(cell_t);
OpAdvTable[OP_JEQ] = sizeof(cell_t);
OpAdvTable[OP_JNEQ] = sizeof(cell_t);
OpAdvTable[OP_JSLESS] = sizeof(cell_t);
OpAdvTable[OP_JSLEQ] = sizeof(cell_t);
OpAdvTable[OP_JSGRTR] = sizeof(cell_t);
OpAdvTable[OP_JSGEQ] = sizeof(cell_t);
OpAdvTable[OP_SWITCH] = sizeof(cell_t);
/* instructions with 0 parameters */
OpAdvTable[OP_LOAD_I] = 0;
OpAdvTable[OP_STOR_I] = 0;
OpAdvTable[OP_LIDX] = 0;
OpAdvTable[OP_IDXADDR] = 0;
OpAdvTable[OP_MOVE_PRI] = 0;
OpAdvTable[OP_MOVE_ALT] = 0;
OpAdvTable[OP_XCHG] = 0;
OpAdvTable[OP_PUSH_PRI] = 0;
OpAdvTable[OP_PUSH_ALT] = 0;
OpAdvTable[OP_POP_PRI] = 0;
OpAdvTable[OP_POP_ALT] = 0;
OpAdvTable[OP_PROC] = 0;
OpAdvTable[OP_RET] = 0;
OpAdvTable[OP_RETN] = 0;
OpAdvTable[OP_CALL_PRI] = 0;
OpAdvTable[OP_SHL] = 0;
OpAdvTable[OP_SHR] = 0;
OpAdvTable[OP_SSHR] = 0;
OpAdvTable[OP_SMUL] = 0;
OpAdvTable[OP_SDIV] = 0;
OpAdvTable[OP_SDIV_ALT] = 0;
OpAdvTable[OP_ADD] = 0;
OpAdvTable[OP_SUB] = 0;
OpAdvTable[OP_SUB_ALT] = 0;
OpAdvTable[OP_AND] = 0;
OpAdvTable[OP_OR] = 0;
OpAdvTable[OP_XOR] = 0;
OpAdvTable[OP_NOT] = 0;
OpAdvTable[OP_NEG] = 0;
OpAdvTable[OP_INVERT] = 0;
OpAdvTable[OP_ZERO_PRI] = 0;
OpAdvTable[OP_ZERO_ALT] = 0;
OpAdvTable[OP_SIGN_PRI] = 0;
OpAdvTable[OP_SIGN_ALT] = 0;
OpAdvTable[OP_EQ] = 0;
OpAdvTable[OP_NEQ] = 0;
OpAdvTable[OP_SLESS] = 0;
OpAdvTable[OP_SLEQ] = 0;
OpAdvTable[OP_SGRTR] = 0;
OpAdvTable[OP_SGEQ] = 0;
OpAdvTable[OP_INC_PRI] = 0;
OpAdvTable[OP_INC_ALT] = 0;
OpAdvTable[OP_INC_I] = 0;
OpAdvTable[OP_DEC_PRI] = 0;
OpAdvTable[OP_DEC_ALT] = 0;
OpAdvTable[OP_DEC_I] = 0;
OpAdvTable[OP_JUMP_PRI] = 0;
OpAdvTable[OP_SWAP_PRI] = 0;
OpAdvTable[OP_SWAP_ALT] = 0;
OpAdvTable[OP_NOP] = 0;
OpAdvTable[OP_BREAK] = 0;
OpAdvTable[OP_HEAP_PRI] = 0;
OpAdvTable[OP_POP_HEAP_PRI] = 0;
OpAdvTable[OP_SYSREQ_PRI] = 0;
/* opcodes that are totally invalid */
/* :TODO: make an alternate table if USE_UNGEN_OPCODES is on? */
OpAdvTable[OP_FILE] = -3;
OpAdvTable[OP_SYMBOL] = -3;
OpAdvTable[OP_LINE] = -3;
OpAdvTable[OP_SRANGE] = -3;
OpAdvTable[OP_SYMTAG] = -3;
OpAdvTable[OP_SYSREQ_D] = -3;
OpAdvTable[OP_SYSREQ_ND] = -3;
OpAdvTable[OP_PUSH_R] = -3;
OpAdvTable[OP_LODB_I] = -3;
OpAdvTable[OP_STRB_I] = -3;
OpAdvTable[OP_LCTRL] = -3;
OpAdvTable[OP_SCTRL] = -3;
OpAdvTable[OP_ALIGN_PRI] = -3;
OpAdvTable[OP_ALIGN_ALT] = -3;
OpAdvTable[OP_JREL] = -3;
OpAdvTable[OP_CMPS] = -3;
OpAdvTable[OP_UMUL] = -3;
OpAdvTable[OP_UDIV] = -3;
OpAdvTable[OP_UDIV_ALT] = -3;
OpAdvTable[OP_LESS] = -3;
OpAdvTable[OP_LEQ] = -3;
OpAdvTable[OP_GRTR] = -3;
OpAdvTable[OP_GEQ] = -3;
OpAdvTable[OP_JLESS] = -3;
OpAdvTable[OP_JLEQ] = -3;
OpAdvTable[OP_JGRTR] = -3;
OpAdvTable[OP_JGEQ] = -3;
}

View File

@ -18,8 +18,10 @@ void WriteOp_Sysreq_N_Function(JitWriter *jit);
/** /**
* Generates code to set an error state in the VM and return. * Generates code to set an error state in the VM and return.
* This is used for generating the error set points in the VM. * This is used for generating the error set points in the VM.
* GetError writes the error from the context. SetError hardcodes.
*/ */
void Write_SetError(JitWriter *jit, bool always_inline, int error); void Write_GetError(JitWriter *jit);
void Write_SetError(JitWriter *jit, int error);
/** /**
* Checks the stacks for min and low errors. * Checks the stacks for min and low errors.
@ -210,7 +212,7 @@ typedef enum
OP_SWAP_ALT, //~VERIFIED (swap.alt) OP_SWAP_ALT, //~VERIFIED (swap.alt)
OP_PUSH_ADR, //VERIFIED OP_PUSH_ADR, //VERIFIED
OP_NOP, //VERIFIED (lol) OP_NOP, //VERIFIED (lol)
OP_SYSREQ_N, OP_SYSREQ_N, //VERIFIED
OP_SYMTAG, // !GEN DEPRECATED OP_SYMTAG, // !GEN DEPRECATED
OP_BREAK, //DONE OP_BREAK, //DONE
OP_PUSH2_C, //~VERIFIED (push3.c) OP_PUSH2_C, //~VERIFIED (push3.c)
@ -244,6 +246,4 @@ typedef enum
OP_NUM_OPCODES OP_NUM_OPCODES
} OPCODE; } OPCODE;
extern int OpAdvTable[];
#endif //_INCLUDE_SOURCEPAWN_JIT_X86_OPCODE_INFO_H_ #endif //_INCLUDE_SOURCEPAWN_JIT_X86_OPCODE_INFO_H_

View File

@ -643,10 +643,22 @@
WriteOp_Call(jit); WriteOp_Call(jit);
break; break;
} }
case OP_SYSREQ_N:
{
if (data->inline_level & JIT_INLINE_NATIVES)
{
WriteOp_Sysreq_N(jit);
} else {
WriteOp_Sysreq_N_NoInline(jit);
}
break;
}
#if defined USE_UNGEN_OPCODES #if defined USE_UNGEN_OPCODES
#include "ungen_opcode_switch.inc" #include "ungen_opcode_switch.inc"
#endif #endif
default: default:
{ {
assert(0); data->error_set = SP_ERR_INVALID_INSTRUCTION;
break;
} }

View File

@ -899,6 +899,22 @@ inline void IA32_Write_Jump32(JitWriter *jit, jitoffs_t jmp, jitoffs_t target)
jit->outptr = oldptr; jit->outptr = oldptr;
} }
/**
* Corrects a jump using an absolute offset, not a relative one.
*/
inline void IA32_Write_Jump32_Abs(JitWriter *jit, jitoffs_t jmp, void *target)
{
//save old ptr
jitcode_t oldptr = jit->outptr;
//get relative difference
long diff = ((long)target - ((long)jit->outbase + jmp + 4));
//overwrite old value
jit->outptr = jit->outbase + jmp;
jit->write_int32(diff);
//restore old ptr
jit->outptr = oldptr;
}
/* For writing and auto-calculating an absolute target */ /* For writing and auto-calculating an absolute target */
inline void IA32_Jump_Imm32_Abs(JitWriter *jit, jitoffs_t target) inline void IA32_Jump_Imm32_Abs(JitWriter *jit, jitoffs_t target)
{ {

View File

@ -12,6 +12,7 @@ using namespace SourcePawn;
BaseContext::BaseContext(sp_context_t *_ctx) BaseContext::BaseContext(sp_context_t *_ctx)
{ {
ctx = _ctx; ctx = _ctx;
ctx->context = this;
} }
IVirtualMachine *BaseContext::GetVirtualMachine() IVirtualMachine *BaseContext::GetVirtualMachine()