changed error defines to have "ERROR" instead of "ERR"
added and verified sysreq.c which is generated on -O0 --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40118
This commit is contained in:
parent
fb7942ee4d
commit
6adba4b731
@ -1407,6 +1407,26 @@ inline void WriteOp_Casetbl(JitWriter *jit)
|
||||
jit->inptr += num_cases;
|
||||
}
|
||||
|
||||
inline void WriteOp_Sysreq_C(JitWriter *jit)
|
||||
{
|
||||
/* store the number of parameters on the stack,
|
||||
* and store the native index as well.
|
||||
*/
|
||||
cell_t native_index = jit->read_cell();
|
||||
|
||||
if ((uint32_t)native_index >= ((CompData*)jit->data)->plugin->info.natives_num)
|
||||
{
|
||||
((CompData *)jit->data)->error_set = SP_ERROR_INSTRUCTION_PARAM;
|
||||
return;
|
||||
}
|
||||
|
||||
//mov ecx, <native_index>
|
||||
IA32_Mov_Rm_Imm32(jit, REG_ECX, native_index, MOD_REG);
|
||||
|
||||
jitoffs_t call = IA32_Call_Imm32(jit, 0);
|
||||
IA32_Write_Jump32(jit, call, ((CompData *)jit->data)->jit_sysreq_c);
|
||||
}
|
||||
|
||||
inline void WriteOp_Sysreq_N_NoInline(JitWriter *jit)
|
||||
{
|
||||
/* store the number of parameters on the stack,
|
||||
@ -1417,7 +1437,7 @@ inline void WriteOp_Sysreq_N_NoInline(JitWriter *jit)
|
||||
|
||||
if ((uint32_t)native_index >= ((CompData*)jit->data)->plugin->info.natives_num)
|
||||
{
|
||||
((CompData *)jit->data)->error_set = SP_ERR_INSTRUCTION_PARAM;
|
||||
((CompData *)jit->data)->error_set = SP_ERROR_INSTRUCTION_PARAM;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1439,7 +1459,7 @@ inline void WriteOp_Sysreq_N(JitWriter *jit)
|
||||
|
||||
if ((uint32_t)native_index >= data->plugin->info.natives_num)
|
||||
{
|
||||
data->error_set = SP_ERR_INSTRUCTION_PARAM;
|
||||
data->error_set = SP_ERROR_INSTRUCTION_PARAM;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1481,7 +1501,12 @@ inline void WriteOp_Sysreq_N(JitWriter *jit)
|
||||
//call NativeCallback
|
||||
IA32_Push_Reg(jit, REG_EAX);
|
||||
jitoffs_t call = IA32_Call_Imm32(jit, 0);
|
||||
IA32_Write_Jump32_Abs(jit, call, NativeCallback);
|
||||
if (!data->debug)
|
||||
{
|
||||
IA32_Write_Jump32_Abs(jit, call, NativeCallback);
|
||||
} else {
|
||||
IA32_Write_Jump32_Abs(jit, call, NativeCallback_Debug);
|
||||
}
|
||||
|
||||
/* check for errors */
|
||||
//mov ecx, [esi+context]
|
||||
@ -1528,13 +1553,55 @@ cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
|
||||
/* Technically both aren't needed, I guess */
|
||||
if (native->status == SP_NATIVE_NONE)
|
||||
{
|
||||
ctx->err = SP_ERR_NATIVE_PENDING;
|
||||
ctx->err = SP_ERROR_NATIVE_PENDING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return native->pfn(ctx, params);
|
||||
}
|
||||
|
||||
cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
|
||||
{
|
||||
cell_t save_sp = ctx->sp;
|
||||
cell_t save_hp = ctx->hp;
|
||||
|
||||
if (ctx->hp < ctx->heapbase)
|
||||
{
|
||||
ctx->err = SP_ERROR_HEAPMIN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->hp + STACK_MARGIN > ctx->sp)
|
||||
{
|
||||
ctx->err = SP_ERROR_STACKLOW;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((uint32_t)ctx->sp >= ctx->memory)
|
||||
{
|
||||
ctx->err = SP_ERROR_STACKMIN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell_t result = NativeCallback(ctx, native_idx, params);
|
||||
|
||||
if (ctx->err != SP_ERROR_NONE)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (save_sp != ctx->sp)
|
||||
{
|
||||
ctx->err = SP_ERROR_STACKLEAK;
|
||||
return result;
|
||||
} else if (save_hp != ctx->hp) {
|
||||
ctx->err = SP_ERROR_HEAPLEAK;
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative)
|
||||
{
|
||||
if (jit->outptr)
|
||||
@ -1559,25 +1626,25 @@ 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);
|
||||
Write_SetError(jit, SP_ERROR_DIVIDE_BY_ZERO);
|
||||
|
||||
data->jit_error_stacklow = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERR_STACKLOW);
|
||||
Write_SetError(jit, SP_ERROR_STACKLOW);
|
||||
|
||||
data->jit_error_stackmin = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERR_STACKMIN);
|
||||
Write_SetError(jit, SP_ERROR_STACKMIN);
|
||||
|
||||
data->jit_error_bounds = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERR_ARRAY_BOUNDS);
|
||||
Write_SetError(jit, SP_ERROR_ARRAY_BOUNDS);
|
||||
|
||||
data->jit_error_memaccess = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERR_MEMACCESS);
|
||||
Write_SetError(jit, SP_ERROR_MEMACCESS);
|
||||
|
||||
data->jit_error_heaplow = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERR_HEAPLOW);
|
||||
Write_SetError(jit, SP_ERROR_HEAPLOW);
|
||||
|
||||
data->jit_error_heapmin = jit->get_outputpos();
|
||||
Write_SetError(jit, SP_ERR_HEAPMIN);
|
||||
Write_SetError(jit, SP_ERROR_HEAPMIN);
|
||||
|
||||
data->jit_extern_error = jit->get_outputpos();
|
||||
Write_GetError(jit);
|
||||
@ -1629,6 +1696,10 @@ jit_rewind:
|
||||
WriteOp_Sysreq_N_Function(jit);
|
||||
}
|
||||
|
||||
/* Plugins compiled with -O0 will need this! */
|
||||
data->jit_sysreq_c = jit->get_outputpos();
|
||||
WriteOp_Sysreq_C_Function(jit);
|
||||
|
||||
/* Write error checking routines that are called to */
|
||||
if (!(data->inline_level & JIT_INLINE_ERRORCHECKS))
|
||||
{
|
||||
@ -1663,7 +1734,7 @@ jit_rewind:
|
||||
#include "opcode_switch.inc"
|
||||
}
|
||||
/* Check for errors. This should only happen in the first pass. */
|
||||
if (data->error_set != SP_ERR_NONE)
|
||||
if (data->error_set != SP_ERROR_NONE)
|
||||
{
|
||||
*err = data->error_set;
|
||||
AbortCompilation(co);
|
||||
@ -1812,7 +1883,7 @@ jit_rewind:
|
||||
/* clean up relocation+compilation memory */
|
||||
AbortCompilation(co);
|
||||
|
||||
*err = SP_ERR_NONE;
|
||||
*err = SP_ERROR_NONE;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
@ -1848,7 +1919,7 @@ ICompilation *JITX86::StartCompilation(sp_plugin_t *plugin)
|
||||
|
||||
data->plugin = plugin;
|
||||
data->inline_level = JIT_INLINE_ERRORCHECKS|JIT_INLINE_NATIVES;
|
||||
data->error_set = SP_ERR_NONE;
|
||||
data->error_set = SP_ERROR_NONE;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -15,17 +15,18 @@ class CompData : public ICompilation
|
||||
{
|
||||
public:
|
||||
CompData() : plugin(NULL),
|
||||
debug(false), inline_level(0), rebase(NULL)
|
||||
debug(false), inline_level(0), rebase(NULL),
|
||||
error_set(SP_ERROR_NONE)
|
||||
{
|
||||
};
|
||||
public:
|
||||
sp_plugin_t *plugin;
|
||||
jitcode_t rebase;
|
||||
jitoffs_t jit_return;
|
||||
sp_plugin_t *plugin; /* plugin handle */
|
||||
jitcode_t rebase; /* relocation map */
|
||||
jitoffs_t jit_return; /* point in main call to return to */
|
||||
jitoffs_t jit_verify_addr_eax;
|
||||
jitoffs_t jit_verify_addr_edx;
|
||||
jitoffs_t jit_break;
|
||||
jitoffs_t jit_sysreq_n;
|
||||
jitoffs_t jit_break; /* call to op.break */
|
||||
jitoffs_t jit_sysreq_n; /* call version of op.sysreq.n */
|
||||
jitoffs_t jit_error_bounds;
|
||||
jitoffs_t jit_error_divzero;
|
||||
jitoffs_t jit_error_stacklow;
|
||||
@ -33,11 +34,12 @@ public:
|
||||
jitoffs_t jit_error_memaccess;
|
||||
jitoffs_t jit_error_heaplow;
|
||||
jitoffs_t jit_error_heapmin;
|
||||
jitoffs_t jit_extern_error;
|
||||
uint32_t codesize;
|
||||
int inline_level;
|
||||
int error_set;
|
||||
bool debug;
|
||||
jitoffs_t jit_extern_error; /* returning generic error */
|
||||
jitoffs_t jit_sysreq_c; /* old version! */
|
||||
uint32_t codesize; /* total codesize */
|
||||
int inline_level; /* inline optimization level */
|
||||
int error_set; /* error code to halt process */
|
||||
bool debug; /* whether to compile debug mode */
|
||||
};
|
||||
|
||||
class JITX86 : public IVirtualMachine
|
||||
@ -53,6 +55,7 @@ public:
|
||||
};
|
||||
|
||||
cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
|
||||
cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
|
||||
jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative=false);
|
||||
|
||||
#define AMX_REG_PRI REG_EAX
|
||||
@ -69,8 +72,7 @@ jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative=false);
|
||||
#define AMX_INFO_RETVAL 8 //physical
|
||||
#define AMX_INFO_CONTEXT 12 //physical
|
||||
#define AMX_INFO_STACKTOP 16 //relocated
|
||||
#define AMX_INFO_HEAPLOW 20 //not relocated. currently unused
|
||||
#define AMX_INFO_STACKTOP_U 24 //not relocated
|
||||
#define AMX_INFO_STACKTOP_U 20 //not relocated
|
||||
|
||||
extern ISourcePawnEngine *engine;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "opcode_helpers.h"
|
||||
#include "x86_macros.h"
|
||||
|
||||
#define NUM_INFO_PARAMS 7
|
||||
#define NUM_INFO_PARAMS 6
|
||||
|
||||
jitoffs_t Write_Execute_Function(JitWriter *jit)
|
||||
{
|
||||
@ -66,14 +66,10 @@ jitoffs_t Write_Execute_Function(JitWriter *jit)
|
||||
//mov [esi+x], ecx - store unrelocated
|
||||
//add ecx, ebp - relocate
|
||||
//mov [esi+x], ecx - store relocated
|
||||
//mov ecx, [eax+<offs>] - get heap low
|
||||
//mov [esi+20], ecx - store heap low into info pointer
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, memory));
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_STACKTOP_U);
|
||||
IA32_Add_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_DAT, MOD_REG);
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_STACKTOP);
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, heapbase));
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_HEAPLOW);
|
||||
|
||||
/* Remaining needed vars */
|
||||
//mov ecx, [esp+(4*(NUM_INFO_PARAMS+3))+12] - get code index (normally esp+12, but we have another array on the stack)
|
||||
@ -88,10 +84,10 @@ jitoffs_t Write_Execute_Function(JitWriter *jit)
|
||||
/* if the code flow gets to here, there was a normal return */
|
||||
//mov ecx, [esi+8] - get retval pointer
|
||||
//mov [ecx], eax - store retval from PRI
|
||||
//mov eax, SP_ERR_NONE - set no error
|
||||
//mov eax, SP_ERROR_NONE - set no error
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, AMX_REG_INFO, AMX_INFO_RETVAL);
|
||||
IA32_Mov_Rm_Reg(jit, REG_ECX, AMX_REG_PRI, MOD_MEM_REG);
|
||||
IA32_Mov_Reg_Imm32(jit, REG_EAX, SP_ERR_NONE);
|
||||
IA32_Mov_Reg_Imm32(jit, REG_EAX, SP_ERROR_NONE);
|
||||
|
||||
/* save where error checking/halting functions should go to */
|
||||
jitoffs_t offs_return = jit->get_outputpos();
|
||||
@ -390,6 +386,71 @@ void Macro_PushN(JitWriter *jit, int i)
|
||||
IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG);
|
||||
}
|
||||
|
||||
void WriteOp_Sysreq_C_Function(JitWriter *jit)
|
||||
{
|
||||
/* The small daddy of the big daddy of opcodes.
|
||||
* ecx - native index
|
||||
*/
|
||||
CompData *data = (CompData *)jit->data;
|
||||
|
||||
/* save registers we will need */
|
||||
//push edx
|
||||
IA32_Push_Reg(jit, AMX_REG_ALT);
|
||||
|
||||
/* push some callback stuff */
|
||||
//push edi ; stack
|
||||
//push ecx ; native index
|
||||
IA32_Push_Reg(jit, AMX_REG_STK);
|
||||
IA32_Push_Reg(jit, REG_ECX);
|
||||
|
||||
/* Relocate stack, heap, frm information, then store back */
|
||||
//sub edi, ebp
|
||||
//mov ecx, [esi+hea]
|
||||
//mov eax, [esi+context]
|
||||
//mov [eax+hp], ecx
|
||||
//mov [eax+sp], edi
|
||||
//mov ecx, [esi+frm]
|
||||
//mov [eax+frm], ecx
|
||||
IA32_Sub_Rm_Reg(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, hp));
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_STK, offsetof(sp_context_t, sp));
|
||||
IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_INFO_FRM, MOD_REG);
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, frm));
|
||||
|
||||
/* finally, push the last parameter and make the call */
|
||||
//push eax ; context
|
||||
//call NativeCallback
|
||||
IA32_Push_Reg(jit, REG_EAX);
|
||||
jitoffs_t call = IA32_Call_Imm32(jit, 0);
|
||||
if (!data->debug)
|
||||
{
|
||||
IA32_Write_Jump32_Abs(jit, call, NativeCallback);
|
||||
} else {
|
||||
IA32_Write_Jump32_Abs(jit, call, NativeCallback_Debug);
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
//add esp, 4*3
|
||||
//add edi, ebp
|
||||
//pop edx
|
||||
IA32_Add_Rm_Imm8(jit, REG_ESP, 4*3, MOD_REG);
|
||||
IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
|
||||
IA32_Pop_Reg(jit, AMX_REG_ALT);
|
||||
|
||||
//ret
|
||||
IA32_Return(jit);
|
||||
}
|
||||
|
||||
void WriteOp_Sysreq_N_Function(JitWriter *jit)
|
||||
{
|
||||
/* The big daddy of opcodes.
|
||||
@ -437,7 +498,12 @@ void WriteOp_Sysreq_N_Function(JitWriter *jit)
|
||||
//call NativeCallback
|
||||
IA32_Push_Reg(jit, REG_EAX);
|
||||
jitoffs_t call = IA32_Call_Imm32(jit, 0);
|
||||
IA32_Write_Jump32_Abs(jit, call, (void *)&NativeCallback);
|
||||
if (!data->debug)
|
||||
{
|
||||
IA32_Write_Jump32_Abs(jit, call, NativeCallback);
|
||||
} else {
|
||||
IA32_Write_Jump32_Abs(jit, call, NativeCallback_Debug);
|
||||
}
|
||||
|
||||
/* Test for error */
|
||||
//mov ecx, [esi+context]
|
||||
|
@ -11,9 +11,10 @@
|
||||
jitoffs_t Write_Execute_Function(JitWriter *jit);
|
||||
|
||||
/**
|
||||
* Writes the Sysreq.n opcode as a function call.
|
||||
* Writes the Sysreq.* opcodes as a function call.
|
||||
*/
|
||||
void WriteOp_Sysreq_N_Function(JitWriter *jit);
|
||||
void WriteOp_Sysreq_C_Function(JitWriter *jit);
|
||||
|
||||
/**
|
||||
* Generates code to set an error state in the VM and return.
|
||||
@ -200,7 +201,7 @@ typedef enum
|
||||
OP_HALT, //DONE
|
||||
OP_BOUNDS, //VERIFIED
|
||||
OP_SYSREQ_PRI, // !GEN
|
||||
OP_SYSREQ_C, // !GEN DEPRECATED
|
||||
OP_SYSREQ_C, //VERIFIED
|
||||
OP_FILE, // !GEN DEPRECATED
|
||||
OP_LINE, // !GEN DEPRECATED
|
||||
OP_SYMBOL, // !GEN DEPRECATED
|
||||
|
@ -643,6 +643,11 @@
|
||||
WriteOp_Call(jit);
|
||||
break;
|
||||
}
|
||||
case OP_SYSREQ_C:
|
||||
{
|
||||
WriteOp_Sysreq_C(jit);
|
||||
break;
|
||||
}
|
||||
case OP_SYSREQ_N:
|
||||
{
|
||||
if (data->inline_level & JIT_INLINE_NATIVES)
|
||||
@ -658,7 +663,7 @@
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
data->error_set = SP_ERR_INVALID_INSTRUCTION;
|
||||
data->error_set = SP_ERROR_INVALID_INSTRUCTION;
|
||||
break;
|
||||
}
|
||||
|
@ -34,13 +34,13 @@ int BaseContext::SetDebugBreak(SPVM_DEBUGBREAK newpfn, SPVM_DEBUGBREAK *oldpfn)
|
||||
{
|
||||
if (!IsDebugging())
|
||||
{
|
||||
return SP_ERR_NOTDEBUGGING;
|
||||
return SP_ERROR_NOTDEBUGGING;
|
||||
}
|
||||
|
||||
*oldpfn = ctx->dbreak;
|
||||
ctx->dbreak = newpfn;
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
IPluginDebugInfo *BaseContext::GetDebugInfo()
|
||||
@ -56,7 +56,7 @@ int BaseContext::Execute(uint32_t public_func, cell_t *result)
|
||||
|
||||
int err;
|
||||
sp_public_t *pubfunc;
|
||||
if ((err=GetPublicByIndex(public_func, &pubfunc)) != SP_ERR_NONE)
|
||||
if ((err=GetPublicByIndex(public_func, &pubfunc)) != SP_ERROR_NONE)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
@ -74,13 +74,13 @@ int BaseContext::Execute(uint32_t public_func, cell_t *result)
|
||||
*/
|
||||
|
||||
#if defined _DEBUG
|
||||
if (err == SP_ERR_NONE)
|
||||
if (err == SP_ERROR_NONE)
|
||||
{
|
||||
assert(ctx->sp - pushcount * sizeof(cell_t) == save_sp);
|
||||
assert(ctx->hp == save_hp);
|
||||
}
|
||||
#endif
|
||||
if (err != SP_ERR_NONE)
|
||||
if (err != SP_ERROR_NONE)
|
||||
{
|
||||
ctx->sp = save_sp;
|
||||
ctx->hp = save_hp;
|
||||
@ -97,7 +97,7 @@ int BaseContext::HeapAlloc(unsigned int cells, cell_t *local_addr, cell_t **phys
|
||||
#if 0
|
||||
if (cells > CELLBOUNDMAX)
|
||||
{
|
||||
return SP_ERR_PARAM;
|
||||
return SP_ERROR_ARAM;
|
||||
}
|
||||
#else
|
||||
assert(cells < CELLBOUNDMAX);
|
||||
@ -110,7 +110,7 @@ int BaseContext::HeapAlloc(unsigned int cells, cell_t *local_addr, cell_t **phys
|
||||
*/
|
||||
if ((cell_t)(ctx->sp - ctx->hp - realmem) < STACKMARGIN)
|
||||
{
|
||||
return SP_ERR_HEAPLOW;
|
||||
return SP_ERROR_HEAPLOW;
|
||||
}
|
||||
|
||||
addr = (cell_t *)(ctx->data + ctx->hp);
|
||||
@ -128,7 +128,7 @@ int BaseContext::HeapAlloc(unsigned int cells, cell_t *local_addr, cell_t **phys
|
||||
|
||||
ctx->hp += realmem;
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int BaseContext::HeapPop(cell_t local_addr)
|
||||
@ -140,7 +140,7 @@ int BaseContext::HeapPop(cell_t local_addr)
|
||||
local_addr -= sizeof(cell_t);
|
||||
if (local_addr < ctx->heapbase || local_addr >= ctx->sp)
|
||||
{
|
||||
return SP_ERR_INVALID_ADDRESS;
|
||||
return SP_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
addr = (cell_t *)(ctx->data + local_addr);
|
||||
@ -148,12 +148,12 @@ int BaseContext::HeapPop(cell_t local_addr)
|
||||
/* check if this memory count looks valid */
|
||||
if (ctx->hp - cellcount - sizeof(cell_t) != local_addr)
|
||||
{
|
||||
return SP_ERR_INVALID_ADDRESS;
|
||||
return SP_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
ctx->hp = local_addr;
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
@ -161,12 +161,12 @@ int BaseContext::HeapRelease(cell_t local_addr)
|
||||
{
|
||||
if (local_addr < ctx->heapbase)
|
||||
{
|
||||
return SP_ERR_INVALID_ADDRESS;
|
||||
return SP_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
ctx->hp = local_addr - sizeof(cell_t);
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int BaseContext::FindNativeByName(const char *name, uint32_t *index)
|
||||
@ -187,7 +187,7 @@ int BaseContext::FindNativeByName(const char *name, uint32_t *index)
|
||||
{
|
||||
*index = mid;
|
||||
}
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
} else if (diff < 0) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
@ -195,14 +195,14 @@ int BaseContext::FindNativeByName(const char *name, uint32_t *index)
|
||||
}
|
||||
}
|
||||
|
||||
return SP_ERR_NOT_FOUND;
|
||||
return SP_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
int BaseContext::GetNativeByIndex(uint32_t index, sp_native_t **native)
|
||||
{
|
||||
if (index >= ctx->plugin->info.natives_num)
|
||||
{
|
||||
return SP_ERR_INDEX;
|
||||
return SP_ERROR_INDEX;
|
||||
}
|
||||
|
||||
if (native)
|
||||
@ -210,7 +210,7 @@ int BaseContext::GetNativeByIndex(uint32_t index, sp_native_t **native)
|
||||
*native = &(ctx->natives[index]);
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
@ -237,7 +237,7 @@ int BaseContext::FindPublicByName(const char *name, uint32_t *index)
|
||||
{
|
||||
*index = mid;
|
||||
}
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
} else if (diff < 0) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
@ -245,14 +245,14 @@ int BaseContext::FindPublicByName(const char *name, uint32_t *index)
|
||||
}
|
||||
}
|
||||
|
||||
return SP_ERR_NOT_FOUND;
|
||||
return SP_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
int BaseContext::GetPublicByIndex(uint32_t index, sp_public_t **pblic)
|
||||
{
|
||||
if (index >= ctx->plugin->info.publics_num)
|
||||
{
|
||||
return SP_ERR_INDEX;
|
||||
return SP_ERROR_INDEX;
|
||||
}
|
||||
|
||||
if (pblic)
|
||||
@ -260,7 +260,7 @@ int BaseContext::GetPublicByIndex(uint32_t index, sp_public_t **pblic)
|
||||
*pblic = &(ctx->publics[index]);
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
uint32_t BaseContext::GetPublicsNum()
|
||||
@ -272,7 +272,7 @@ int BaseContext::GetPubvarByIndex(uint32_t index, sp_pubvar_t **pubvar)
|
||||
{
|
||||
if (index >= ctx->plugin->info.pubvars_num)
|
||||
{
|
||||
return SP_ERR_INDEX;
|
||||
return SP_ERROR_INDEX;
|
||||
}
|
||||
|
||||
if (pubvar)
|
||||
@ -280,7 +280,7 @@ int BaseContext::GetPubvarByIndex(uint32_t index, sp_pubvar_t **pubvar)
|
||||
*pubvar = &(ctx->pubvars[index]);
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int BaseContext::FindPubvarByName(const char *name, uint32_t *index)
|
||||
@ -301,7 +301,7 @@ int BaseContext::FindPubvarByName(const char *name, uint32_t *index)
|
||||
{
|
||||
*index = mid;
|
||||
}
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
} else if (diff < 0) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
@ -309,20 +309,20 @@ int BaseContext::FindPubvarByName(const char *name, uint32_t *index)
|
||||
}
|
||||
}
|
||||
|
||||
return SP_ERR_NOT_FOUND;
|
||||
return SP_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
int BaseContext::GetPubvarAddrs(uint32_t index, cell_t *local_addr, cell_t **phys_addr)
|
||||
{
|
||||
if (index >= ctx->plugin->info.pubvars_num)
|
||||
{
|
||||
return SP_ERR_INDEX;
|
||||
return SP_ERROR_INDEX;
|
||||
}
|
||||
|
||||
*local_addr = ctx->plugin->info.pubvars[index].address;
|
||||
*phys_addr = ctx->pubvars[index].offs;
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
uint32_t BaseContext::GetPubVarsNum()
|
||||
@ -353,7 +353,7 @@ int BaseContext::BindNatives(sp_nativeinfo_t *natives, unsigned int num, int ove
|
||||
}
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
@ -363,7 +363,7 @@ int BaseContext::BindNative(sp_nativeinfo_t *native, uint32_t status)
|
||||
uint32_t index;
|
||||
int err;
|
||||
|
||||
if ((err = FindNativeByName(native->name, &index)) != SP_ERR_NONE)
|
||||
if ((err = FindNativeByName(native->name, &index)) != SP_ERROR_NONE)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
@ -371,7 +371,7 @@ int BaseContext::BindNative(sp_nativeinfo_t *native, uint32_t status)
|
||||
ctx->natives[index].pfn = native->func;
|
||||
ctx->natives[index].status = status;
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int BaseContext::BindNativeToAny(SPVM_NATIVE_FUNC native)
|
||||
@ -389,14 +389,14 @@ int BaseContext::BindNativeToAny(SPVM_NATIVE_FUNC native)
|
||||
}
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int BaseContext::LocalToPhysAddr(cell_t local_addr, cell_t **phys_addr)
|
||||
{
|
||||
if (((local_addr >= ctx->hp) && (local_addr < ctx->sp)) || (local_addr < 0) || ((ucell_t)local_addr >= ctx->memory))
|
||||
{
|
||||
return SP_ERR_INVALID_ADDRESS;
|
||||
return SP_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
if (phys_addr)
|
||||
@ -404,21 +404,21 @@ int BaseContext::LocalToPhysAddr(cell_t local_addr, cell_t **phys_addr)
|
||||
*phys_addr = (cell_t *)(ctx->data + local_addr);
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int BaseContext::PushCell(cell_t value)
|
||||
{
|
||||
if ((ctx->hp + STACKMARGIN) > (cell_t)(ctx->sp - sizeof(cell_t)))
|
||||
{
|
||||
return SP_ERR_STACKLOW;
|
||||
return SP_ERROR_STACKLOW;
|
||||
}
|
||||
|
||||
ctx->sp -= sizeof(cell_t);
|
||||
*(cell_t *)(ctx->data + ctx->sp) = value;
|
||||
ctx->pushcount++;
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int BaseContext::PushCellsFromArray(cell_t array[], unsigned int numcells)
|
||||
@ -428,7 +428,7 @@ int BaseContext::PushCellsFromArray(cell_t array[], unsigned int numcells)
|
||||
|
||||
for (i=0; i<numcells; i++)
|
||||
{
|
||||
if ((err = PushCell(array[i])) != SP_ERR_NONE)
|
||||
if ((err = PushCell(array[i])) != SP_ERROR_NONE)
|
||||
{
|
||||
ctx->sp += (cell_t)(i * sizeof(cell_t));
|
||||
ctx->pushcount -= i;
|
||||
@ -436,7 +436,7 @@ int BaseContext::PushCellsFromArray(cell_t array[], unsigned int numcells)
|
||||
}
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int BaseContext::PushCellArray(cell_t *local_addr, cell_t **phys_addr, cell_t array[], unsigned int numcells)
|
||||
@ -444,14 +444,14 @@ int BaseContext::PushCellArray(cell_t *local_addr, cell_t **phys_addr, cell_t ar
|
||||
cell_t *ph_addr;
|
||||
int err;
|
||||
|
||||
if ((err = HeapAlloc(numcells, local_addr, &ph_addr)) != SP_ERR_NONE)
|
||||
if ((err = HeapAlloc(numcells, local_addr, &ph_addr)) != SP_ERROR_NONE)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
memcpy(ph_addr, array, numcells * sizeof(cell_t));
|
||||
|
||||
if ((err = PushCell(*local_addr)) != SP_ERR_NONE)
|
||||
if ((err = PushCell(*local_addr)) != SP_ERROR_NONE)
|
||||
{
|
||||
HeapRelease(*local_addr);
|
||||
return err;
|
||||
@ -462,7 +462,7 @@ int BaseContext::PushCellArray(cell_t *local_addr, cell_t **phys_addr, cell_t ar
|
||||
*phys_addr = ph_addr;
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int BaseContext::LocalToString(cell_t local_addr, char *buffer, size_t maxlength, int *chars)
|
||||
@ -472,7 +472,7 @@ int BaseContext::LocalToString(cell_t local_addr, char *buffer, size_t maxlength
|
||||
|
||||
if (((local_addr >= ctx->hp) && (local_addr < ctx->sp)) || (local_addr < 0) || ((ucell_t)local_addr >= ctx->memory))
|
||||
{
|
||||
return SP_ERR_INVALID_ADDRESS;
|
||||
return SP_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
src = (cell_t *)(ctx->data + local_addr);
|
||||
@ -495,7 +495,7 @@ int BaseContext::LocalToString(cell_t local_addr, char *buffer, size_t maxlength
|
||||
*chars = len;
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int BaseContext::PushString(cell_t *local_addr, cell_t **phys_addr, const char *string)
|
||||
@ -504,7 +504,7 @@ int BaseContext::PushString(cell_t *local_addr, cell_t **phys_addr, const char *
|
||||
int err;
|
||||
unsigned int i, numcells = strlen(string);
|
||||
|
||||
if ((err = HeapAlloc(numcells+1, local_addr, &ph_addr)) != SP_ERR_NONE)
|
||||
if ((err = HeapAlloc(numcells+1, local_addr, &ph_addr)) != SP_ERROR_NONE)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
@ -515,7 +515,7 @@ int BaseContext::PushString(cell_t *local_addr, cell_t **phys_addr, const char *
|
||||
}
|
||||
ph_addr[numcells] = '\0';
|
||||
|
||||
if ((err = PushCell(*local_addr)) != SP_ERR_NONE)
|
||||
if ((err = PushCell(*local_addr)) != SP_ERROR_NONE)
|
||||
{
|
||||
HeapRelease(*local_addr);
|
||||
return err;
|
||||
@ -526,7 +526,7 @@ int BaseContext::PushString(cell_t *local_addr, cell_t **phys_addr, const char *
|
||||
*phys_addr = ph_addr;
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int BaseContext::StringToLocal(cell_t local_addr, size_t chars, const char *source)
|
||||
@ -536,7 +536,7 @@ int BaseContext::StringToLocal(cell_t local_addr, size_t chars, const char *sour
|
||||
|
||||
if (((local_addr >= ctx->hp) && (local_addr < ctx->sp)) || (local_addr < 0) || ((ucell_t)local_addr >= ctx->memory))
|
||||
{
|
||||
return SP_ERR_INVALID_ADDRESS;
|
||||
return SP_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
len = strlen(source);
|
||||
@ -553,7 +553,7 @@ int BaseContext::StringToLocal(cell_t local_addr, size_t chars, const char *sour
|
||||
}
|
||||
dest[len] = '\0';
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
#define USHR(x) ((unsigned int)(x)>>1)
|
||||
@ -578,12 +578,12 @@ int BaseContext::LookupFile(ucell_t addr, const char **filename)
|
||||
|
||||
if (low == -1)
|
||||
{
|
||||
return SP_ERR_NOT_FOUND;
|
||||
return SP_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
*filename = ctx->files[low].name;
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int BaseContext::LookupFunction(ucell_t addr, const char **name)
|
||||
@ -602,12 +602,12 @@ int BaseContext::LookupFunction(ucell_t addr, const char **name)
|
||||
|
||||
if (iter >= max)
|
||||
{
|
||||
return SP_ERR_NOT_FOUND;
|
||||
return SP_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
*name = ctx->symbols[iter].name;
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int BaseContext::LookupLine(ucell_t addr, uint32_t *line)
|
||||
@ -630,10 +630,10 @@ int BaseContext::LookupLine(ucell_t addr, uint32_t *line)
|
||||
|
||||
if (low == -1)
|
||||
{
|
||||
return SP_ERR_NOT_FOUND;
|
||||
return SP_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
*line = ctx->lines[low].line;
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ sp_plugin_t *_ReadPlugin(sp_file_hdr_t *hdr, uint8_t *base, sp_plugin_t *plugin,
|
||||
|
||||
if (err)
|
||||
{
|
||||
*err = SP_ERR_NONE;
|
||||
*err = SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
return plugin;
|
||||
@ -159,7 +159,7 @@ sp_plugin_t *_ReadPlugin(sp_file_hdr_t *hdr, uint8_t *base, sp_plugin_t *plugin,
|
||||
return_error:
|
||||
if (err)
|
||||
{
|
||||
*err = SP_ERR_FILE_FORMAT;
|
||||
*err = SP_ERROR_FILE_FORMAT;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -175,7 +175,7 @@ sp_plugin_t *SourcePawnEngine::LoadFromFilePointer(FILE *fp, int *err)
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
error = SP_ERR_NOT_FOUND;
|
||||
error = SP_ERROR_NOT_FOUND;
|
||||
goto return_error;
|
||||
}
|
||||
|
||||
@ -185,7 +185,7 @@ sp_plugin_t *SourcePawnEngine::LoadFromFilePointer(FILE *fp, int *err)
|
||||
|
||||
if (hdr.magic != SPFILE_MAGIC)
|
||||
{
|
||||
error = SP_ERR_FILE_FORMAT;
|
||||
error = SP_ERROR_FILE_FORMAT;
|
||||
goto return_error;
|
||||
}
|
||||
|
||||
@ -211,7 +211,7 @@ sp_plugin_t *SourcePawnEngine::LoadFromFilePointer(FILE *fp, int *err)
|
||||
{
|
||||
free(sectheader);
|
||||
free(uncompdata);
|
||||
error = SP_ERR_DECOMPRESSOR;
|
||||
error = SP_ERROR_DECOMPRESSOR;
|
||||
goto return_error;
|
||||
}
|
||||
|
||||
@ -232,7 +232,7 @@ sp_plugin_t *SourcePawnEngine::LoadFromFilePointer(FILE *fp, int *err)
|
||||
}
|
||||
default:
|
||||
{
|
||||
error = SP_ERR_DECOMPRESSOR;
|
||||
error = SP_ERROR_DECOMPRESSOR;
|
||||
goto return_error;
|
||||
}
|
||||
}
|
||||
@ -300,5 +300,5 @@ int SourcePawnEngine::FreeFromMemory(sp_plugin_t *plugin)
|
||||
free(plugin);
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <sp_vm_api.h>
|
||||
#include <sp_vm_context.h>
|
||||
#include "sp_vm_engine.h"
|
||||
#include "sp_vm_basecontext.h"
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
@ -10,6 +11,29 @@ using namespace SourcePawn;
|
||||
typedef void (*GIVEENGINE)(ISourcePawnEngine *);
|
||||
typedef IVirtualMachine *(*GETEXPORT)(unsigned int);
|
||||
|
||||
cell_t TestNative(sp_context_t *ctx, cell_t *params)
|
||||
{
|
||||
IPluginContext *pl = ctx->context;
|
||||
cell_t *phys;
|
||||
int err;
|
||||
printf("params[0] = %d\n", params[0]);
|
||||
printf("params[1] = %d\n", params[1]);
|
||||
if ((err=pl->LocalToPhysAddr(params[2], &phys)) != SP_ERROR_NONE)
|
||||
{
|
||||
ctx->err = err;
|
||||
return 0;
|
||||
}
|
||||
printf("params[2] %c%c%c%c%c\n", phys[0], phys[1], phys[2], phys[3], phys[4]);
|
||||
if ((err=pl->LocalToPhysAddr(params[3], &phys)) != SP_ERROR_NONE)
|
||||
{
|
||||
ctx->err = err;
|
||||
return 0;
|
||||
}
|
||||
printf("params[3] = %d\n", *phys);
|
||||
*phys = 95;
|
||||
return 5;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
SourcePawnEngine engine;
|
||||
@ -30,7 +54,7 @@ int main()
|
||||
return 0;
|
||||
}
|
||||
plugin = engine.LoadFromFilePointer(fp, &err);
|
||||
if (err != SP_ERR_NONE)
|
||||
if (err != SP_ERROR_NONE)
|
||||
{
|
||||
printf("Error loading: %d", err);
|
||||
return 0;
|
||||
@ -56,12 +80,26 @@ int main()
|
||||
}
|
||||
|
||||
co = vm->StartCompilation(plugin);
|
||||
ctx = vm->CompileToContext(co, &err);
|
||||
if ((ctx = vm->CompileToContext(co, &err)) == NULL)
|
||||
{
|
||||
printf("CompileToContext() failed: %d", err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
IPluginContext *base = engine.CreateBaseContext(ctx);
|
||||
|
||||
sp_nativeinfo_t mynative;
|
||||
mynative.name = "gaben";
|
||||
mynative.func = TestNative;
|
||||
|
||||
if ((err=base->BindNative(&mynative, SP_NATIVE_OKAY)) != SP_ERROR_NONE)
|
||||
{
|
||||
printf("BindNative() failed: %d", err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
base->PushCell(1);
|
||||
base->PushCell(5);
|
||||
base->PushCell(4);
|
||||
err = base->Execute(0, &result);
|
||||
printf("Result: %d Error: %d\n", result, err);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user