Move nidx from sp_context_t to PluginContext.
This commit is contained in:
parent
5502fbbdc1
commit
9c104ef310
@ -108,12 +108,16 @@ CContextTrace::GetLastNative(uint32_t *index)
|
|||||||
if (m_ctx->n_err == SP_ERROR_NONE)
|
if (m_ctx->n_err == SP_ERROR_NONE)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
int lastNative = context_->lastNative();
|
||||||
|
if (lastNative < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
sp_native_t *native;
|
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;
|
return NULL;
|
||||||
|
|
||||||
if (index)
|
if (index)
|
||||||
*index = m_ctx->n_idx;
|
*index = lastNative;
|
||||||
|
|
||||||
return native->name;
|
return native->name;
|
||||||
}
|
}
|
||||||
|
@ -95,61 +95,6 @@ CheckAddress(const sp_plugin_t *plugin, sp_context_t *ctx, cell_t *stk, cell_t a
|
|||||||
return true;
|
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
|
static inline bool
|
||||||
GenerateArray(PluginRuntime *rt, sp_context_t *ctx, cell_t dims, cell_t *stk, bool autozero)
|
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);
|
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) {
|
if (ctx->n_err != SP_ERROR_NONE) {
|
||||||
ctx->err = ctx->n_err;
|
ctx->err = ctx->n_err;
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
int Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval);
|
int Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval);
|
||||||
|
|
||||||
int GenerateFullArray(PluginRuntime *rt, uint32_t argc, cell_t *argv, int autozero);
|
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);
|
cell_t BoundNativeCallback(sp_context_t *ctx, SPVM_NATIVE_FUNC pfn, cell_t *params);
|
||||||
|
|
||||||
#endif // _include_sourcepawn_interpreter_h_
|
#endif // _include_sourcepawn_interpreter_h_
|
||||||
|
@ -79,7 +79,6 @@ typedef struct sp_context_s
|
|||||||
int32_t cip; /**< Code pointer last error occurred in */
|
int32_t cip; /**< Code pointer last error occurred in */
|
||||||
int32_t err; /**< Error last set by interpreter */
|
int32_t err; /**< Error last set by interpreter */
|
||||||
int32_t n_err; /**< Error code set by a native */
|
int32_t n_err; /**< Error code set by a native */
|
||||||
uint32_t n_idx; /**< Current native index being executed */
|
|
||||||
sp_plugin_t *plugin;
|
sp_plugin_t *plugin;
|
||||||
PluginContext *basecx;
|
PluginContext *basecx;
|
||||||
} sp_context_t;
|
} sp_context_t;
|
||||||
|
@ -55,8 +55,8 @@ PluginContext::PluginContext(PluginRuntime *pRuntime)
|
|||||||
m_ctx.sp = m_pRuntime->plugin()->mem_size - sizeof(cell_t);
|
m_ctx.sp = m_pRuntime->plugin()->mem_size - sizeof(cell_t);
|
||||||
m_ctx.frm = m_ctx.sp;
|
m_ctx.frm = m_ctx.sp;
|
||||||
m_ctx.n_err = SP_ERROR_NONE;
|
m_ctx.n_err = SP_ERROR_NONE;
|
||||||
m_ctx.n_idx = SP_ERROR_NONE;
|
|
||||||
rp_ = 0;
|
rp_ = 0;
|
||||||
|
last_native_ = -1;
|
||||||
|
|
||||||
tracker_.pBase = (ucell_t *)malloc(1024);
|
tracker_.pBase = (ucell_t *)malloc(1024);
|
||||||
tracker_.pCur = tracker_.pBase;
|
tracker_.pCur = tracker_.pBase;
|
||||||
@ -581,7 +581,7 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne
|
|||||||
save_sp = m_ctx.sp;
|
save_sp = m_ctx.sp;
|
||||||
save_hp = m_ctx.hp;
|
save_hp = m_ctx.hp;
|
||||||
save_exec = m_InExec;
|
save_exec = m_InExec;
|
||||||
save_n_idx = m_ctx.n_idx;
|
save_n_idx = last_native_;
|
||||||
save_rp = rp_;
|
save_rp = rp_;
|
||||||
save_cip = m_ctx.cip;
|
save_cip = m_ctx.cip;
|
||||||
|
|
||||||
@ -596,7 +596,7 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne
|
|||||||
|
|
||||||
/* Clear internal state */
|
/* Clear internal state */
|
||||||
m_ctx.n_err = SP_ERROR_NONE;
|
m_ctx.n_err = SP_ERROR_NONE;
|
||||||
m_ctx.n_idx = 0;
|
last_native_ = -1;
|
||||||
m_MsgCache[0] = '\0';
|
m_MsgCache[0] = '\0';
|
||||||
m_CustomMsg = false;
|
m_CustomMsg = false;
|
||||||
m_InExec = true;
|
m_InExec = true;
|
||||||
@ -645,7 +645,7 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne
|
|||||||
rp_ = save_rp;
|
rp_ = save_rp;
|
||||||
|
|
||||||
m_ctx.cip = save_cip;
|
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_ctx.n_err = SP_ERROR_NONE;
|
||||||
m_MsgCache[0] = '\0';
|
m_MsgCache[0] = '\0';
|
||||||
m_CustomMsg = false;
|
m_CustomMsg = false;
|
||||||
@ -850,3 +850,59 @@ PluginContext::pushTracker(uint32_t amount)
|
|||||||
*tracker_.pCur++ = amount;
|
*tracker_.pCur++ = amount;
|
||||||
return SP_ERROR_NONE;
|
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;
|
||||||
|
}
|
||||||
|
@ -97,7 +97,11 @@ class PluginContext : public IPluginContext
|
|||||||
static inline size_t offsetOfTracker() {
|
static inline size_t offsetOfTracker() {
|
||||||
return offsetof(PluginContext, tracker_);
|
return offsetof(PluginContext, tracker_);
|
||||||
}
|
}
|
||||||
|
static inline size_t offsetOfLastNative() {
|
||||||
|
return offsetof(PluginContext, last_native_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return stack logic.
|
||||||
bool pushReturnCip(cell_t cip) {
|
bool pushReturnCip(cell_t cip) {
|
||||||
if (rp_ >= SP_MAX_RETURN_STACK)
|
if (rp_ >= SP_MAX_RETURN_STACK)
|
||||||
return false;
|
return false;
|
||||||
@ -119,6 +123,12 @@ class PluginContext : public IPluginContext
|
|||||||
int popTrackerAndSetHeap();
|
int popTrackerAndSetHeap();
|
||||||
int pushTracker(uint32_t amount);
|
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:
|
private:
|
||||||
void SetErrorMessage(const char *msg, va_list ap);
|
void SetErrorMessage(const char *msg, va_list ap);
|
||||||
void _SetErrorMessage(const char *msg, ...);
|
void _SetErrorMessage(const char *msg, ...);
|
||||||
@ -140,6 +150,9 @@ class PluginContext : public IPluginContext
|
|||||||
// Return stack.
|
// Return stack.
|
||||||
cell_t rp_;
|
cell_t rp_;
|
||||||
cell_t rstk_cips_[SP_MAX_RETURN_STACK];
|
cell_t rstk_cips_[SP_MAX_RETURN_STACK];
|
||||||
|
|
||||||
|
// Track the currently executing native index.
|
||||||
|
uint32_t last_native_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEPAWN_BASECONTEXT_H_
|
#endif //_INCLUDE_SOURCEPAWN_BASECONTEXT_H_
|
||||||
|
@ -397,6 +397,18 @@ InvokePopTrackerAndSetHeap(PluginContext *cx)
|
|||||||
return cx->popTrackerAndSetHeap();
|
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
|
bool
|
||||||
Compiler::emitOp(OPCODE op)
|
Compiler::emitOp(OPCODE op)
|
||||||
{
|
{
|
||||||
@ -1594,14 +1606,15 @@ Compiler::emitNativeCall(OPCODE op)
|
|||||||
// Push the last parameter for the C++ function.
|
// Push the last parameter for the C++ function.
|
||||||
__ push(stk);
|
__ 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
|
// Relocate our absolute stk to be dat-relative, and update the context's
|
||||||
// view.
|
// view.
|
||||||
__ movl(eax, intptr_t(rt_->GetBaseContext()->GetCtx()));
|
__ movl(eax, intptr_t(rt_->GetBaseContext()->GetCtx()));
|
||||||
__ subl(stk, dat);
|
__ subl(stk, dat);
|
||||||
__ movl(Operand(eax, offsetof(sp_context_t, sp)), stk);
|
__ 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);
|
sp_native_t *native = rt_->GetNativeByIndex(native_index);
|
||||||
if ((native->status != SP_NATIVE_BOUND) ||
|
if ((native->status != SP_NATIVE_BOUND) ||
|
||||||
(native->flags & (SP_NTVFLAG_OPTIONAL | SP_NTVFLAG_EPHEMERAL)))
|
(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
|
// The native is either unbound, or it could become unbound in the
|
||||||
// future. Invoke the slower native callback.
|
// future. Invoke the slower native callback.
|
||||||
__ push(native_index);
|
__ push(native_index);
|
||||||
__ push(eax);
|
__ push(intptr_t(rt_->GetBaseContext()));
|
||||||
__ call(ExternalAddress((void *)NativeCallback));
|
__ call(ExternalAddress((void *)InvokeNativeHelper));
|
||||||
} else {
|
} else {
|
||||||
// The native is bound so we have a few more guarantees.
|
// The native is bound so we have a few more guarantees.
|
||||||
__ push(intptr_t(native->pfn));
|
__ push(intptr_t(native->pfn));
|
||||||
__ push(eax);
|
__ push(intptr_t(rt_->GetBaseContext()));
|
||||||
__ call(ExternalAddress((void *)BoundNativeCallback));
|
__ call(ExternalAddress((void *)InvokeBoundNativeHelper));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for errors.
|
// Check for errors.
|
||||||
|
Loading…
Reference in New Issue
Block a user