push functions and some little fixes

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%4058
This commit is contained in:
Borja Ferrer 2006-08-04 19:09:41 +00:00
parent 4a324feac0
commit 84ec7c8713
3 changed files with 112 additions and 7 deletions

View File

@ -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)) if (!(plugin->pcode) || !(plugin->data) || !(plugin->info.stringbase))
{
goto return_error; goto return_error;
}
if ((plugin->flags == SP_FILE_DEBUG) && (!(plugin->debug.files) || !(plugin->debug.lines) || !(plugin->debug.symbols))) if ((plugin->flags == SP_FILE_DEBUG) && (!(plugin->debug.files) || !(plugin->debug.lines) || !(plugin->debug.symbols)))
{
goto return_error; goto return_error;
}
if (err) if (err)
{
*err = SP_ERR_NONE; *err = SP_ERR_NONE;
}
return plugin; return plugin;
return_error: return_error:
if (err) if (err)
{
*err = SP_ERR_FILE_FORMAT; *err = SP_ERR_FILE_FORMAT;
}
return NULL; return NULL;
} }
@ -180,7 +188,9 @@ sp_plugin_t *SP_LoadFromFilePointer(FILE *fp, int *err)
return_error: return_error:
if (err) if (err)
{
*err = error; *err = error;
}
return NULL; 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 (!_ReadPlugin(&hdr, base, plugin, err))
{ {
if (noptr) if (noptr)
{
free(plugin); free(plugin);
}
return NULL; return NULL;
} }

View File

@ -24,6 +24,7 @@ int main()
assert(SP_HeapRelease(&ctx, 4) == SP_ERR_INVALID_ADDRESS); assert(SP_HeapRelease(&ctx, 4) == SP_ERR_INVALID_ADDRESS);
assert(SP_HeapAlloc(&ctx, 500, &l, &p) == SP_ERR_NONE); assert(SP_HeapAlloc(&ctx, 500, &l, &p) == SP_ERR_NONE);
assert(SP_HeapRelease(&ctx, l) == SP_ERR_NONE); assert(SP_HeapRelease(&ctx, l) == SP_ERR_NONE);
assert(SP_PushCell(&ctx, 1337) == SP_ERR_NONE);
return 0; 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) 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; high = ctx->plugin->info.natives_num - 1;
low = 0; low = 0;
@ -121,7 +123,9 @@ int SP_FindNativeByName(sp_context_t *ctx, const char *name, uint32_t *index)
if (diff == 0) if (diff == 0)
{ {
if (index) if (index)
{
*index = mid; *index = mid;
}
return SP_ERR_NONE; return SP_ERR_NONE;
} else if (diff < 0) { } else if (diff < 0) {
low = mid + 1; 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) int SP_GetNativeByIndex(sp_context_t *ctx, uint32_t index, sp_native_t **native)
{ {
if (index >= ctx->plugin->info.natives_num) if (index >= ctx->plugin->info.natives_num)
{
return SP_ERR_INDEX; return SP_ERR_INDEX;
}
if (native) if (native)
{
*native = &(ctx->natives[index]); *native = &(ctx->natives[index]);
}
return SP_ERR_NONE; 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) 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; high = ctx->plugin->info.publics_num - 1;
low = 0; low = 0;
@ -165,7 +174,9 @@ int SP_FindPublicByName(sp_context_t *ctx, const char *name, uint32_t *index)
if (diff == 0) if (diff == 0)
{ {
if (index) if (index)
{
*index = mid; *index = mid;
}
return SP_ERR_NONE; return SP_ERR_NONE;
} else if (diff < 0) { } else if (diff < 0) {
low = mid + 1; 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) int SP_GetPublicByIndex(sp_context_t *ctx, uint32_t index, sp_public_t **pblic)
{ {
if (index >= ctx->plugin->info.publics_num) if (index >= ctx->plugin->info.publics_num)
{
return SP_ERR_INDEX; return SP_ERR_INDEX;
}
if (pblic) if (pblic)
{
*pblic = &(ctx->publics[index]); *pblic = &(ctx->publics[index]);
}
return SP_ERR_NONE; 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) int SP_GetPubvarByIndex(sp_context_t *ctx, uint32_t index, sp_pubvar_t **pubvar)
{ {
if (index >= ctx->plugin->info.pubvars_num) if (index >= ctx->plugin->info.pubvars_num)
{
return SP_ERR_INDEX; return SP_ERR_INDEX;
}
if (pubvar) if (pubvar)
{
*pubvar = &(ctx->pubvars[index]); *pubvar = &(ctx->pubvars[index]);
}
return SP_ERR_NONE; return SP_ERR_NONE;
} }
int SP_FindPubvarByName(sp_context_t *ctx, const char *name, uint32_t *index) 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; high = ctx->plugin->info.pubvars_num - 1;
low = 0; low = 0;
@ -220,7 +240,9 @@ int SP_FindPubvarByName(sp_context_t *ctx, const char *name, uint32_t *index)
if (diff == 0) if (diff == 0)
{ {
if (index) if (index)
{
*index = mid; *index = mid;
}
return SP_ERR_NONE; return SP_ERR_NONE;
} else if (diff < 0) { } else if (diff < 0) {
low = mid + 1; 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) 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) if (index >= ctx->plugin->info.pubvars_num)
{
return SP_ERR_INDEX; return SP_ERR_INDEX;
}
*local_addr = ctx->plugin->info.pubvars[index].address; *local_addr = ctx->plugin->info.pubvars[index].address;
*phys_addr = ctx->pubvars[index].offs; *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++) for (i=0; i<max; i++)
{ {
if ((ctx->natives[i].status == SP_NATIVE_OKAY) && !overwrite) if ((ctx->natives[i].status == SP_NATIVE_OKAY) && !overwrite)
{
continue; continue;
}
for (j=0; (natives[j].name) && (!num || j<num); j++) 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) 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) if ((err = SP_FindNativeByName(ctx, native->name, &index)) != SP_ERR_NONE)
{
return err; return err;
}
ctx->natives[index].pfn = native->func; ctx->natives[index].pfn = native->func;
ctx->natives[index].status = status; 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) 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)) if (((local_addr >= ctx->hp) && (local_addr < ctx->sp)) || (local_addr < 0) || ((ucell_t)local_addr >= ctx->memory))
{
return SP_ERR_INVALID_ADDRESS; return SP_ERR_INVALID_ADDRESS;
}
if (phys_addr) if (phys_addr)
{
*phys_addr = (cell_t *)(ctx->data + local_addr); *phys_addr = (cell_t *)(ctx->data + local_addr);
}
return SP_ERR_NONE; 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;
}

View File

@ -8,6 +8,7 @@
** Note that all functions return a non-zero error code on failure ** Note that all functions return a non-zero error code on failure
* unless otherwise noted. * unless otherwise noted.
* All input pointers must be valid unless otherwise noted as optional. * 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 * All local address are guaranteed to be positive. However, they are stored
* as signed integers, because they must logically fit inside a cell. * 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. * 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 * Note that this does not release the heap, so you should release it after
* calling SP_Execute(). * 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 * Individually pushes each cell of an array of cells onto the stack. Increases the
* parameter count by the number of cells pushed. * 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 ctx Context pointer.
* @param array Array of cells to read from. * @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); 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. * Status is automatically set to pending.
* *
* @param ctx Context pointer. * @param ctx Context pointer.