Move sp from sp_context_t to PluginContext.

This commit is contained in:
David Anderson 2015-02-24 21:06:06 -08:00
parent 4c9321f02a
commit b2c61a341a
9 changed files with 60 additions and 41 deletions

View File

@ -16,13 +16,13 @@
#include <stdint.h> #include <stdint.h>
#include <sp_vm_api.h> #include <sp_vm_api.h>
typedef struct sp_context_s sp_context_t; class PluginContext;
namespace sp { namespace sp {
class Environment; 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 class CodeStubs
{ {

View File

@ -239,7 +239,6 @@ int
Environment::Invoke(PluginRuntime *runtime, CompiledFunction *fn, cell_t *result) Environment::Invoke(PluginRuntime *runtime, CompiledFunction *fn, cell_t *result)
{ {
PluginContext *cx = runtime->GetBaseContext(); PluginContext *cx = runtime->GetBaseContext();
sp_context_t *ctx = cx->GetCtx();
// Note that cip, hp, sp are saved and restored by Execute2(). // Note that cip, hp, sp are saved and restored by Execute2().
*cx->addressOfCip() = fn->GetCodeOffset(); *cx->addressOfCip() = fn->GetCodeOffset();
@ -247,9 +246,8 @@ Environment::Invoke(PluginRuntime *runtime, CompiledFunction *fn, cell_t *result
InvokeStubFn invoke = code_stubs_->InvokeStub(); InvokeStubFn invoke = code_stubs_->InvokeStub();
EnterInvoke(); EnterInvoke();
int err = invoke(ctx, runtime->plugin()->memory, fn->GetEntryAddress()); int err = invoke(cx, fn->GetEntryAddress(), result);
LeaveInvoke(); LeaveInvoke();
*result = ctx->rval;
return err; return err;
} }

View File

@ -137,12 +137,13 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
// the stack unwinding code. // the stack unwinding code.
cell_t orig_frm = cx->frm(); cell_t orig_frm = cx->frm();
cell_t &frm = *cx->addressOfFrm();
cell_t &sp = *cx->addressOfSp();
cell_t pri = 0; cell_t pri = 0;
cell_t alt = 0; cell_t alt = 0;
cell_t *cip = code + (aCodeStart / 4); cell_t *cip = code + (aCodeStart / 4);
cell_t *stk = reinterpret_cast<cell_t *>(plugin->memory + ctx->sp); cell_t *stk = reinterpret_cast<cell_t *>(plugin->memory + sp);
cell_t &frm = *cx->addressOfFrm();
for (;;) { for (;;) {
if (cip >= codeend) { if (cip >= codeend) {
@ -808,11 +809,11 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
goto error; goto error;
} }
*cx->addressOfCip() = offset; *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); 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->addressOfCip() = rcip;
cx->popReturnCip(); cx->popReturnCip();
@ -848,7 +849,7 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
*--stk = num_params; *--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); pri = cx->invokeNative(native_index, stk);
if (cx->GetLastNativeError() != SP_ERROR_NONE) { if (cx->GetLastNativeError() != SP_ERROR_NONE) {
err = cx->GetLastNativeError(); err = cx->GetLastNativeError();
@ -892,7 +893,7 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
done: done:
assert(orig_frm == frm); assert(orig_frm == frm);
ctx->sp = uintptr_t(stk) - uintptr_t(plugin->memory); sp = uintptr_t(stk) - uintptr_t(plugin->memory);
return err; return err;
error: error:

View File

@ -73,7 +73,6 @@ class PluginContext;
typedef struct sp_context_s typedef struct sp_context_s
{ {
cell_t hp; /**< Heap pointer */ cell_t hp; /**< Heap pointer */
cell_t sp; /**< Stack pointer */
cell_t rval; /**< Return value from InvokeFunction() */ cell_t rval; /**< Return value from InvokeFunction() */
sp_plugin_t *plugin; sp_plugin_t *plugin;
PluginContext *basecx; PluginContext *basecx;

View File

@ -52,8 +52,8 @@ PluginContext::PluginContext(PluginRuntime *pRuntime)
} }
m_ctx.hp = m_pRuntime->plugin()->data_size; m_ctx.hp = m_pRuntime->plugin()->data_size;
m_ctx.sp = m_pRuntime->plugin()->mem_size - sizeof(cell_t); sp_ = m_pRuntime->plugin()->mem_size - sizeof(cell_t);
frm_ = m_ctx.sp; frm_ = sp_;
rp_ = 0; rp_ = 0;
last_native_ = -1; last_native_ = -1;
native_error_ = SP_ERROR_NONE; 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. * 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; return SP_ERROR_HEAPLOW;
addr = (cell_t *)(m_pRuntime->plugin()->memory + m_ctx.hp); 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 */ /* check the bounds of this address */
local_addr -= sizeof(cell_t); 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; return SP_ERROR_INVALID_ADDRESS;
addr = (cell_t *)(m_pRuntime->plugin()->memory + local_addr); addr = (cell_t *)(m_pRuntime->plugin()->memory + local_addr);
@ -325,7 +325,7 @@ PluginContext::BindNativeToAny(SPVM_NATIVE_FUNC native)
int int
PluginContext::LocalToPhysAddr(cell_t local_addr, cell_t **phys_addr) 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)) (local_addr < 0) || ((ucell_t)local_addr >= m_pRuntime->plugin()->mem_size))
{ {
return SP_ERROR_INVALID_ADDRESS; return SP_ERROR_INVALID_ADDRESS;
@ -358,7 +358,7 @@ PluginContext::PushCellArray(cell_t *local_addr, cell_t **phys_addr, cell_t arra
int int
PluginContext::LocalToString(cell_t local_addr, char **addr) 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)) (local_addr < 0) || ((ucell_t)local_addr >= m_pRuntime->plugin()->mem_size))
{ {
return SP_ERROR_INVALID_ADDRESS; return SP_ERROR_INVALID_ADDRESS;
@ -380,7 +380,7 @@ PluginContext::StringToLocal(cell_t local_addr, size_t bytes, const char *source
char *dest; char *dest;
size_t len; 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)) (local_addr < 0) || ((ucell_t)local_addr >= m_pRuntime->plugin()->mem_size))
{ {
return SP_ERROR_INVALID_ADDRESS; return SP_ERROR_INVALID_ADDRESS;
@ -443,7 +443,7 @@ PluginContext::StringToLocalUTF8(cell_t local_addr, size_t maxbytes, const char
size_t len; size_t len;
bool needtocheck = false; 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) || (local_addr < 0) ||
((ucell_t)local_addr >= m_pRuntime->plugin()->mem_size)) ((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()) if (m_pRuntime->IsPaused())
return SP_ERROR_NOT_RUNNABLE; 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; return SP_ERROR_STACKLOW;
if (result == NULL) if (result == NULL)
@ -578,7 +578,7 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne
uint32_t save_n_idx; uint32_t save_n_idx;
cell_t save_sp, save_hp, save_rp, save_cip; cell_t save_sp, save_hp, save_rp, save_cip;
save_sp = m_ctx.sp; save_sp = sp_;
save_hp = m_ctx.hp; save_hp = m_ctx.hp;
save_exec = m_InExec; save_exec = m_InExec;
save_n_idx = last_native_; save_n_idx = last_native_;
@ -587,8 +587,8 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne
/* Push parameters */ /* Push parameters */
m_ctx.sp -= sizeof(cell_t) * (num_params + 1); sp_ -= sizeof(cell_t) * (num_params + 1);
sp = (cell_t *)(m_pRuntime->plugin()->memory + m_ctx.sp); sp = (cell_t *)(m_pRuntime->plugin()->memory + sp_);
sp[0] = num_params; sp[0] = num_params;
for (unsigned int i = 0; i < num_params; i++) 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) { if (ir == SP_ERROR_NONE) {
native_error_ = SP_ERROR_NONE; native_error_ = SP_ERROR_NONE;
if (m_ctx.sp != save_sp) { if (sp_ != save_sp) {
ir = SP_ERROR_STACKLEAK; ir = SP_ERROR_STACKLEAK;
_SetErrorMessage("Stack leak detected: sp:%d should be %d!", _SetErrorMessage("Stack leak detected: sp:%d should be %d!",
m_ctx.sp, sp_,
save_sp); save_sp);
} }
if (m_ctx.hp != save_hp) { if (m_ctx.hp != save_hp) {
@ -640,7 +640,7 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne
if (ir != SP_ERROR_NONE) if (ir != SP_ERROR_NONE)
Environment::get()->ReportError(m_pRuntime, ir, m_MsgCache, save_rp); Environment::get()->ReportError(m_pRuntime, ir, m_MsgCache, save_rp);
m_ctx.sp = save_sp; sp_ = save_sp;
m_ctx.hp = save_hp; m_ctx.hp = save_hp;
rp_ = save_rp; rp_ = save_rp;
@ -854,7 +854,7 @@ PluginContext::pushTracker(uint32_t amount)
cell_t cell_t
PluginContext::invokeNative(ucell_t native_idx, cell_t *params) 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; cell_t save_hp = m_ctx.hp;
// Note: Invoke() saves the last native, so we don't need to here. // 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) if (native_error_ != SP_ERROR_NONE)
return result; return result;
if (save_sp != m_ctx.sp) { if (save_sp != sp_) {
native_error_ = SP_ERROR_STACKLEAK; native_error_ = SP_ERROR_STACKLEAK;
return result; return result;
} }
@ -887,7 +887,7 @@ PluginContext::invokeNative(ucell_t native_idx, cell_t *params)
cell_t cell_t
PluginContext::invokeBoundNative(SPVM_NATIVE_FUNC pfn, cell_t *params) 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 save_hp = m_ctx.hp;
cell_t result = pfn(this, params); 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) if (native_error_ != SP_ERROR_NONE)
return result; return result;
if (save_sp != m_ctx.sp) { if (save_sp != sp_) {
native_error_ = SP_ERROR_STACKLEAK; native_error_ = SP_ERROR_STACKLEAK;
return result; return result;
} }

View File

@ -103,10 +103,19 @@ class PluginContext : public IPluginContext
static inline size_t offsetOfNativeError() { static inline size_t offsetOfNativeError() {
return offsetof(PluginContext, native_error_); 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() { int32_t *addressOfCip() {
return &cip_; return &cip_;
} }
int32_t *addressOfSp() {
return &sp_;
}
cell_t *addressOfFrm() { cell_t *addressOfFrm() {
return &frm_; return &frm_;
} }
@ -175,7 +184,8 @@ class PluginContext : public IPluginContext
// Most recent CIP. // Most recent CIP.
int32_t cip_; int32_t cip_;
// Frame pointer. // Stack and frame pointer.
cell_t sp_;
cell_t frm_; cell_t frm_;
}; };

View File

@ -96,6 +96,10 @@ class PluginRuntime
return m_JitFunctions[i]; return m_JitFunctions[i];
} }
static inline size_t offsetToPlugin() {
return offsetof(PluginRuntime, m_plugin);
}
private: private:
void SetupFloatNativeRemapping(); void SetupFloatNativeRemapping();

View File

@ -47,12 +47,19 @@ CodeStubs::CompileInvokeStub()
__ push(ebx); // ebp - 12 __ push(ebx); // ebp - 12
__ push(esp); // ebp - 16 __ push(esp); // ebp - 16
// ebx = cx
__ movl(ebx, Operand(ebp, 8 + 4 * 0)); __ 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. // Set up run-time registers.
__ movl(edi, Operand(ebx, offsetof(sp_context_t, sp))); __ movl(edi, Operand(ebx, PluginContext::offsetOfSp()));
__ addl(edi, eax); __ addl(edi, eax);
__ movl(esi, eax); __ movl(esi, eax);
__ movl(ebx, edi); __ movl(ebx, edi);
@ -64,8 +71,8 @@ CodeStubs::CompileInvokeStub()
__ call(ecx); __ call(ecx);
// Get input context, store rval. // Get input context, store rval.
__ movl(ecx, Operand(ebp, 8 + 4 * 0)); __ movl(ecx, Operand(ebp, 8 + 4 * 2));
__ movl(Operand(ecx, offsetof(sp_context_t, rval)), pri); __ movl(Operand(ecx, 0), pri);
// Set no error. // Set no error.
__ movl(eax, SP_ERROR_NONE); __ movl(eax, SP_ERROR_NONE);
@ -75,7 +82,8 @@ CodeStubs::CompileInvokeStub()
Label ret; Label ret;
__ bind(&ret); __ bind(&ret);
__ subl(stk, dat); __ 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. // Restore stack.
__ movl(esp, Operand(ebp, -16)); __ movl(esp, Operand(ebp, -16));

View File

@ -1612,9 +1612,8 @@ Compiler::emitNativeCall(OPCODE op)
// 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()));
__ subl(stk, dat); __ 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); sp_native_t *native = rt_->GetNativeByIndex(native_index);
if ((native->status != SP_NATIVE_BOUND) || if ((native->status != SP_NATIVE_BOUND) ||