push functions and some little fixes
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%4058
This commit is contained in:
parent
4a324feac0
commit
84ec7c8713
@ -79,19 +79,27 @@ sp_plugin_t *_ReadPlugin(sp_file_hdr_t *hdr, uint8_t *base, sp_plugin_t *plugin,
|
||||
}
|
||||
|
||||
if (!(plugin->pcode) || !(plugin->data) || !(plugin->info.stringbase))
|
||||
{
|
||||
goto return_error;
|
||||
}
|
||||
|
||||
if ((plugin->flags == SP_FILE_DEBUG) && (!(plugin->debug.files) || !(plugin->debug.lines) || !(plugin->debug.symbols)))
|
||||
{
|
||||
goto return_error;
|
||||
}
|
||||
|
||||
if (err)
|
||||
{
|
||||
*err = SP_ERR_NONE;
|
||||
}
|
||||
|
||||
return plugin;
|
||||
|
||||
return_error:
|
||||
if (err)
|
||||
{
|
||||
*err = SP_ERR_FILE_FORMAT;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -180,7 +188,9 @@ sp_plugin_t *SP_LoadFromFilePointer(FILE *fp, int *err)
|
||||
|
||||
return_error:
|
||||
if (err)
|
||||
{
|
||||
*err = error;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -200,7 +210,9 @@ sp_plugin_t *SP_LoadFromMemory(void *base, sp_plugin_t *plugin, int *err)
|
||||
if (!_ReadPlugin(&hdr, base, plugin, err))
|
||||
{
|
||||
if (noptr)
|
||||
{
|
||||
free(plugin);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ int main()
|
||||
assert(SP_HeapRelease(&ctx, 4) == SP_ERR_INVALID_ADDRESS);
|
||||
assert(SP_HeapAlloc(&ctx, 500, &l, &p) == SP_ERR_NONE);
|
||||
assert(SP_HeapRelease(&ctx, l) == SP_ERR_NONE);
|
||||
assert(SP_PushCell(&ctx, 1337) == SP_ERR_NONE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -109,7 +110,8 @@ int SP_HeapRelease(sp_context_t *ctx, cell_t local_addr)
|
||||
|
||||
int SP_FindNativeByName(sp_context_t *ctx, const char *name, uint32_t *index)
|
||||
{
|
||||
uint32_t mid, low, high, diff;
|
||||
uint32_t mid, low, high;
|
||||
int diff;
|
||||
|
||||
high = ctx->plugin->info.natives_num - 1;
|
||||
low = 0;
|
||||
@ -121,7 +123,9 @@ int SP_FindNativeByName(sp_context_t *ctx, const char *name, uint32_t *index)
|
||||
if (diff == 0)
|
||||
{
|
||||
if (index)
|
||||
{
|
||||
*index = mid;
|
||||
}
|
||||
return SP_ERR_NONE;
|
||||
} else if (diff < 0) {
|
||||
low = mid + 1;
|
||||
@ -136,10 +140,14 @@ int SP_FindNativeByName(sp_context_t *ctx, const char *name, uint32_t *index)
|
||||
int SP_GetNativeByIndex(sp_context_t *ctx, uint32_t index, sp_native_t **native)
|
||||
{
|
||||
if (index >= ctx->plugin->info.natives_num)
|
||||
{
|
||||
return SP_ERR_INDEX;
|
||||
}
|
||||
|
||||
if (native)
|
||||
{
|
||||
*native = &(ctx->natives[index]);
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
}
|
||||
@ -153,7 +161,8 @@ int SP_GetNativesNum(sp_context_t *ctx, uint32_t *num)
|
||||
|
||||
int SP_FindPublicByName(sp_context_t *ctx, const char *name, uint32_t *index)
|
||||
{
|
||||
uint32_t mid, low, high, diff;
|
||||
uint32_t mid, low, high;
|
||||
int diff;
|
||||
|
||||
high = ctx->plugin->info.publics_num - 1;
|
||||
low = 0;
|
||||
@ -165,7 +174,9 @@ int SP_FindPublicByName(sp_context_t *ctx, const char *name, uint32_t *index)
|
||||
if (diff == 0)
|
||||
{
|
||||
if (index)
|
||||
{
|
||||
*index = mid;
|
||||
}
|
||||
return SP_ERR_NONE;
|
||||
} else if (diff < 0) {
|
||||
low = mid + 1;
|
||||
@ -180,10 +191,14 @@ int SP_FindPublicByName(sp_context_t *ctx, const char *name, uint32_t *index)
|
||||
int SP_GetPublicByIndex(sp_context_t *ctx, uint32_t index, sp_public_t **pblic)
|
||||
{
|
||||
if (index >= ctx->plugin->info.publics_num)
|
||||
{
|
||||
return SP_ERR_INDEX;
|
||||
}
|
||||
|
||||
if (pblic)
|
||||
{
|
||||
*pblic = &(ctx->publics[index]);
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
}
|
||||
@ -198,17 +213,22 @@ int SP_GetPublicsNum(sp_context_t *ctx, uint32_t *num)
|
||||
int SP_GetPubvarByIndex(sp_context_t *ctx, uint32_t index, sp_pubvar_t **pubvar)
|
||||
{
|
||||
if (index >= ctx->plugin->info.pubvars_num)
|
||||
{
|
||||
return SP_ERR_INDEX;
|
||||
}
|
||||
|
||||
if (pubvar)
|
||||
{
|
||||
*pubvar = &(ctx->pubvars[index]);
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
}
|
||||
|
||||
int SP_FindPubvarByName(sp_context_t *ctx, const char *name, uint32_t *index)
|
||||
{
|
||||
uint32_t mid, low, high, diff;
|
||||
uint32_t mid, low, high;
|
||||
int diff;
|
||||
|
||||
high = ctx->plugin->info.pubvars_num - 1;
|
||||
low = 0;
|
||||
@ -220,7 +240,9 @@ int SP_FindPubvarByName(sp_context_t *ctx, const char *name, uint32_t *index)
|
||||
if (diff == 0)
|
||||
{
|
||||
if (index)
|
||||
{
|
||||
*index = mid;
|
||||
}
|
||||
return SP_ERR_NONE;
|
||||
} else if (diff < 0) {
|
||||
low = mid + 1;
|
||||
@ -235,7 +257,9 @@ int SP_FindPubvarByName(sp_context_t *ctx, const char *name, uint32_t *index)
|
||||
int SP_GetPubvarAddrs(sp_context_t *ctx, uint32_t index, cell_t *local_addr, cell_t **phys_addr)
|
||||
{
|
||||
if (index >= ctx->plugin->info.pubvars_num)
|
||||
{
|
||||
return SP_ERR_INDEX;
|
||||
}
|
||||
|
||||
*local_addr = ctx->plugin->info.pubvars[index].address;
|
||||
*phys_addr = ctx->pubvars[index].offs;
|
||||
@ -259,7 +283,9 @@ int SP_BindNatives(sp_context_t *ctx, sp_nativeinfo_t *natives, unsigned int num
|
||||
for (i=0; i<max; i++)
|
||||
{
|
||||
if ((ctx->natives[i].status == SP_NATIVE_OKAY) && !overwrite)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j=0; (natives[j].name) && (!num || j<num); j++)
|
||||
{
|
||||
@ -276,10 +302,13 @@ int SP_BindNatives(sp_context_t *ctx, sp_nativeinfo_t *natives, unsigned int num
|
||||
|
||||
int SP_BindNative(sp_context_t *ctx, sp_nativeinfo_t *native, uint32_t status)
|
||||
{
|
||||
uint32_t index, err;
|
||||
uint32_t index;
|
||||
int err;
|
||||
|
||||
if ((err = SP_FindNativeByName(ctx, native->name, &index)) != SP_ERR_NONE)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
ctx->natives[index].pfn = native->func;
|
||||
ctx->natives[index].status = status;
|
||||
@ -308,10 +337,71 @@ int SP_BindNativeToAny(sp_context_t *ctx, SPVM_NATIVE_FUNC native)
|
||||
int SP_LocalToPhysAddr(sp_context_t *ctx, cell_t local_addr, cell_t **phys_addr)
|
||||
{
|
||||
if (((local_addr >= ctx->hp) && (local_addr < ctx->sp)) || (local_addr < 0) || ((ucell_t)local_addr >= ctx->memory))
|
||||
{
|
||||
return SP_ERR_INVALID_ADDRESS;
|
||||
|
||||
}
|
||||
|
||||
if (phys_addr)
|
||||
{
|
||||
*phys_addr = (cell_t *)(ctx->data + local_addr);
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
int SP_PushCell(sp_context_t *ctx, cell_t value)
|
||||
{
|
||||
if ((ctx->hp + STACKMARGIN) > (cell_t)(ctx->sp - sizeof(cell_t)))
|
||||
{
|
||||
return SP_ERR_HEAPLOW;
|
||||
}
|
||||
|
||||
ctx->sp -= sizeof(cell_t);
|
||||
*(cell_t *)(ctx->data + ctx->sp) = value;
|
||||
ctx->pushcount++;
|
||||
|
||||
return SP_ERR_NONE;
|
||||
}
|
||||
|
||||
int SP_PushCellsFromArray(sp_context_t *ctx, cell_t array[], unsigned int numcells)
|
||||
{
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
||||
for (i=0; i<numcells; i++)
|
||||
{
|
||||
if ((err = SP_PushCell(ctx, array[i])) != SP_ERR_NONE)
|
||||
{
|
||||
ctx->sp += i * sizeof(cell_t);
|
||||
ctx->pushcount -= i;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
}
|
||||
|
||||
int SP_PushCellArray(sp_context_t *ctx, cell_t *local_addr, cell_t **phys_addr, cell_t array[], unsigned int numcells)
|
||||
{
|
||||
cell_t *ph_addr;
|
||||
int err;
|
||||
|
||||
if ((err = SP_HeapAlloc(ctx, numcells, local_addr, &ph_addr)) != SP_ERR_NONE)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
memcpy(ph_addr, array, numcells * sizeof(cell_t));
|
||||
if (phys_addr)
|
||||
{
|
||||
*phys_addr = ph_addr;
|
||||
}
|
||||
|
||||
if ((err = SP_PushCell(ctx, *local_addr)) != SP_ERR_NONE)
|
||||
{
|
||||
SP_HeapRelease(ctx, *local_addr);
|
||||
return err;
|
||||
}
|
||||
|
||||
return SP_ERR_NONE;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
** Note that all functions return a non-zero error code on failure
|
||||
* unless otherwise noted.
|
||||
* All input pointers must be valid unless otherwise noted as optional.
|
||||
* All output pointers on failure are undefined.
|
||||
* All local address are guaranteed to be positive. However, they are stored
|
||||
* as signed integers, because they must logically fit inside a cell.
|
||||
*/
|
||||
@ -195,6 +196,7 @@ int SP_PushCell(sp_context_t *ctx, cell_t value);
|
||||
|
||||
/**
|
||||
* Pushes an array of cells onto the stack. Increases the parameter count by one.
|
||||
* If the function returns an error it will fail entirely, releasing anything allocated in the process.
|
||||
* Note that this does not release the heap, so you should release it after
|
||||
* calling SP_Execute().
|
||||
*
|
||||
@ -229,6 +231,7 @@ int SP_PushString(sp_context_t *ctx,
|
||||
/**
|
||||
* Individually pushes each cell of an array of cells onto the stack. Increases the
|
||||
* parameter count by the number of cells pushed.
|
||||
* If the function returns an error it will fail entirely, releasing anything allocated in the process.
|
||||
*
|
||||
* @param ctx Context pointer.
|
||||
* @param array Array of cells to read from.
|
||||
@ -260,7 +263,7 @@ int SP_BindNatives(sp_context_t *ctx, sp_nativeinfo_t *natives, unsigned int num
|
||||
int SP_BindNative(sp_context_t *ctx, sp_nativeinfo_t *native, uint32_t status);
|
||||
|
||||
/**
|
||||
* Binds a single native to any non-registered native.
|
||||
* Binds a single native to any non-registered or pending native.
|
||||
* Status is automatically set to pending.
|
||||
*
|
||||
* @param ctx Context pointer.
|
||||
|
Loading…
Reference in New Issue
Block a user