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:
David Anderson 2006-10-12 00:27:18 +00:00
parent fb7942ee4d
commit 6adba4b731
8 changed files with 285 additions and 102 deletions

View File

@ -1407,6 +1407,26 @@ inline void WriteOp_Casetbl(JitWriter *jit)
jit->inptr += num_cases; 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) inline void WriteOp_Sysreq_N_NoInline(JitWriter *jit)
{ {
/* store the number of parameters on the stack, /* 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) 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; return;
} }
@ -1439,7 +1459,7 @@ inline void WriteOp_Sysreq_N(JitWriter *jit)
if ((uint32_t)native_index >= data->plugin->info.natives_num) 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; return;
} }
@ -1481,8 +1501,13 @@ 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_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 */ /* check for errors */
//mov ecx, [esi+context] //mov ecx, [esi+context]
//cmp [ecx+err], 0 //cmp [ecx+err], 0
@ -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 */ /* Technically both aren't needed, I guess */
if (native->status == SP_NATIVE_NONE) if (native->status == SP_NATIVE_NONE)
{ {
ctx->err = SP_ERR_NATIVE_PENDING; ctx->err = SP_ERROR_NATIVE_PENDING;
return 0; return 0;
} }
return native->pfn(ctx, params); 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) jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative)
{ {
if (jit->outptr) if (jit->outptr)
@ -1559,25 +1626,25 @@ jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative)
void WriteErrorRoutines(CompData *data, JitWriter *jit) void WriteErrorRoutines(CompData *data, JitWriter *jit)
{ {
data->jit_error_divzero = jit->get_outputpos(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); data->jit_extern_error = jit->get_outputpos();
Write_GetError(jit); Write_GetError(jit);
@ -1629,6 +1696,10 @@ jit_rewind:
WriteOp_Sysreq_N_Function(jit); 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 */ /* Write error checking routines that are called to */
if (!(data->inline_level & JIT_INLINE_ERRORCHECKS)) if (!(data->inline_level & JIT_INLINE_ERRORCHECKS))
{ {
@ -1663,7 +1734,7 @@ jit_rewind:
#include "opcode_switch.inc" #include "opcode_switch.inc"
} }
/* Check for errors. This should only happen in the first pass. */ /* 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; *err = data->error_set;
AbortCompilation(co); AbortCompilation(co);
@ -1812,7 +1883,7 @@ jit_rewind:
/* clean up relocation+compilation memory */ /* clean up relocation+compilation memory */
AbortCompilation(co); AbortCompilation(co);
*err = SP_ERR_NONE; *err = SP_ERROR_NONE;
return ctx; return ctx;
} }
@ -1848,7 +1919,7 @@ ICompilation *JITX86::StartCompilation(sp_plugin_t *plugin)
data->plugin = plugin; data->plugin = plugin;
data->inline_level = JIT_INLINE_ERRORCHECKS|JIT_INLINE_NATIVES; data->inline_level = JIT_INLINE_ERRORCHECKS|JIT_INLINE_NATIVES;
data->error_set = SP_ERR_NONE; data->error_set = SP_ERROR_NONE;
return data; return data;
} }

View File

@ -15,17 +15,18 @@ class CompData : public ICompilation
{ {
public: public:
CompData() : plugin(NULL), CompData() : plugin(NULL),
debug(false), inline_level(0), rebase(NULL) debug(false), inline_level(0), rebase(NULL),
error_set(SP_ERROR_NONE)
{ {
}; };
public: public:
sp_plugin_t *plugin; sp_plugin_t *plugin; /* plugin handle */
jitcode_t rebase; jitcode_t rebase; /* relocation map */
jitoffs_t jit_return; jitoffs_t jit_return; /* point in main call to return to */
jitoffs_t jit_verify_addr_eax; jitoffs_t jit_verify_addr_eax;
jitoffs_t jit_verify_addr_edx; jitoffs_t jit_verify_addr_edx;
jitoffs_t jit_break; jitoffs_t jit_break; /* call to op.break */
jitoffs_t jit_sysreq_n; jitoffs_t jit_sysreq_n; /* call version of op.sysreq.n */
jitoffs_t jit_error_bounds; jitoffs_t jit_error_bounds;
jitoffs_t jit_error_divzero; jitoffs_t jit_error_divzero;
jitoffs_t jit_error_stacklow; jitoffs_t jit_error_stacklow;
@ -33,11 +34,12 @@ 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; jitoffs_t jit_extern_error; /* returning generic error */
uint32_t codesize; jitoffs_t jit_sysreq_c; /* old version! */
int inline_level; uint32_t codesize; /* total codesize */
int error_set; int inline_level; /* inline optimization level */
bool debug; int error_set; /* error code to halt process */
bool debug; /* whether to compile debug mode */
}; };
class JITX86 : public IVirtualMachine 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(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); jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative=false);
#define AMX_REG_PRI REG_EAX #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_RETVAL 8 //physical
#define AMX_INFO_CONTEXT 12 //physical #define AMX_INFO_CONTEXT 12 //physical
#define AMX_INFO_STACKTOP 16 //relocated #define AMX_INFO_STACKTOP 16 //relocated
#define AMX_INFO_HEAPLOW 20 //not relocated. currently unused #define AMX_INFO_STACKTOP_U 20 //not relocated
#define AMX_INFO_STACKTOP_U 24 //not relocated
extern ISourcePawnEngine *engine; extern ISourcePawnEngine *engine;

View File

@ -4,7 +4,7 @@
#include "opcode_helpers.h" #include "opcode_helpers.h"
#include "x86_macros.h" #include "x86_macros.h"
#define NUM_INFO_PARAMS 7 #define NUM_INFO_PARAMS 6
jitoffs_t Write_Execute_Function(JitWriter *jit) jitoffs_t Write_Execute_Function(JitWriter *jit)
{ {
@ -66,14 +66,10 @@ jitoffs_t Write_Execute_Function(JitWriter *jit)
//mov [esi+x], ecx - store unrelocated //mov [esi+x], ecx - store unrelocated
//add ecx, ebp - relocate //add ecx, ebp - relocate
//mov [esi+x], ecx - store relocated //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_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_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_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_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 */ /* 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) //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 */ /* if the code flow gets to here, there was a normal return */
//mov ecx, [esi+8] - get retval pointer //mov ecx, [esi+8] - get retval pointer
//mov [ecx], eax - store retval from PRI //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_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_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 */ /* save where error checking/halting functions should go to */
jitoffs_t offs_return = jit->get_outputpos(); 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); 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) void WriteOp_Sysreq_N_Function(JitWriter *jit)
{ {
/* The big daddy of opcodes. /* The big daddy of opcodes.
@ -437,7 +498,12 @@ void WriteOp_Sysreq_N_Function(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_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 */ /* Test for error */
//mov ecx, [esi+context] //mov ecx, [esi+context]

View File

@ -11,9 +11,10 @@
jitoffs_t Write_Execute_Function(JitWriter *jit); 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_N_Function(JitWriter *jit);
void WriteOp_Sysreq_C_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.
@ -200,7 +201,7 @@ typedef enum
OP_HALT, //DONE OP_HALT, //DONE
OP_BOUNDS, //VERIFIED OP_BOUNDS, //VERIFIED
OP_SYSREQ_PRI, // !GEN OP_SYSREQ_PRI, // !GEN
OP_SYSREQ_C, // !GEN DEPRECATED OP_SYSREQ_C, //VERIFIED
OP_FILE, // !GEN DEPRECATED OP_FILE, // !GEN DEPRECATED
OP_LINE, // !GEN DEPRECATED OP_LINE, // !GEN DEPRECATED
OP_SYMBOL, // !GEN DEPRECATED OP_SYMBOL, // !GEN DEPRECATED

View File

@ -643,6 +643,11 @@
WriteOp_Call(jit); WriteOp_Call(jit);
break; break;
} }
case OP_SYSREQ_C:
{
WriteOp_Sysreq_C(jit);
break;
}
case OP_SYSREQ_N: case OP_SYSREQ_N:
{ {
if (data->inline_level & JIT_INLINE_NATIVES) if (data->inline_level & JIT_INLINE_NATIVES)
@ -658,7 +663,7 @@
#endif #endif
default: default:
{ {
data->error_set = SP_ERR_INVALID_INSTRUCTION; data->error_set = SP_ERROR_INVALID_INSTRUCTION;
break; break;
} }

View File

@ -34,13 +34,13 @@ int BaseContext::SetDebugBreak(SPVM_DEBUGBREAK newpfn, SPVM_DEBUGBREAK *oldpfn)
{ {
if (!IsDebugging()) if (!IsDebugging())
{ {
return SP_ERR_NOTDEBUGGING; return SP_ERROR_NOTDEBUGGING;
} }
*oldpfn = ctx->dbreak; *oldpfn = ctx->dbreak;
ctx->dbreak = newpfn; ctx->dbreak = newpfn;
return SP_ERR_NONE; return SP_ERROR_NONE;
} }
IPluginDebugInfo *BaseContext::GetDebugInfo() IPluginDebugInfo *BaseContext::GetDebugInfo()
@ -56,7 +56,7 @@ int BaseContext::Execute(uint32_t public_func, cell_t *result)
int err; int err;
sp_public_t *pubfunc; sp_public_t *pubfunc;
if ((err=GetPublicByIndex(public_func, &pubfunc)) != SP_ERR_NONE) if ((err=GetPublicByIndex(public_func, &pubfunc)) != SP_ERROR_NONE)
{ {
return err; return err;
} }
@ -74,13 +74,13 @@ int BaseContext::Execute(uint32_t public_func, cell_t *result)
*/ */
#if defined _DEBUG #if defined _DEBUG
if (err == SP_ERR_NONE) if (err == SP_ERROR_NONE)
{ {
assert(ctx->sp - pushcount * sizeof(cell_t) == save_sp); assert(ctx->sp - pushcount * sizeof(cell_t) == save_sp);
assert(ctx->hp == save_hp); assert(ctx->hp == save_hp);
} }
#endif #endif
if (err != SP_ERR_NONE) if (err != SP_ERROR_NONE)
{ {
ctx->sp = save_sp; ctx->sp = save_sp;
ctx->hp = save_hp; ctx->hp = save_hp;
@ -97,7 +97,7 @@ int BaseContext::HeapAlloc(unsigned int cells, cell_t *local_addr, cell_t **phys
#if 0 #if 0
if (cells > CELLBOUNDMAX) if (cells > CELLBOUNDMAX)
{ {
return SP_ERR_PARAM; return SP_ERROR_ARAM;
} }
#else #else
assert(cells < CELLBOUNDMAX); 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) if ((cell_t)(ctx->sp - ctx->hp - realmem) < STACKMARGIN)
{ {
return SP_ERR_HEAPLOW; return SP_ERROR_HEAPLOW;
} }
addr = (cell_t *)(ctx->data + ctx->hp); 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; ctx->hp += realmem;
return SP_ERR_NONE; return SP_ERROR_NONE;
} }
int BaseContext::HeapPop(cell_t local_addr) int BaseContext::HeapPop(cell_t local_addr)
@ -140,7 +140,7 @@ int BaseContext::HeapPop(cell_t local_addr)
local_addr -= sizeof(cell_t); local_addr -= sizeof(cell_t);
if (local_addr < ctx->heapbase || local_addr >= ctx->sp) 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); 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 */ /* check if this memory count looks valid */
if (ctx->hp - cellcount - sizeof(cell_t) != local_addr) if (ctx->hp - cellcount - sizeof(cell_t) != local_addr)
{ {
return SP_ERR_INVALID_ADDRESS; return SP_ERROR_INVALID_ADDRESS;
} }
ctx->hp = local_addr; 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) if (local_addr < ctx->heapbase)
{ {
return SP_ERR_INVALID_ADDRESS; return SP_ERROR_INVALID_ADDRESS;
} }
ctx->hp = local_addr - sizeof(cell_t); ctx->hp = local_addr - sizeof(cell_t);
return SP_ERR_NONE; return SP_ERROR_NONE;
} }
int BaseContext::FindNativeByName(const char *name, uint32_t *index) int BaseContext::FindNativeByName(const char *name, uint32_t *index)
@ -187,7 +187,7 @@ int BaseContext::FindNativeByName(const char *name, uint32_t *index)
{ {
*index = mid; *index = mid;
} }
return SP_ERR_NONE; return SP_ERROR_NONE;
} else if (diff < 0) { } else if (diff < 0) {
low = mid + 1; low = mid + 1;
} else { } 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) int BaseContext::GetNativeByIndex(uint32_t index, sp_native_t **native)
{ {
if (index >= ctx->plugin->info.natives_num) if (index >= ctx->plugin->info.natives_num)
{ {
return SP_ERR_INDEX; return SP_ERROR_INDEX;
} }
if (native) if (native)
@ -210,7 +210,7 @@ int BaseContext::GetNativeByIndex(uint32_t index, sp_native_t **native)
*native = &(ctx->natives[index]); *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; *index = mid;
} }
return SP_ERR_NONE; return SP_ERROR_NONE;
} else if (diff < 0) { } else if (diff < 0) {
low = mid + 1; low = mid + 1;
} else { } 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) int BaseContext::GetPublicByIndex(uint32_t index, sp_public_t **pblic)
{ {
if (index >= ctx->plugin->info.publics_num) if (index >= ctx->plugin->info.publics_num)
{ {
return SP_ERR_INDEX; return SP_ERROR_INDEX;
} }
if (pblic) if (pblic)
@ -260,7 +260,7 @@ int BaseContext::GetPublicByIndex(uint32_t index, sp_public_t **pblic)
*pblic = &(ctx->publics[index]); *pblic = &(ctx->publics[index]);
} }
return SP_ERR_NONE; return SP_ERROR_NONE;
} }
uint32_t BaseContext::GetPublicsNum() 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) if (index >= ctx->plugin->info.pubvars_num)
{ {
return SP_ERR_INDEX; return SP_ERROR_INDEX;
} }
if (pubvar) if (pubvar)
@ -280,7 +280,7 @@ int BaseContext::GetPubvarByIndex(uint32_t index, sp_pubvar_t **pubvar)
*pubvar = &(ctx->pubvars[index]); *pubvar = &(ctx->pubvars[index]);
} }
return SP_ERR_NONE; return SP_ERROR_NONE;
} }
int BaseContext::FindPubvarByName(const char *name, uint32_t *index) int BaseContext::FindPubvarByName(const char *name, uint32_t *index)
@ -301,7 +301,7 @@ int BaseContext::FindPubvarByName(const char *name, uint32_t *index)
{ {
*index = mid; *index = mid;
} }
return SP_ERR_NONE; return SP_ERROR_NONE;
} else if (diff < 0) { } else if (diff < 0) {
low = mid + 1; low = mid + 1;
} else { } 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) int BaseContext::GetPubvarAddrs(uint32_t index, cell_t *local_addr, cell_t **phys_addr)
{ {
if (index >= ctx->plugin->info.pubvars_num) if (index >= ctx->plugin->info.pubvars_num)
{ {
return SP_ERR_INDEX; return SP_ERROR_INDEX;
} }
*local_addr = ctx->plugin->info.pubvars[index].address; *local_addr = ctx->plugin->info.pubvars[index].address;
*phys_addr = ctx->pubvars[index].offs; *phys_addr = ctx->pubvars[index].offs;
return SP_ERR_NONE; return SP_ERROR_NONE;
} }
uint32_t BaseContext::GetPubVarsNum() 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; uint32_t index;
int err; int err;
if ((err = FindNativeByName(native->name, &index)) != SP_ERR_NONE) if ((err = FindNativeByName(native->name, &index)) != SP_ERROR_NONE)
{ {
return err; 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].pfn = native->func;
ctx->natives[index].status = status; ctx->natives[index].status = status;
return SP_ERR_NONE; return SP_ERROR_NONE;
} }
int BaseContext::BindNativeToAny(SPVM_NATIVE_FUNC native) 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) 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)) 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) 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); *phys_addr = (cell_t *)(ctx->data + local_addr);
} }
return SP_ERR_NONE; return SP_ERROR_NONE;
} }
int BaseContext::PushCell(cell_t value) int BaseContext::PushCell(cell_t value)
{ {
if ((ctx->hp + STACKMARGIN) > (cell_t)(ctx->sp - sizeof(cell_t))) if ((ctx->hp + STACKMARGIN) > (cell_t)(ctx->sp - sizeof(cell_t)))
{ {
return SP_ERR_STACKLOW; return SP_ERROR_STACKLOW;
} }
ctx->sp -= sizeof(cell_t); ctx->sp -= sizeof(cell_t);
*(cell_t *)(ctx->data + ctx->sp) = value; *(cell_t *)(ctx->data + ctx->sp) = value;
ctx->pushcount++; ctx->pushcount++;
return SP_ERR_NONE; return SP_ERROR_NONE;
} }
int BaseContext::PushCellsFromArray(cell_t array[], unsigned int numcells) 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++) 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->sp += (cell_t)(i * sizeof(cell_t));
ctx->pushcount -= i; 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) 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; cell_t *ph_addr;
int err; 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; return err;
} }
memcpy(ph_addr, array, numcells * sizeof(cell_t)); 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); HeapRelease(*local_addr);
return err; return err;
@ -462,7 +462,7 @@ int BaseContext::PushCellArray(cell_t *local_addr, cell_t **phys_addr, cell_t ar
*phys_addr = ph_addr; *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) 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)) 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); 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; *chars = len;
} }
return SP_ERR_NONE; return SP_ERROR_NONE;
} }
int BaseContext::PushString(cell_t *local_addr, cell_t **phys_addr, const char *string) 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; int err;
unsigned int i, numcells = strlen(string); 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; return err;
} }
@ -515,7 +515,7 @@ int BaseContext::PushString(cell_t *local_addr, cell_t **phys_addr, const char *
} }
ph_addr[numcells] = '\0'; ph_addr[numcells] = '\0';
if ((err = PushCell(*local_addr)) != SP_ERR_NONE) if ((err = PushCell(*local_addr)) != SP_ERROR_NONE)
{ {
HeapRelease(*local_addr); HeapRelease(*local_addr);
return err; return err;
@ -526,7 +526,7 @@ int BaseContext::PushString(cell_t *local_addr, cell_t **phys_addr, const char *
*phys_addr = ph_addr; *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) 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)) 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); len = strlen(source);
@ -553,7 +553,7 @@ int BaseContext::StringToLocal(cell_t local_addr, size_t chars, const char *sour
} }
dest[len] = '\0'; dest[len] = '\0';
return SP_ERR_NONE; return SP_ERROR_NONE;
} }
#define USHR(x) ((unsigned int)(x)>>1) #define USHR(x) ((unsigned int)(x)>>1)
@ -578,12 +578,12 @@ int BaseContext::LookupFile(ucell_t addr, const char **filename)
if (low == -1) if (low == -1)
{ {
return SP_ERR_NOT_FOUND; return SP_ERROR_NOT_FOUND;
} }
*filename = ctx->files[low].name; *filename = ctx->files[low].name;
return SP_ERR_NONE; return SP_ERROR_NONE;
} }
int BaseContext::LookupFunction(ucell_t addr, const char **name) 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) if (iter >= max)
{ {
return SP_ERR_NOT_FOUND; return SP_ERROR_NOT_FOUND;
} }
*name = ctx->symbols[iter].name; *name = ctx->symbols[iter].name;
return SP_ERR_NONE; return SP_ERROR_NONE;
} }
int BaseContext::LookupLine(ucell_t addr, uint32_t *line) 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) if (low == -1)
{ {
return SP_ERR_NOT_FOUND; return SP_ERROR_NOT_FOUND;
} }
*line = ctx->lines[low].line; *line = ctx->lines[low].line;
return SP_ERR_NONE; return SP_ERROR_NONE;
} }

View File

@ -151,7 +151,7 @@ sp_plugin_t *_ReadPlugin(sp_file_hdr_t *hdr, uint8_t *base, sp_plugin_t *plugin,
if (err) if (err)
{ {
*err = SP_ERR_NONE; *err = SP_ERROR_NONE;
} }
return plugin; return plugin;
@ -159,7 +159,7 @@ sp_plugin_t *_ReadPlugin(sp_file_hdr_t *hdr, uint8_t *base, sp_plugin_t *plugin,
return_error: return_error:
if (err) if (err)
{ {
*err = SP_ERR_FILE_FORMAT; *err = SP_ERROR_FILE_FORMAT;
} }
return NULL; return NULL;
@ -175,7 +175,7 @@ sp_plugin_t *SourcePawnEngine::LoadFromFilePointer(FILE *fp, int *err)
if (!fp) if (!fp)
{ {
error = SP_ERR_NOT_FOUND; error = SP_ERROR_NOT_FOUND;
goto return_error; goto return_error;
} }
@ -185,7 +185,7 @@ sp_plugin_t *SourcePawnEngine::LoadFromFilePointer(FILE *fp, int *err)
if (hdr.magic != SPFILE_MAGIC) if (hdr.magic != SPFILE_MAGIC)
{ {
error = SP_ERR_FILE_FORMAT; error = SP_ERROR_FILE_FORMAT;
goto return_error; goto return_error;
} }
@ -211,7 +211,7 @@ sp_plugin_t *SourcePawnEngine::LoadFromFilePointer(FILE *fp, int *err)
{ {
free(sectheader); free(sectheader);
free(uncompdata); free(uncompdata);
error = SP_ERR_DECOMPRESSOR; error = SP_ERROR_DECOMPRESSOR;
goto return_error; goto return_error;
} }
@ -232,7 +232,7 @@ sp_plugin_t *SourcePawnEngine::LoadFromFilePointer(FILE *fp, int *err)
} }
default: default:
{ {
error = SP_ERR_DECOMPRESSOR; error = SP_ERROR_DECOMPRESSOR;
goto return_error; goto return_error;
} }
} }
@ -300,5 +300,5 @@ int SourcePawnEngine::FreeFromMemory(sp_plugin_t *plugin)
free(plugin); free(plugin);
} }
return SP_ERR_NONE; return SP_ERROR_NONE;
} }

View File

@ -1,5 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <sp_vm_api.h> #include <sp_vm_api.h>
#include <sp_vm_context.h>
#include "sp_vm_engine.h" #include "sp_vm_engine.h"
#include "sp_vm_basecontext.h" #include "sp_vm_basecontext.h"
#define WINDOWS_LEAN_AND_MEAN #define WINDOWS_LEAN_AND_MEAN
@ -10,6 +11,29 @@ using namespace SourcePawn;
typedef void (*GIVEENGINE)(ISourcePawnEngine *); typedef void (*GIVEENGINE)(ISourcePawnEngine *);
typedef IVirtualMachine *(*GETEXPORT)(unsigned int); 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() int main()
{ {
SourcePawnEngine engine; SourcePawnEngine engine;
@ -30,7 +54,7 @@ int main()
return 0; return 0;
} }
plugin = engine.LoadFromFilePointer(fp, &err); plugin = engine.LoadFromFilePointer(fp, &err);
if (err != SP_ERR_NONE) if (err != SP_ERROR_NONE)
{ {
printf("Error loading: %d", err); printf("Error loading: %d", err);
return 0; return 0;
@ -56,12 +80,26 @@ int main()
} }
co = vm->StartCompilation(plugin); 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); 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(1);
base->PushCell(5); base->PushCell(4);
err = base->Execute(0, &result); err = base->Execute(0, &result);
printf("Result: %d Error: %d\n", result, err); printf("Result: %d Error: %d\n", result, err);