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;
|
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
|
cell_t
|
||||||
NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ctx->err = PushTracker(ctx, bytes)) != SP_ERROR_NONE)
|
if ((ctx->err = rt->GetBaseContext()->pushTracker(bytes)) != SP_ERROR_NONE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (autozero)
|
if (autozero)
|
||||||
@ -849,7 +807,7 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
|
|||||||
case OP_TRACKER_PUSH_C:
|
case OP_TRACKER_PUSH_C:
|
||||||
{
|
{
|
||||||
cell_t amount = *cip++;
|
cell_t amount = *cip++;
|
||||||
int error = PushTracker(ctx, amount * 4);
|
int error = cx->pushTracker(amount * 4);
|
||||||
if (error != SP_ERROR_NONE) {
|
if (error != SP_ERROR_NONE) {
|
||||||
ctx->err = error;
|
ctx->err = error;
|
||||||
goto error;
|
goto error;
|
||||||
@ -859,7 +817,7 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
|
|||||||
|
|
||||||
case OP_TRACKER_POP_SETHEAP:
|
case OP_TRACKER_POP_SETHEAP:
|
||||||
{
|
{
|
||||||
int error = PopTrackerAndSetHeap(rt);
|
int error = cx->popTrackerAndSetHeap();
|
||||||
if (error != SP_ERROR_NONE) {
|
if (error != SP_ERROR_NONE) {
|
||||||
ctx->err = error;
|
ctx->err = error;
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -22,19 +22,10 @@
|
|||||||
#include "plugin-runtime.h"
|
#include "plugin-runtime.h"
|
||||||
#include "plugin-context.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 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 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);
|
||||||
int PopTrackerAndSetHeap(PluginRuntime *rt);
|
|
||||||
int PushTracker(sp_context_t *ctx, size_t amount);
|
|
||||||
|
|
||||||
#endif // _include_sourcepawn_interpreter_h_
|
#endif // _include_sourcepawn_interpreter_h_
|
||||||
|
@ -68,7 +68,6 @@ namespace SourcePawn
|
|||||||
} sp_plugin_t;
|
} sp_plugin_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tracker_t;
|
|
||||||
class PluginContext;
|
class PluginContext;
|
||||||
|
|
||||||
typedef struct sp_context_s
|
typedef struct sp_context_s
|
||||||
@ -81,7 +80,6 @@ typedef struct sp_context_s
|
|||||||
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 */
|
uint32_t n_idx; /**< Current native index being executed */
|
||||||
tracker_t *tracker;
|
|
||||||
sp_plugin_t *plugin;
|
sp_plugin_t *plugin;
|
||||||
PluginContext *basecx;
|
PluginContext *basecx;
|
||||||
} sp_context_t;
|
} sp_context_t;
|
||||||
|
@ -58,18 +58,16 @@ PluginContext::PluginContext(PluginRuntime *pRuntime)
|
|||||||
m_ctx.n_idx = SP_ERROR_NONE;
|
m_ctx.n_idx = SP_ERROR_NONE;
|
||||||
rp_ = 0;
|
rp_ = 0;
|
||||||
|
|
||||||
m_ctx.tracker = new tracker_t;
|
tracker_.pBase = (ucell_t *)malloc(1024);
|
||||||
m_ctx.tracker->pBase = (ucell_t *)malloc(1024);
|
tracker_.pCur = tracker_.pBase;
|
||||||
m_ctx.tracker->pCur = m_ctx.tracker->pBase;
|
tracker_.size = 1024 / sizeof(cell_t);
|
||||||
m_ctx.tracker->size = 1024 / sizeof(cell_t);
|
|
||||||
m_ctx.basecx = this;
|
m_ctx.basecx = this;
|
||||||
m_ctx.plugin = const_cast<sp_plugin_t *>(pRuntime->plugin());
|
m_ctx.plugin = const_cast<sp_plugin_t *>(pRuntime->plugin());
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginContext::~PluginContext()
|
PluginContext::~PluginContext()
|
||||||
{
|
{
|
||||||
free(m_ctx.tracker->pBase);
|
free(tracker_.pBase);
|
||||||
delete m_ctx.tracker;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IVirtualMachine *
|
IVirtualMachine *
|
||||||
@ -814,3 +812,41 @@ PluginContext::ClearLastNativeError()
|
|||||||
{
|
{
|
||||||
m_ctx.n_err = SP_ERROR_NONE;
|
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 "plugin-runtime.h"
|
||||||
#include "jit_shared.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
|
class PluginContext : public IPluginContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -82,6 +94,9 @@ class PluginContext : public IPluginContext
|
|||||||
static inline size_t offsetOfRstkCips() {
|
static inline size_t offsetOfRstkCips() {
|
||||||
return offsetof(PluginContext, rstk_cips_);
|
return offsetof(PluginContext, rstk_cips_);
|
||||||
}
|
}
|
||||||
|
static inline size_t offsetOfTracker() {
|
||||||
|
return offsetof(PluginContext, tracker_);
|
||||||
|
}
|
||||||
|
|
||||||
bool pushReturnCip(cell_t cip) {
|
bool pushReturnCip(cell_t cip) {
|
||||||
if (rp_ >= SP_MAX_RETURN_STACK)
|
if (rp_ >= SP_MAX_RETURN_STACK)
|
||||||
@ -101,6 +116,9 @@ class PluginContext : public IPluginContext
|
|||||||
return rstk_cips_[index];
|
return rstk_cips_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int popTrackerAndSetHeap();
|
||||||
|
int pushTracker(uint32_t amount);
|
||||||
|
|
||||||
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, ...);
|
||||||
@ -116,6 +134,9 @@ class PluginContext : public IPluginContext
|
|||||||
void *m_keys[4];
|
void *m_keys[4];
|
||||||
bool m_keys_set[4];
|
bool m_keys_set[4];
|
||||||
|
|
||||||
|
// Tracker for local HEA growth.
|
||||||
|
HeapTracker tracker_;
|
||||||
|
|
||||||
// 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];
|
||||||
|
@ -187,7 +187,7 @@ GenerateFullArray(PluginRuntime *rt, uint32_t argc, cell_t *argv, int autozero)
|
|||||||
if (dat_hp >= argv - STACK_MARGIN)
|
if (dat_hp >= argv - STACK_MARGIN)
|
||||||
return SP_ERROR_HEAPLOW;
|
return SP_ERROR_HEAPLOW;
|
||||||
|
|
||||||
if (int err = PushTracker(rt->GetBaseContext()->GetCtx(), bytes))
|
if (int err = rt->GetBaseContext()->pushTracker(bytes))
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
cell_t *base = reinterpret_cast<cell_t *>(rt->plugin()->memory + ctx->hp);
|
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());
|
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
|
bool
|
||||||
Compiler::emitOp(OPCODE op)
|
Compiler::emitOp(OPCODE op)
|
||||||
{
|
{
|
||||||
@ -1258,8 +1271,8 @@ Compiler::emitOp(OPCODE op)
|
|||||||
__ push(alt);
|
__ push(alt);
|
||||||
|
|
||||||
__ push(amount * 4);
|
__ push(amount * 4);
|
||||||
__ push(intptr_t(rt_->GetBaseContext()->GetCtx()));
|
__ push(intptr_t(rt_->GetBaseContext()));
|
||||||
__ call(ExternalAddress((void *)PushTracker));
|
__ call(ExternalAddress((void *)InvokePushTracker));
|
||||||
__ addl(esp, 8);
|
__ addl(esp, 8);
|
||||||
__ testl(eax, eax);
|
__ testl(eax, eax);
|
||||||
__ j(not_zero, &extern_error_);
|
__ j(not_zero, &extern_error_);
|
||||||
@ -1276,8 +1289,8 @@ Compiler::emitOp(OPCODE op)
|
|||||||
__ push(alt);
|
__ push(alt);
|
||||||
|
|
||||||
// Get the context pointer and call the sanity checker.
|
// Get the context pointer and call the sanity checker.
|
||||||
__ push(intptr_t(rt_));
|
__ push(intptr_t(rt_->GetBaseContext()));
|
||||||
__ call(ExternalAddress((void *)PopTrackerAndSetHeap));
|
__ call(ExternalAddress((void *)InvokePopTrackerAndSetHeap));
|
||||||
__ addl(esp, 4);
|
__ addl(esp, 4);
|
||||||
__ testl(eax, eax);
|
__ testl(eax, eax);
|
||||||
__ j(not_zero, &extern_error_);
|
__ j(not_zero, &extern_error_);
|
||||||
@ -1405,8 +1418,8 @@ Compiler::emitGenArray(bool autozero)
|
|||||||
|
|
||||||
__ shll(tmp, 2);
|
__ shll(tmp, 2);
|
||||||
__ push(tmp);
|
__ push(tmp);
|
||||||
__ push(intptr_t(rt_->GetBaseContext()->GetCtx()));
|
__ push(intptr_t(rt_->GetBaseContext()));
|
||||||
__ call(ExternalAddress((void *)PushTracker));
|
__ call(ExternalAddress((void *)InvokePushTracker));
|
||||||
__ addl(esp, 4);
|
__ addl(esp, 4);
|
||||||
__ pop(tmp);
|
__ pop(tmp);
|
||||||
__ shrl(tmp, 2);
|
__ shrl(tmp, 2);
|
||||||
|
Loading…
Reference in New Issue
Block a user