Move the tracker from sp_context_t to PluginContext.
This commit is contained in:
parent
deedc1aaa6
commit
5502fbbdc1
@ -95,48 +95,6 @@ CheckAddress(const sp_plugin_t *plugin, sp_context_t *ctx, cell_t *stk, cell_t a
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
PopTrackerAndSetHeap(PluginRuntime *rt)
|
||||
{
|
||||
sp_context_t *ctx = rt->GetBaseContext()->GetCtx();
|
||||
tracker_t *trk = ctx->tracker;
|
||||
assert(trk->pCur > trk->pBase);
|
||||
|
||||
trk->pCur--;
|
||||
if (trk->pCur < trk->pBase)
|
||||
return SP_ERROR_TRACKER_BOUNDS;
|
||||
|
||||
ucell_t amt = *trk->pCur;
|
||||
if (amt > (ctx->hp - rt->plugin()->data_size))
|
||||
return SP_ERROR_HEAPMIN;
|
||||
|
||||
ctx->hp -= amt;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
PushTracker(sp_context_t *ctx, size_t amount)
|
||||
{
|
||||
tracker_t *trk = ctx->tracker;
|
||||
|
||||
if ((size_t)(trk->pCur - trk->pBase) >= trk->size)
|
||||
return SP_ERROR_TRACKER_BOUNDS;
|
||||
|
||||
if (trk->pCur + 1 - (trk->pBase + trk->size) == 0) {
|
||||
size_t disp = trk->size - 1;
|
||||
trk->size *= 2;
|
||||
trk->pBase = (ucell_t *)realloc(trk->pBase, trk->size * sizeof(cell_t));
|
||||
|
||||
if (!trk->pBase)
|
||||
return SP_ERROR_TRACKER_BOUNDS;
|
||||
|
||||
trk->pCur = trk->pBase + disp;
|
||||
}
|
||||
|
||||
*trk->pCur++ = amount;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
cell_t
|
||||
NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
|
||||
{
|
||||
@ -211,7 +169,7 @@ GenerateArray(PluginRuntime *rt, sp_context_t *ctx, cell_t dims, cell_t *stk, bo
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((ctx->err = PushTracker(ctx, bytes)) != SP_ERROR_NONE)
|
||||
if ((ctx->err = rt->GetBaseContext()->pushTracker(bytes)) != SP_ERROR_NONE)
|
||||
return false;
|
||||
|
||||
if (autozero)
|
||||
@ -849,7 +807,7 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
|
||||
case OP_TRACKER_PUSH_C:
|
||||
{
|
||||
cell_t amount = *cip++;
|
||||
int error = PushTracker(ctx, amount * 4);
|
||||
int error = cx->pushTracker(amount * 4);
|
||||
if (error != SP_ERROR_NONE) {
|
||||
ctx->err = error;
|
||||
goto error;
|
||||
@ -859,7 +817,7 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
|
||||
|
||||
case OP_TRACKER_POP_SETHEAP:
|
||||
{
|
||||
int error = PopTrackerAndSetHeap(rt);
|
||||
int error = cx->popTrackerAndSetHeap();
|
||||
if (error != SP_ERROR_NONE) {
|
||||
ctx->err = error;
|
||||
goto error;
|
||||
|
@ -22,19 +22,10 @@
|
||||
#include "plugin-runtime.h"
|
||||
#include "plugin-context.h"
|
||||
|
||||
struct tracker_t
|
||||
{
|
||||
size_t size;
|
||||
ucell_t *pBase;
|
||||
ucell_t *pCur;
|
||||
};
|
||||
|
||||
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);
|
||||
int PopTrackerAndSetHeap(PluginRuntime *rt);
|
||||
int PushTracker(sp_context_t *ctx, size_t amount);
|
||||
|
||||
#endif // _include_sourcepawn_interpreter_h_
|
||||
|
@ -68,7 +68,6 @@ namespace SourcePawn
|
||||
} sp_plugin_t;
|
||||
}
|
||||
|
||||
struct tracker_t;
|
||||
class PluginContext;
|
||||
|
||||
typedef struct sp_context_s
|
||||
@ -81,7 +80,6 @@ typedef struct sp_context_s
|
||||
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 */
|
||||
tracker_t *tracker;
|
||||
sp_plugin_t *plugin;
|
||||
PluginContext *basecx;
|
||||
} sp_context_t;
|
||||
|
@ -58,18 +58,16 @@ PluginContext::PluginContext(PluginRuntime *pRuntime)
|
||||
m_ctx.n_idx = SP_ERROR_NONE;
|
||||
rp_ = 0;
|
||||
|
||||
m_ctx.tracker = new tracker_t;
|
||||
m_ctx.tracker->pBase = (ucell_t *)malloc(1024);
|
||||
m_ctx.tracker->pCur = m_ctx.tracker->pBase;
|
||||
m_ctx.tracker->size = 1024 / sizeof(cell_t);
|
||||
tracker_.pBase = (ucell_t *)malloc(1024);
|
||||
tracker_.pCur = tracker_.pBase;
|
||||
tracker_.size = 1024 / sizeof(cell_t);
|
||||
m_ctx.basecx = this;
|
||||
m_ctx.plugin = const_cast<sp_plugin_t *>(pRuntime->plugin());
|
||||
}
|
||||
|
||||
PluginContext::~PluginContext()
|
||||
{
|
||||
free(m_ctx.tracker->pBase);
|
||||
delete m_ctx.tracker;
|
||||
free(tracker_.pBase);
|
||||
}
|
||||
|
||||
IVirtualMachine *
|
||||
@ -814,3 +812,41 @@ PluginContext::ClearLastNativeError()
|
||||
{
|
||||
m_ctx.n_err = SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
PluginContext::popTrackerAndSetHeap()
|
||||
{
|
||||
assert(tracker_.pCur > tracker_.pBase);
|
||||
|
||||
tracker_.pCur--;
|
||||
if (tracker_.pCur < tracker_.pBase)
|
||||
return SP_ERROR_TRACKER_BOUNDS;
|
||||
|
||||
ucell_t amt = *tracker_.pCur;
|
||||
if (amt > (m_ctx.hp - m_pRuntime->plugin()->data_size))
|
||||
return SP_ERROR_HEAPMIN;
|
||||
|
||||
m_ctx.hp -= amt;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
PluginContext::pushTracker(uint32_t amount)
|
||||
{
|
||||
if ((size_t)(tracker_.pCur - tracker_.pBase) >= tracker_.size)
|
||||
return SP_ERROR_TRACKER_BOUNDS;
|
||||
|
||||
if (tracker_.pCur + 1 - (tracker_.pBase + tracker_.size) == 0) {
|
||||
size_t disp = tracker_.size - 1;
|
||||
tracker_.size *= 2;
|
||||
tracker_.pBase = (ucell_t *)realloc(tracker_.pBase, tracker_.size * sizeof(cell_t));
|
||||
|
||||
if (!tracker_.pBase)
|
||||
return SP_ERROR_TRACKER_BOUNDS;
|
||||
|
||||
tracker_.pCur = tracker_.pBase + disp;
|
||||
}
|
||||
|
||||
*tracker_.pCur++ = amount;
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
@ -18,6 +18,18 @@
|
||||
#include "plugin-runtime.h"
|
||||
#include "jit_shared.h"
|
||||
|
||||
struct HeapTracker
|
||||
{
|
||||
HeapTracker()
|
||||
: size(0),
|
||||
pBase(nullptr),
|
||||
pCur(nullptr)
|
||||
{}
|
||||
size_t size;
|
||||
ucell_t *pBase;
|
||||
ucell_t *pCur;
|
||||
};
|
||||
|
||||
class PluginContext : public IPluginContext
|
||||
{
|
||||
public:
|
||||
@ -82,6 +94,9 @@ class PluginContext : public IPluginContext
|
||||
static inline size_t offsetOfRstkCips() {
|
||||
return offsetof(PluginContext, rstk_cips_);
|
||||
}
|
||||
static inline size_t offsetOfTracker() {
|
||||
return offsetof(PluginContext, tracker_);
|
||||
}
|
||||
|
||||
bool pushReturnCip(cell_t cip) {
|
||||
if (rp_ >= SP_MAX_RETURN_STACK)
|
||||
@ -101,6 +116,9 @@ class PluginContext : public IPluginContext
|
||||
return rstk_cips_[index];
|
||||
}
|
||||
|
||||
int popTrackerAndSetHeap();
|
||||
int pushTracker(uint32_t amount);
|
||||
|
||||
private:
|
||||
void SetErrorMessage(const char *msg, va_list ap);
|
||||
void _SetErrorMessage(const char *msg, ...);
|
||||
@ -116,6 +134,9 @@ class PluginContext : public IPluginContext
|
||||
void *m_keys[4];
|
||||
bool m_keys_set[4];
|
||||
|
||||
// Tracker for local HEA growth.
|
||||
HeapTracker tracker_;
|
||||
|
||||
// Return stack.
|
||||
cell_t rp_;
|
||||
cell_t rstk_cips_[SP_MAX_RETURN_STACK];
|
||||
|
@ -187,7 +187,7 @@ GenerateFullArray(PluginRuntime *rt, uint32_t argc, cell_t *argv, int autozero)
|
||||
if (dat_hp >= argv - STACK_MARGIN)
|
||||
return SP_ERROR_HEAPLOW;
|
||||
|
||||
if (int err = PushTracker(rt->GetBaseContext()->GetCtx(), bytes))
|
||||
if (int err = rt->GetBaseContext()->pushTracker(bytes))
|
||||
return err;
|
||||
|
||||
cell_t *base = reinterpret_cast<cell_t *>(rt->plugin()->memory + ctx->hp);
|
||||
@ -384,6 +384,19 @@ Compiler::emit(int *errp)
|
||||
return new CompiledFunction(code, pcode_start_, edges.take());
|
||||
}
|
||||
|
||||
// Helpers for invoking context members.
|
||||
static int
|
||||
InvokePushTracker(PluginContext *cx, uint32_t amount)
|
||||
{
|
||||
return cx->pushTracker(amount);
|
||||
}
|
||||
|
||||
static int
|
||||
InvokePopTrackerAndSetHeap(PluginContext *cx)
|
||||
{
|
||||
return cx->popTrackerAndSetHeap();
|
||||
}
|
||||
|
||||
bool
|
||||
Compiler::emitOp(OPCODE op)
|
||||
{
|
||||
@ -1258,8 +1271,8 @@ Compiler::emitOp(OPCODE op)
|
||||
__ push(alt);
|
||||
|
||||
__ push(amount * 4);
|
||||
__ push(intptr_t(rt_->GetBaseContext()->GetCtx()));
|
||||
__ call(ExternalAddress((void *)PushTracker));
|
||||
__ push(intptr_t(rt_->GetBaseContext()));
|
||||
__ call(ExternalAddress((void *)InvokePushTracker));
|
||||
__ addl(esp, 8);
|
||||
__ testl(eax, eax);
|
||||
__ j(not_zero, &extern_error_);
|
||||
@ -1276,8 +1289,8 @@ Compiler::emitOp(OPCODE op)
|
||||
__ push(alt);
|
||||
|
||||
// Get the context pointer and call the sanity checker.
|
||||
__ push(intptr_t(rt_));
|
||||
__ call(ExternalAddress((void *)PopTrackerAndSetHeap));
|
||||
__ push(intptr_t(rt_->GetBaseContext()));
|
||||
__ call(ExternalAddress((void *)InvokePopTrackerAndSetHeap));
|
||||
__ addl(esp, 4);
|
||||
__ testl(eax, eax);
|
||||
__ j(not_zero, &extern_error_);
|
||||
@ -1405,8 +1418,8 @@ Compiler::emitGenArray(bool autozero)
|
||||
|
||||
__ shll(tmp, 2);
|
||||
__ push(tmp);
|
||||
__ push(intptr_t(rt_->GetBaseContext()->GetCtx()));
|
||||
__ call(ExternalAddress((void *)PushTracker));
|
||||
__ push(intptr_t(rt_->GetBaseContext()));
|
||||
__ call(ExternalAddress((void *)InvokePushTracker));
|
||||
__ addl(esp, 4);
|
||||
__ pop(tmp);
|
||||
__ shrl(tmp, 2);
|
||||
|
Loading…
Reference in New Issue
Block a user