From 84ec7c87133172e141ed00dd86a0911852f5db5c Mon Sep 17 00:00:00 2001 From: Borja Ferrer Date: Fri, 4 Aug 2006 19:09:41 +0000 Subject: [PATCH] push functions and some little fixes --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%4058 --- sourcepawn/vm/sp_reader.c | 12 +++++ sourcepawn/vm/sp_vm.c | 102 +++++++++++++++++++++++++++++++++++--- sourcepawn/vm/sp_vm.h | 5 +- 3 files changed, 112 insertions(+), 7 deletions(-) diff --git a/sourcepawn/vm/sp_reader.c b/sourcepawn/vm/sp_reader.c index 504cf69c..a0014c15 100644 --- a/sourcepawn/vm/sp_reader.c +++ b/sourcepawn/vm/sp_reader.c @@ -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; } diff --git a/sourcepawn/vm/sp_vm.c b/sourcepawn/vm/sp_vm.c index b1ec091c..60b7d627 100644 --- a/sourcepawn/vm/sp_vm.c +++ b/sourcepawn/vm/sp_vm.c @@ -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; inatives[i].status == SP_NATIVE_OKAY) && !overwrite) + { continue; + } for (j=0; (natives[j].name) && (!num || jname, &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; -} \ No newline at end of file +} + +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; isp += 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; +} diff --git a/sourcepawn/vm/sp_vm.h b/sourcepawn/vm/sp_vm.h index bba01c79..69fec20d 100644 --- a/sourcepawn/vm/sp_vm.h +++ b/sourcepawn/vm/sp_vm.h @@ -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.