diff --git a/sourcepawn/vm/sp_vm.c b/sourcepawn/vm/sp_vm.c index 3e7ac7a3..d2896f5b 100644 --- a/sourcepawn/vm/sp_vm.c +++ b/sourcepawn/vm/sp_vm.c @@ -403,10 +403,6 @@ int SP_PushCellArray(sp_context_t *ctx, cell_t *local_addr, cell_t **phys_addr, } 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) { @@ -414,6 +410,11 @@ int SP_PushCellArray(sp_context_t *ctx, cell_t *local_addr, cell_t **phys_addr, return err; } + if (phys_addr) + { + *phys_addr = ph_addr; + } + return SP_ERR_NONE; } @@ -467,16 +468,43 @@ int SP_PushString(sp_context_t *ctx, cell_t *local_addr, cell_t **phys_addr, con } ph_addr[numcells] = '\0'; - if (phys_addr) - { - *phys_addr = ph_addr; - } - if ((err = SP_PushCell(ctx, *local_addr)) != SP_ERR_NONE) { SP_HeapRelease(ctx, *local_addr); return err; } + if (phys_addr) + { + *phys_addr = ph_addr; + } + + return SP_ERR_NONE; +} + +int SP_StringToLocal(sp_context_t *ctx, cell_t local_addr, size_t chars, const char *source) +{ + cell_t *dest; + size_t i, len; + + if (((local_addr >= ctx->hp) && (local_addr < ctx->sp)) || (local_addr < 0) || ((ucell_t)local_addr >= ctx->memory)) + { + return SP_ERR_INVALID_ADDRESS; + } + + len = strlen(source); + dest = (cell_t *)(ctx->data + local_addr); + + if (len >= chars) + { + len = chars - 1; + } + + for (i=0; i<len; i++) + { + dest[i] = (cell_t)source[i]; + } + dest[len] = '\0'; + return SP_ERR_NONE; } diff --git a/sourcepawn/vm/sp_vm_debug.c b/sourcepawn/vm/sp_vm_debug.c new file mode 100644 index 00000000..f3fc80e9 --- /dev/null +++ b/sourcepawn/vm/sp_vm_debug.c @@ -0,0 +1,88 @@ +#include "sp_vm.h" +#include "sp_vm_debug.h" + +int SP_DbgLookupFile(sp_context_t *ctx, ucell_t addr, const char **filename) +{ + uint32_t mid, low, high; + int diff; + + high = ctx->plugin->debug.files_num - 1; + low = 0; + + while (low <= high) + { + mid = (low + high) / 2; + diff = ctx->files[mid].addr - addr; + if (diff == 0) + { + *filename = ctx->files[mid].name; + return SP_ERR_NONE; + } else if (diff < 0) { + low = mid + 1; + } else { + high = mid - 1; + } + } + + return SP_ERR_NOT_FOUND; +} + +int SP_DbgLookupFunction(sp_context_t *ctx, ucell_t addr, const char **name) +{ + uint32_t iter, max = ctx->plugin->debug.syms_num; + + for (iter=0; iter<max; iter++) + { + if ((ctx->symbols[iter].sym->ident == SP_SYM_FUNCTION) + && (ctx->symbols[iter].codestart <= addr) + && (ctx->symbols[iter].codeend > addr)) + { + break; + } + } + + if (iter >= max) + { + return SP_ERR_NOT_FOUND; + } + + *name = ctx->symbols[iter].name; + + return SP_ERR_NONE; +} + +int SP_DbgLookupLine(sp_context_t *ctx, ucell_t addr, uint32_t *line) +{ + uint32_t mid, low, high; + int diff; + + high = ctx->plugin->debug.lines_num - 1; + low = 0; + + while (low <= high) + { + mid = (low + high) / 2; + diff = ctx->lines[mid].addr - addr; + if (diff == 0) + { + *line = ctx->lines[mid].line; + return SP_ERR_NONE; + } else if (diff < 0) { + low = mid + 1; + } else { + high = mid - 1; + } + } + + return SP_ERR_NOT_FOUND; +} + +int SP_DbgInstallBreak(sp_context_t *ctx, SPVM_DEBUGBREAK newpfn, SPVM_DEBUGBREAK *oldpfn) +{ + if (ctx->dbreak) + *oldpfn = ctx->dbreak; + + ctx->dbreak = newpfn; + + return SP_ERR_NONE; +}