From b2c61a341a8112c84451dc08ed5d4e1857c07f48 Mon Sep 17 00:00:00 2001 From: David Anderson <dvander@alliedmods.net> Date: Tue, 24 Feb 2015 21:06:06 -0800 Subject: [PATCH] Move sp from sp_context_t to PluginContext. --- sourcepawn/jit/code-stubs.h | 4 +-- sourcepawn/jit/environment.cpp | 4 +-- sourcepawn/jit/interpreter.cpp | 15 ++++++----- sourcepawn/jit/jit_shared.h | 1 - sourcepawn/jit/plugin-context.cpp | 38 +++++++++++++-------------- sourcepawn/jit/plugin-context.h | 12 ++++++++- sourcepawn/jit/plugin-runtime.h | 4 +++ sourcepawn/jit/x86/code-stubs-x86.cpp | 20 +++++++++----- sourcepawn/jit/x86/jit_x86.cpp | 3 +-- 9 files changed, 60 insertions(+), 41 deletions(-) diff --git a/sourcepawn/jit/code-stubs.h b/sourcepawn/jit/code-stubs.h index 093ec7aa..045280de 100644 --- a/sourcepawn/jit/code-stubs.h +++ b/sourcepawn/jit/code-stubs.h @@ -16,13 +16,13 @@ #include <stdint.h> #include <sp_vm_api.h> -typedef struct sp_context_s sp_context_t; +class PluginContext; namespace sp { class Environment; -typedef int (*InvokeStubFn)(sp_context_t *ctx, uint8_t *memory, void *code); +typedef int (*InvokeStubFn)(PluginContext *cx, void *code, cell_t *rval); class CodeStubs { diff --git a/sourcepawn/jit/environment.cpp b/sourcepawn/jit/environment.cpp index 25e127e1..7c808817 100644 --- a/sourcepawn/jit/environment.cpp +++ b/sourcepawn/jit/environment.cpp @@ -239,7 +239,6 @@ int Environment::Invoke(PluginRuntime *runtime, CompiledFunction *fn, cell_t *result) { PluginContext *cx = runtime->GetBaseContext(); - sp_context_t *ctx = cx->GetCtx(); // Note that cip, hp, sp are saved and restored by Execute2(). *cx->addressOfCip() = fn->GetCodeOffset(); @@ -247,9 +246,8 @@ Environment::Invoke(PluginRuntime *runtime, CompiledFunction *fn, cell_t *result InvokeStubFn invoke = code_stubs_->InvokeStub(); EnterInvoke(); - int err = invoke(ctx, runtime->plugin()->memory, fn->GetEntryAddress()); + int err = invoke(cx, fn->GetEntryAddress(), result); LeaveInvoke(); - *result = ctx->rval; return err; } diff --git a/sourcepawn/jit/interpreter.cpp b/sourcepawn/jit/interpreter.cpp index 07badecc..f100a6d6 100644 --- a/sourcepawn/jit/interpreter.cpp +++ b/sourcepawn/jit/interpreter.cpp @@ -137,12 +137,13 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval) // the stack unwinding code. cell_t orig_frm = cx->frm(); + cell_t &frm = *cx->addressOfFrm(); + cell_t &sp = *cx->addressOfSp(); + cell_t pri = 0; cell_t alt = 0; cell_t *cip = code + (aCodeStart / 4); - cell_t *stk = reinterpret_cast<cell_t *>(plugin->memory + ctx->sp); - - cell_t &frm = *cx->addressOfFrm(); + cell_t *stk = reinterpret_cast<cell_t *>(plugin->memory + sp); for (;;) { if (cip >= codeend) { @@ -808,11 +809,11 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval) goto error; } *cx->addressOfCip() = offset; - ctx->sp = uintptr_t(stk) - uintptr_t(plugin->memory); + sp = uintptr_t(stk) - uintptr_t(plugin->memory); int err = Interpret(rt, offset, &pri); - stk = reinterpret_cast<cell_t *>(plugin->memory + ctx->sp); + stk = reinterpret_cast<cell_t *>(plugin->memory + sp); *cx->addressOfCip() = rcip; cx->popReturnCip(); @@ -848,7 +849,7 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval) *--stk = num_params; } - ctx->sp = uintptr_t(stk) - uintptr_t(plugin->memory); + sp = uintptr_t(stk) - uintptr_t(plugin->memory); pri = cx->invokeNative(native_index, stk); if (cx->GetLastNativeError() != SP_ERROR_NONE) { err = cx->GetLastNativeError(); @@ -892,7 +893,7 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval) done: assert(orig_frm == frm); - ctx->sp = uintptr_t(stk) - uintptr_t(plugin->memory); + sp = uintptr_t(stk) - uintptr_t(plugin->memory); return err; error: diff --git a/sourcepawn/jit/jit_shared.h b/sourcepawn/jit/jit_shared.h index 2c220d93..35486862 100644 --- a/sourcepawn/jit/jit_shared.h +++ b/sourcepawn/jit/jit_shared.h @@ -73,7 +73,6 @@ class PluginContext; typedef struct sp_context_s { cell_t hp; /**< Heap pointer */ - cell_t sp; /**< Stack pointer */ cell_t rval; /**< Return value from InvokeFunction() */ sp_plugin_t *plugin; PluginContext *basecx; diff --git a/sourcepawn/jit/plugin-context.cpp b/sourcepawn/jit/plugin-context.cpp index 58f7b4f8..6ea64b0b 100644 --- a/sourcepawn/jit/plugin-context.cpp +++ b/sourcepawn/jit/plugin-context.cpp @@ -52,8 +52,8 @@ PluginContext::PluginContext(PluginRuntime *pRuntime) } m_ctx.hp = m_pRuntime->plugin()->data_size; - m_ctx.sp = m_pRuntime->plugin()->mem_size - sizeof(cell_t); - frm_ = m_ctx.sp; + sp_ = m_pRuntime->plugin()->mem_size - sizeof(cell_t); + frm_ = sp_; rp_ = 0; last_native_ = -1; native_error_ = SP_ERROR_NONE; @@ -185,7 +185,7 @@ PluginContext::HeapAlloc(unsigned int cells, cell_t *local_addr, cell_t **phys_a /** * Check if the space between the heap and stack is sufficient. */ - if ((cell_t)(m_ctx.sp - m_ctx.hp - realmem) < STACKMARGIN) + if ((cell_t)(sp_ - m_ctx.hp - realmem) < STACKMARGIN) return SP_ERROR_HEAPLOW; addr = (cell_t *)(m_pRuntime->plugin()->memory + m_ctx.hp); @@ -212,7 +212,7 @@ PluginContext::HeapPop(cell_t local_addr) /* check the bounds of this address */ local_addr -= sizeof(cell_t); - if (local_addr < (cell_t)m_pRuntime->plugin()->data_size || local_addr >= m_ctx.sp) + if (local_addr < (cell_t)m_pRuntime->plugin()->data_size || local_addr >= sp_) return SP_ERROR_INVALID_ADDRESS; addr = (cell_t *)(m_pRuntime->plugin()->memory + local_addr); @@ -325,7 +325,7 @@ PluginContext::BindNativeToAny(SPVM_NATIVE_FUNC native) int PluginContext::LocalToPhysAddr(cell_t local_addr, cell_t **phys_addr) { - if (((local_addr >= m_ctx.hp) && (local_addr < m_ctx.sp)) || + if (((local_addr >= m_ctx.hp) && (local_addr < sp_)) || (local_addr < 0) || ((ucell_t)local_addr >= m_pRuntime->plugin()->mem_size)) { return SP_ERROR_INVALID_ADDRESS; @@ -358,7 +358,7 @@ PluginContext::PushCellArray(cell_t *local_addr, cell_t **phys_addr, cell_t arra int PluginContext::LocalToString(cell_t local_addr, char **addr) { - if (((local_addr >= m_ctx.hp) && (local_addr < m_ctx.sp)) || + if (((local_addr >= m_ctx.hp) && (local_addr < sp_)) || (local_addr < 0) || ((ucell_t)local_addr >= m_pRuntime->plugin()->mem_size)) { return SP_ERROR_INVALID_ADDRESS; @@ -380,7 +380,7 @@ PluginContext::StringToLocal(cell_t local_addr, size_t bytes, const char *source char *dest; size_t len; - if (((local_addr >= m_ctx.hp) && (local_addr < m_ctx.sp)) || + if (((local_addr >= m_ctx.hp) && (local_addr < sp_)) || (local_addr < 0) || ((ucell_t)local_addr >= m_pRuntime->plugin()->mem_size)) { return SP_ERROR_INVALID_ADDRESS; @@ -443,7 +443,7 @@ PluginContext::StringToLocalUTF8(cell_t local_addr, size_t maxbytes, const char size_t len; bool needtocheck = false; - if (((local_addr >= m_ctx.hp) && (local_addr < m_ctx.sp)) || + if (((local_addr >= m_ctx.hp) && (local_addr < sp_)) || (local_addr < 0) || ((ucell_t)local_addr >= m_pRuntime->plugin()->mem_size)) { @@ -548,7 +548,7 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne if (m_pRuntime->IsPaused()) return SP_ERROR_NOT_RUNNABLE; - if ((cell_t)(m_ctx.hp + 16*sizeof(cell_t)) > (cell_t)(m_ctx.sp - (sizeof(cell_t) * (num_params + 1)))) + if ((cell_t)(m_ctx.hp + 16*sizeof(cell_t)) > (cell_t)(sp_ - (sizeof(cell_t) * (num_params + 1)))) return SP_ERROR_STACKLOW; if (result == NULL) @@ -578,7 +578,7 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne uint32_t save_n_idx; cell_t save_sp, save_hp, save_rp, save_cip; - save_sp = m_ctx.sp; + save_sp = sp_; save_hp = m_ctx.hp; save_exec = m_InExec; save_n_idx = last_native_; @@ -587,8 +587,8 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne /* Push parameters */ - m_ctx.sp -= sizeof(cell_t) * (num_params + 1); - sp = (cell_t *)(m_pRuntime->plugin()->memory + m_ctx.sp); + sp_ -= sizeof(cell_t) * (num_params + 1); + sp = (cell_t *)(m_pRuntime->plugin()->memory + sp_); sp[0] = num_params; for (unsigned int i = 0; i < num_params; i++) @@ -614,10 +614,10 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne if (ir == SP_ERROR_NONE) { native_error_ = SP_ERROR_NONE; - if (m_ctx.sp != save_sp) { + if (sp_ != save_sp) { ir = SP_ERROR_STACKLEAK; _SetErrorMessage("Stack leak detected: sp:%d should be %d!", - m_ctx.sp, + sp_, save_sp); } if (m_ctx.hp != save_hp) { @@ -640,7 +640,7 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne if (ir != SP_ERROR_NONE) Environment::get()->ReportError(m_pRuntime, ir, m_MsgCache, save_rp); - m_ctx.sp = save_sp; + sp_ = save_sp; m_ctx.hp = save_hp; rp_ = save_rp; @@ -854,7 +854,7 @@ PluginContext::pushTracker(uint32_t amount) cell_t PluginContext::invokeNative(ucell_t native_idx, cell_t *params) { - cell_t save_sp = m_ctx.sp; + cell_t save_sp = sp_; cell_t save_hp = m_ctx.hp; // Note: Invoke() saves the last native, so we don't need to here. @@ -872,7 +872,7 @@ PluginContext::invokeNative(ucell_t native_idx, cell_t *params) if (native_error_ != SP_ERROR_NONE) return result; - if (save_sp != m_ctx.sp) { + if (save_sp != sp_) { native_error_ = SP_ERROR_STACKLEAK; return result; } @@ -887,7 +887,7 @@ PluginContext::invokeNative(ucell_t native_idx, cell_t *params) cell_t PluginContext::invokeBoundNative(SPVM_NATIVE_FUNC pfn, cell_t *params) { - cell_t save_sp = m_ctx.sp; + cell_t save_sp = sp_; cell_t save_hp = m_ctx.hp; cell_t result = pfn(this, params); @@ -895,7 +895,7 @@ PluginContext::invokeBoundNative(SPVM_NATIVE_FUNC pfn, cell_t *params) if (native_error_ != SP_ERROR_NONE) return result; - if (save_sp != m_ctx.sp) { + if (save_sp != sp_) { native_error_ = SP_ERROR_STACKLEAK; return result; } diff --git a/sourcepawn/jit/plugin-context.h b/sourcepawn/jit/plugin-context.h index e71301fa..4a78eac5 100644 --- a/sourcepawn/jit/plugin-context.h +++ b/sourcepawn/jit/plugin-context.h @@ -103,10 +103,19 @@ class PluginContext : public IPluginContext static inline size_t offsetOfNativeError() { return offsetof(PluginContext, native_error_); } + static inline size_t offsetOfSp() { + return offsetof(PluginContext, sp_); + } + static inline size_t offsetOfRuntime() { + return offsetof(PluginContext, m_pRuntime); + } int32_t *addressOfCip() { return &cip_; } + int32_t *addressOfSp() { + return &sp_; + } cell_t *addressOfFrm() { return &frm_; } @@ -175,7 +184,8 @@ class PluginContext : public IPluginContext // Most recent CIP. int32_t cip_; - // Frame pointer. + // Stack and frame pointer. + cell_t sp_; cell_t frm_; }; diff --git a/sourcepawn/jit/plugin-runtime.h b/sourcepawn/jit/plugin-runtime.h index 9f0706a0..1ced62dc 100644 --- a/sourcepawn/jit/plugin-runtime.h +++ b/sourcepawn/jit/plugin-runtime.h @@ -96,6 +96,10 @@ class PluginRuntime return m_JitFunctions[i]; } + static inline size_t offsetToPlugin() { + return offsetof(PluginRuntime, m_plugin); + } + private: void SetupFloatNativeRemapping(); diff --git a/sourcepawn/jit/x86/code-stubs-x86.cpp b/sourcepawn/jit/x86/code-stubs-x86.cpp index 2b7a4b94..9b85bb1a 100644 --- a/sourcepawn/jit/x86/code-stubs-x86.cpp +++ b/sourcepawn/jit/x86/code-stubs-x86.cpp @@ -47,12 +47,19 @@ CodeStubs::CompileInvokeStub() __ push(ebx); // ebp - 12 __ push(esp); // ebp - 16 + // ebx = cx __ movl(ebx, Operand(ebp, 8 + 4 * 0)); - __ movl(eax, Operand(ebp, 8 + 4 * 1)); - __ movl(ecx, Operand(ebp, 8 + 4 * 2)); + + // ecx = code + __ movl(ecx, Operand(ebp, 8 + 4 * 1)); + + // eax = cx->m_pRuntime->m_plugin.memory + __ movl(eax, Operand(ebx, PluginContext::offsetOfRuntime())); + __ addl(eax, PluginRuntime::offsetToPlugin()); + __ movl(eax, Operand(eax, offsetof(sp_plugin_t, memory))); // Set up run-time registers. - __ movl(edi, Operand(ebx, offsetof(sp_context_t, sp))); + __ movl(edi, Operand(ebx, PluginContext::offsetOfSp())); __ addl(edi, eax); __ movl(esi, eax); __ movl(ebx, edi); @@ -64,8 +71,8 @@ CodeStubs::CompileInvokeStub() __ call(ecx); // Get input context, store rval. - __ movl(ecx, Operand(ebp, 8 + 4 * 0)); - __ movl(Operand(ecx, offsetof(sp_context_t, rval)), pri); + __ movl(ecx, Operand(ebp, 8 + 4 * 2)); + __ movl(Operand(ecx, 0), pri); // Set no error. __ movl(eax, SP_ERROR_NONE); @@ -75,7 +82,8 @@ CodeStubs::CompileInvokeStub() Label ret; __ bind(&ret); __ subl(stk, dat); - __ movl(Operand(ecx, offsetof(sp_context_t, sp)), stk); + __ movl(ecx, Operand(ebp, 8 + 4 * 0)); + __ movl(Operand(ecx, PluginContext::offsetOfSp()), stk); // Restore stack. __ movl(esp, Operand(ebp, -16)); diff --git a/sourcepawn/jit/x86/jit_x86.cpp b/sourcepawn/jit/x86/jit_x86.cpp index f0b0fbbf..576c6d1e 100644 --- a/sourcepawn/jit/x86/jit_x86.cpp +++ b/sourcepawn/jit/x86/jit_x86.cpp @@ -1612,9 +1612,8 @@ Compiler::emitNativeCall(OPCODE op) // Relocate our absolute stk to be dat-relative, and update the context's // view. - __ movl(eax, intptr_t(rt_->GetBaseContext()->GetCtx())); __ subl(stk, dat); - __ movl(Operand(eax, offsetof(sp_context_t, sp)), stk); + __ movl(Operand(eax, PluginContext::offsetOfSp()), stk); sp_native_t *native = rt_->GetNativeByIndex(native_index); if ((native->status != SP_NATIVE_BOUND) ||