diff --git a/sourcepawn/vm/jit/x86/jit_x86.cpp b/sourcepawn/vm/jit/x86/jit_x86.cpp index 5ef91c9d..e969e293 100644 --- a/sourcepawn/vm/jit/x86/jit_x86.cpp +++ b/sourcepawn/vm/jit/x86/jit_x86.cpp @@ -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, + 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,8 +1501,13 @@ 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] //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 */ 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; } diff --git a/sourcepawn/vm/jit/x86/jit_x86.h b/sourcepawn/vm/jit/x86/jit_x86.h index 49198999..ee54e78e 100644 --- a/sourcepawn/vm/jit/x86/jit_x86.h +++ b/sourcepawn/vm/jit/x86/jit_x86.h @@ -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; diff --git a/sourcepawn/vm/jit/x86/opcode_helpers.cpp b/sourcepawn/vm/jit/x86/opcode_helpers.cpp index 92cea6e1..55b45e71 100644 --- a/sourcepawn/vm/jit/x86/opcode_helpers.cpp +++ b/sourcepawn/vm/jit/x86/opcode_helpers.cpp @@ -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+] - 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] diff --git a/sourcepawn/vm/jit/x86/opcode_helpers.h b/sourcepawn/vm/jit/x86/opcode_helpers.h index 9859bd4a..5e303efc 100644 --- a/sourcepawn/vm/jit/x86/opcode_helpers.h +++ b/sourcepawn/vm/jit/x86/opcode_helpers.h @@ -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 diff --git a/sourcepawn/vm/jit/x86/opcode_switch.inc b/sourcepawn/vm/jit/x86/opcode_switch.inc index 759fbe1b..4f389db7 100644 --- a/sourcepawn/vm/jit/x86/opcode_switch.inc +++ b/sourcepawn/vm/jit/x86/opcode_switch.inc @@ -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; } \ No newline at end of file diff --git a/sourcepawn/vm/sp_vm_basecontext.cpp b/sourcepawn/vm/sp_vm_basecontext.cpp index 718f230b..34c38b23 100644 --- a/sourcepawn/vm/sp_vm_basecontext.cpp +++ b/sourcepawn/vm/sp_vm_basecontext.cpp @@ -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; isp += (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; } diff --git a/sourcepawn/vm/sp_vm_engine.cpp b/sourcepawn/vm/sp_vm_engine.cpp index fa3d2a79..1e108263 100644 --- a/sourcepawn/vm/sp_vm_engine.cpp +++ b/sourcepawn/vm/sp_vm_engine.cpp @@ -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; } diff --git a/sourcepawn/vm/test_main.cpp b/sourcepawn/vm/test_main.cpp index b6094321..c22c7dba 100644 --- a/sourcepawn/vm/test_main.cpp +++ b/sourcepawn/vm/test_main.cpp @@ -1,5 +1,6 @@ #include #include +#include #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);