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))
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user