diff --git a/sourcepawn/jit/jit_shared.h b/sourcepawn/jit/jit_shared.h index 59dc780e..c533bb74 100644 --- a/sourcepawn/jit/jit_shared.h +++ b/sourcepawn/jit/jit_shared.h @@ -1,3 +1,4 @@ +// vim: set ts=4 sw=4 tw=99 noet: #ifndef _INCLUDE_SOURCEPAWN_JIT_SHARED_H_ #define _INCLUDE_SOURCEPAWN_JIT_SHARED_H_ @@ -71,6 +72,7 @@ typedef struct sp_context_s cell_t hp; /**< Heap pointer */ cell_t sp; /**< Stack pointer */ cell_t frm; /**< Frame pointer */ + cell_t rval; /**< Return value from InvokeFunction() */ int32_t err_cip; /**< Code pointer last error occurred in */ int32_t n_err; /**< Error code set by a native */ uint32_t n_idx; /**< Current native index being executed */ diff --git a/sourcepawn/jit/opcodes.cpp b/sourcepawn/jit/opcodes.cpp index 83a0ce9e..ef50eacf 100644 --- a/sourcepawn/jit/opcodes.cpp +++ b/sourcepawn/jit/opcodes.cpp @@ -70,6 +70,8 @@ SourcePawn::SpewOpcode(const sp_plugin_t *plugin, cell_t *start, cell_t *cip) case OP_HEAP: case OP_GENARRAY: case OP_GENARRAY_Z: + case OP_CONST_PRI: + case OP_CONST_ALT: fprintf(stdout, "%d", cip[1]); break; diff --git a/sourcepawn/jit/x86/jit_x86.cpp b/sourcepawn/jit/x86/jit_x86.cpp index 222e37e5..69cf83ec 100644 --- a/sourcepawn/jit/x86/jit_x86.cpp +++ b/sourcepawn/jit/x86/jit_x86.cpp @@ -1304,8 +1304,8 @@ Compiler::emitOp(OPCODE op) case OP_HALT: __ align(16); - __ movl(tmp, Operand(info, AMX_INFO_RETVAL)); - __ movl(Operand(ecx, 0), pri); + __ movl(tmp, intptr_t(rt_->GetBaseContext()->GetCtx())); + __ movl(Operand(tmp, offsetof(sp_context_t, rval)), pri); __ movl(pri, readCell()); __ jmp(&extern_error_); break; @@ -1755,13 +1755,15 @@ Compiler::emitErrorPaths() } } +typedef int (*JIT_EXECUTE)(InfoVars *vars, void *addr, uint8_t *memory, sp_context_t *ctx); + static void * GenerateEntry(void **retp) { AssemblerX86 masm; // Variables we're passed in: - // InfoVars *vars, void *entry, uint8_t *memory + // InfoVars *vars, void *entry, uint8_t *memory, sp_context_t * __ push(ebp); __ movl(ebp, esp); @@ -1787,23 +1789,36 @@ GenerateEntry(void **retp) // Call into plugin (align the stack first). __ call(ecx); - __ movl(ecx, Operand(info, AMX_INFO_RETVAL)); - __ movl(Operand(ecx, 0), pri); + // Restore stack. + __ movl(esp, Operand(info, AMX_INFO_NSTACK)); + + // Get input context. + __ movl(ecx, Operand(esp, 32)); + __ movl(Operand(ecx, offsetof(sp_context_t, rval)), pri); + + // Set no error. __ movl(eax, SP_ERROR_NONE); - // If stuff goes wrong, it'll jump directly to here. - Label error; - __ bind(&error); - __ movl(esp, Operand(info, AMX_INFO_NSTACK)); + // Store latest stk. If we have an error code, we'll jump directly to here, + // so eax will already be set. + Label ret; + __ bind(&ret); __ subl(stk, dat); __ movl(Operand(esi, AMX_INFO_FRAME), stk); + // Restore registers and gtfo. __ pop(ebx); __ pop(edi); __ pop(esi); __ pop(ebp); __ ret(); + // The universal emergency return will jump to here. + Label error; + __ bind(&error); + __ movl(esp, Operand(info, AMX_INFO_NSTACK)); + __ jmp(&ret); + void *code = LinkCode(masm); if (!code) return NULL; @@ -1953,29 +1968,24 @@ bool CompData::SetOption(const char *key, const char *val) return false; } -typedef int (*JIT_EXECUTE)(InfoVars *vars, void *addr, uint8_t *memory); int JITX86::InvokeFunction(BaseRuntime *runtime, JitFunction *fn, cell_t *result) { - int err; - JIT_EXECUTE pfn; - sp_context_t *ctx; + sp_context_t *ctx = runtime->GetBaseContext()->GetCtx(); + InfoVars vars; - - ctx = runtime->GetBaseContext()->GetCtx(); - vars.frm = ctx->sp; vars.hp = ctx->hp; - vars.rval = result; vars.cip = fn->GetPCodeAddress(); /* vars.esp will be set in the entry code */ - pfn = (JIT_EXECUTE)m_pJitEntry; - err = pfn(&vars, fn->GetEntryAddress(), runtime->plugin()->memory); + JIT_EXECUTE pfn = (JIT_EXECUTE)m_pJitEntry; + int err = pfn(&vars, fn->GetEntryAddress(), runtime->plugin()->memory, ctx); ctx->sp = vars.frm; ctx->hp = vars.hp; ctx->err_cip = vars.cip; + *result = ctx->rval; return err; } diff --git a/sourcepawn/jit/x86/jit_x86.h b/sourcepawn/jit/x86/jit_x86.h index ebb27b0f..f2dd4270 100644 --- a/sourcepawn/jit/x86/jit_x86.h +++ b/sourcepawn/jit/x86/jit_x86.h @@ -197,14 +197,12 @@ const Register frm = ebx; struct InfoVars { ucell_t frm; ucell_t hp; - cell_t *rval; ucell_t cip; void *esp; }; #define AMX_INFO_FRAME offsetof(InfoVars, frm) #define AMX_INFO_HEAP offsetof(InfoVars, hp) -#define AMX_INFO_RETVAL offsetof(InfoVars, rval) #define AMX_INFO_CIP offsetof(InfoVars, cip) #define AMX_INFO_NSTACK offsetof(InfoVars, esp)