From 9c104ef310dd84c42d07e895b397eb73cfbf1166 Mon Sep 17 00:00:00 2001 From: "dvander@alliedmods.net" Date: Tue, 24 Feb 2015 19:59:45 -0800 Subject: [PATCH] Move nidx from sp_context_t to PluginContext. --- sourcepawn/jit/debug-trace.cpp | 8 +++- sourcepawn/jit/interpreter.cpp | 57 +-------------------------- sourcepawn/jit/interpreter.h | 1 - sourcepawn/jit/jit_shared.h | 1 - sourcepawn/jit/plugin-context.cpp | 64 +++++++++++++++++++++++++++++-- sourcepawn/jit/plugin-context.h | 13 +++++++ sourcepawn/jit/x86/jit_x86.cpp | 25 +++++++++--- 7 files changed, 99 insertions(+), 70 deletions(-) diff --git a/sourcepawn/jit/debug-trace.cpp b/sourcepawn/jit/debug-trace.cpp index 569d3291..5aaef6ee 100644 --- a/sourcepawn/jit/debug-trace.cpp +++ b/sourcepawn/jit/debug-trace.cpp @@ -108,12 +108,16 @@ CContextTrace::GetLastNative(uint32_t *index) if (m_ctx->n_err == SP_ERROR_NONE) return NULL; + int lastNative = context_->lastNative(); + if (lastNative < 0) + return NULL; + sp_native_t *native; - if (m_pRuntime->GetNativeByIndex(m_ctx->n_idx, &native) != SP_ERROR_NONE) + if (m_pRuntime->GetNativeByIndex(lastNative, &native) != SP_ERROR_NONE) return NULL; if (index) - *index = m_ctx->n_idx; + *index = lastNative; return native->name; } diff --git a/sourcepawn/jit/interpreter.cpp b/sourcepawn/jit/interpreter.cpp index 0fa41014..a5eac421 100644 --- a/sourcepawn/jit/interpreter.cpp +++ b/sourcepawn/jit/interpreter.cpp @@ -95,61 +95,6 @@ CheckAddress(const sp_plugin_t *plugin, sp_context_t *ctx, cell_t *stk, cell_t a return true; } -cell_t -NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params) -{ - cell_t save_sp = ctx->sp; - cell_t save_hp = ctx->hp; - - ctx->n_idx = native_idx; - - sp_native_t *native = &ctx->plugin->natives[native_idx]; - - if (native->status == SP_NATIVE_UNBOUND) { - ctx->n_err = SP_ERROR_INVALID_NATIVE; - return 0; - } - - cell_t result = native->pfn(ctx->basecx, params); - - if (ctx->n_err != SP_ERROR_NONE) - return result; - - if (save_sp != ctx->sp) { - ctx->n_err = SP_ERROR_STACKLEAK; - return result; - } - if (save_hp != ctx->hp) { - ctx->n_err = SP_ERROR_HEAPLEAK; - return result; - } - - return result; -} - -cell_t -BoundNativeCallback(sp_context_t *ctx, SPVM_NATIVE_FUNC pfn, cell_t *params) -{ - cell_t save_sp = ctx->sp; - cell_t save_hp = ctx->hp; - - cell_t result = pfn(ctx->basecx, params); - - if (ctx->n_err != SP_ERROR_NONE) - return result; - - if (save_sp != ctx->sp) { - ctx->n_err = SP_ERROR_STACKLEAK; - return result; - } - if (save_hp != ctx->hp) { - ctx->n_err = SP_ERROR_HEAPLEAK; - return result; - } - - return result; -} - static inline bool GenerateArray(PluginRuntime *rt, sp_context_t *ctx, cell_t dims, cell_t *stk, bool autozero) { @@ -896,7 +841,7 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval) } ctx->sp = uintptr_t(stk) - uintptr_t(plugin->memory); - pri = NativeCallback(ctx, native_index, stk); + pri = cx->invokeNative(native_index, stk); if (ctx->n_err != SP_ERROR_NONE) { ctx->err = ctx->n_err; goto error; diff --git a/sourcepawn/jit/interpreter.h b/sourcepawn/jit/interpreter.h index ed73a55f..0274707a 100644 --- a/sourcepawn/jit/interpreter.h +++ b/sourcepawn/jit/interpreter.h @@ -25,7 +25,6 @@ int Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval); int GenerateFullArray(PluginRuntime *rt, uint32_t argc, cell_t *argv, int autozero); -cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params); cell_t BoundNativeCallback(sp_context_t *ctx, SPVM_NATIVE_FUNC pfn, cell_t *params); #endif // _include_sourcepawn_interpreter_h_ diff --git a/sourcepawn/jit/jit_shared.h b/sourcepawn/jit/jit_shared.h index 593d1db4..eea556e5 100644 --- a/sourcepawn/jit/jit_shared.h +++ b/sourcepawn/jit/jit_shared.h @@ -79,7 +79,6 @@ typedef struct sp_context_s int32_t cip; /**< Code pointer last error occurred in */ int32_t err; /**< Error last set by interpreter */ int32_t n_err; /**< Error code set by a native */ - uint32_t n_idx; /**< Current native index being executed */ sp_plugin_t *plugin; PluginContext *basecx; } sp_context_t; diff --git a/sourcepawn/jit/plugin-context.cpp b/sourcepawn/jit/plugin-context.cpp index 9b6cc381..f65f22eb 100644 --- a/sourcepawn/jit/plugin-context.cpp +++ b/sourcepawn/jit/plugin-context.cpp @@ -55,8 +55,8 @@ PluginContext::PluginContext(PluginRuntime *pRuntime) m_ctx.sp = m_pRuntime->plugin()->mem_size - sizeof(cell_t); m_ctx.frm = m_ctx.sp; m_ctx.n_err = SP_ERROR_NONE; - m_ctx.n_idx = SP_ERROR_NONE; rp_ = 0; + last_native_ = -1; tracker_.pBase = (ucell_t *)malloc(1024); tracker_.pCur = tracker_.pBase; @@ -581,7 +581,7 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne save_sp = m_ctx.sp; save_hp = m_ctx.hp; save_exec = m_InExec; - save_n_idx = m_ctx.n_idx; + save_n_idx = last_native_; save_rp = rp_; save_cip = m_ctx.cip; @@ -596,7 +596,7 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne /* Clear internal state */ m_ctx.n_err = SP_ERROR_NONE; - m_ctx.n_idx = 0; + last_native_ = -1; m_MsgCache[0] = '\0'; m_CustomMsg = false; m_InExec = true; @@ -645,7 +645,7 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne rp_ = save_rp; m_ctx.cip = save_cip; - m_ctx.n_idx = save_n_idx; + last_native_ = save_n_idx; m_ctx.n_err = SP_ERROR_NONE; m_MsgCache[0] = '\0'; m_CustomMsg = false; @@ -850,3 +850,59 @@ PluginContext::pushTracker(uint32_t amount) *tracker_.pCur++ = amount; return SP_ERROR_NONE; } + +cell_t +PluginContext::invokeNative(ucell_t native_idx, cell_t *params) +{ + cell_t save_sp = m_ctx.sp; + cell_t save_hp = m_ctx.hp; + + // Note: Invoke() saves the last native, so we don't need to here. + last_native_ = native_idx; + + sp_native_t *native = &m_pRuntime->plugin()->natives[native_idx]; + + if (native->status == SP_NATIVE_UNBOUND) { + m_ctx.n_err = SP_ERROR_INVALID_NATIVE; + return 0; + } + + cell_t result = native->pfn(m_ctx.basecx, params); + + if (m_ctx.n_err != SP_ERROR_NONE) + return result; + + if (save_sp != m_ctx.sp) { + m_ctx.n_err = SP_ERROR_STACKLEAK; + return result; + } + if (save_hp != m_ctx.hp) { + m_ctx.n_err = SP_ERROR_HEAPLEAK; + return result; + } + + return result; +} + +cell_t +PluginContext::invokeBoundNative(SPVM_NATIVE_FUNC pfn, cell_t *params) +{ + cell_t save_sp = m_ctx.sp; + cell_t save_hp = m_ctx.hp; + + cell_t result = pfn(this, params); + + if (m_ctx.n_err != SP_ERROR_NONE) + return result; + + if (save_sp != m_ctx.sp) { + m_ctx.n_err = SP_ERROR_STACKLEAK; + return result; + } + if (save_hp != m_ctx.hp) { + m_ctx.n_err = SP_ERROR_HEAPLEAK; + return result; + } + + return result; +} diff --git a/sourcepawn/jit/plugin-context.h b/sourcepawn/jit/plugin-context.h index b1f730d4..d00b7c04 100644 --- a/sourcepawn/jit/plugin-context.h +++ b/sourcepawn/jit/plugin-context.h @@ -97,7 +97,11 @@ class PluginContext : public IPluginContext static inline size_t offsetOfTracker() { return offsetof(PluginContext, tracker_); } + static inline size_t offsetOfLastNative() { + return offsetof(PluginContext, last_native_); + } + // Return stack logic. bool pushReturnCip(cell_t cip) { if (rp_ >= SP_MAX_RETURN_STACK) return false; @@ -119,6 +123,12 @@ class PluginContext : public IPluginContext int popTrackerAndSetHeap(); int pushTracker(uint32_t amount); + cell_t invokeNative(ucell_t native_idx, cell_t *params); + cell_t invokeBoundNative(SPVM_NATIVE_FUNC pfn, cell_t *params); + int lastNative() const { + return last_native_; + } + private: void SetErrorMessage(const char *msg, va_list ap); void _SetErrorMessage(const char *msg, ...); @@ -140,6 +150,9 @@ class PluginContext : public IPluginContext // Return stack. cell_t rp_; cell_t rstk_cips_[SP_MAX_RETURN_STACK]; + + // Track the currently executing native index. + uint32_t last_native_; }; #endif //_INCLUDE_SOURCEPAWN_BASECONTEXT_H_ diff --git a/sourcepawn/jit/x86/jit_x86.cpp b/sourcepawn/jit/x86/jit_x86.cpp index bcdad96a..93c2769d 100644 --- a/sourcepawn/jit/x86/jit_x86.cpp +++ b/sourcepawn/jit/x86/jit_x86.cpp @@ -397,6 +397,18 @@ InvokePopTrackerAndSetHeap(PluginContext *cx) return cx->popTrackerAndSetHeap(); } +static cell_t +InvokeNativeHelper(PluginContext *cx, ucell_t native_idx, cell_t *params) +{ + return cx->invokeNative(native_idx, params); +} + +static cell_t +InvokeBoundNativeHelper(PluginContext *cx, SPVM_NATIVE_FUNC fn, cell_t *params) +{ + return cx->invokeBoundNative(fn, params); +} + bool Compiler::emitOp(OPCODE op) { @@ -1594,14 +1606,15 @@ Compiler::emitNativeCall(OPCODE op) // Push the last parameter for the C++ function. __ push(stk); + __ movl(eax, intptr_t(rt_->GetBaseContext())); + __ movl(Operand(eax, PluginContext::offsetOfLastNative()), native_index); + // 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, offsetof(sp_context_t, n_idx)), native_index); - sp_native_t *native = rt_->GetNativeByIndex(native_index); if ((native->status != SP_NATIVE_BOUND) || (native->flags & (SP_NTVFLAG_OPTIONAL | SP_NTVFLAG_EPHEMERAL))) @@ -1609,13 +1622,13 @@ Compiler::emitNativeCall(OPCODE op) // The native is either unbound, or it could become unbound in the // future. Invoke the slower native callback. __ push(native_index); - __ push(eax); - __ call(ExternalAddress((void *)NativeCallback)); + __ push(intptr_t(rt_->GetBaseContext())); + __ call(ExternalAddress((void *)InvokeNativeHelper)); } else { // The native is bound so we have a few more guarantees. __ push(intptr_t(native->pfn)); - __ push(eax); - __ call(ExternalAddress((void *)BoundNativeCallback)); + __ push(intptr_t(rt_->GetBaseContext())); + __ call(ExternalAddress((void *)InvokeBoundNativeHelper)); } // Check for errors.