From d2cb27e20c93bd76869258cc4318e94e73b8109a Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 10 Oct 2006 02:06:50 +0000 Subject: [PATCH] added simple test procedure to VM and updated some context stuff for stack checking --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40111 --- sourcepawn/vm/msvc8/vm.vcproj | 8 +++- sourcepawn/vm/sp_vm_basecontext.cpp | 28 ++++++++--- sourcepawn/vm/sp_vm_engine.h | 18 ++++---- sourcepawn/vm/test_main.cpp | 72 +++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 17 deletions(-) create mode 100644 sourcepawn/vm/test_main.cpp diff --git a/sourcepawn/vm/msvc8/vm.vcproj b/sourcepawn/vm/msvc8/vm.vcproj index 3bd93d34..c57a6b54 100644 --- a/sourcepawn/vm/msvc8/vm.vcproj +++ b/sourcepawn/vm/msvc8/vm.vcproj @@ -20,7 +20,7 @@ OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" - CharacterSet="1" + CharacterSet="2" > + + vmbase; + uint32_t pushcount = ctx->pushcount; + int err; sp_public_t *pubfunc; if ((err=GetPublicByIndex(public_func, &pubfunc)) != SP_ERR_NONE) @@ -58,16 +60,30 @@ int BaseContext::Execute(uint32_t public_func, cell_t *result) return err; } - PushCell(ctx->pushcount); + PushCell(pushcount++); ctx->pushcount = 0; cell_t save_sp = ctx->sp; cell_t save_hp = ctx->hp; err = vm->ContextExecute(ctx, pubfunc->offs, result); + + /** + * :TODO: turn this into an error check + */ - ctx->sp = save_sp; - ctx->hp = save_hp; +#if defined _DEBUG + if (err == SP_ERR_NONE) + { + assert(ctx->sp - pushcount * sizeof(cell_t) == save_sp); + assert(ctx->hp == save_hp); + } +#endif + if (err != SP_ERR_NONE) + { + ctx->sp = save_sp; + ctx->hp = save_hp; + } return err; } @@ -89,8 +105,8 @@ int BaseContext::HeapAlloc(unsigned int cells, cell_t *local_addr, cell_t **phys realmem = cells * sizeof(cell_t); /** - * Check if the space between the heap and stack is sufficient. - */ + * Check if the space between the heap and stack is sufficient. + */ if ((cell_t)(ctx->sp - ctx->hp - realmem) < STACKMARGIN) { return SP_ERR_HEAPLOW; @@ -394,7 +410,7 @@ int BaseContext::PushCell(cell_t value) { if ((ctx->hp + STACKMARGIN) > (cell_t)(ctx->sp - sizeof(cell_t))) { - return SP_ERR_STACKERR; + return SP_ERR_STACKLOW; } ctx->sp -= sizeof(cell_t); diff --git a/sourcepawn/vm/sp_vm_engine.h b/sourcepawn/vm/sp_vm_engine.h index 66b38e6c..9a181c26 100644 --- a/sourcepawn/vm/sp_vm_engine.h +++ b/sourcepawn/vm/sp_vm_engine.h @@ -70,18 +70,18 @@ namespace SourcePawn /** - * Allocates executable memory. - * - * @param size Size of memory to allocate. - * @return Pointer to memory, NULL if allocation failed. - */ + * Allocates executable memory. + * + * @param size Size of memory to allocate. + * @return Pointer to memory, NULL if allocation failed. + */ void *ExecAlloc(size_t size); /** - * Frees executable memory. - * - * @param mem Address to free. - */ + * Frees executable memory. + * + * @param mem Address to free. + */ void ExecFree(void *address); }; }; diff --git a/sourcepawn/vm/test_main.cpp b/sourcepawn/vm/test_main.cpp new file mode 100644 index 00000000..b6094321 --- /dev/null +++ b/sourcepawn/vm/test_main.cpp @@ -0,0 +1,72 @@ +#include +#include +#include "sp_vm_engine.h" +#include "sp_vm_basecontext.h" +#define WINDOWS_LEAN_AND_MEAN +#include + +using namespace SourcePawn; + +typedef void (*GIVEENGINE)(ISourcePawnEngine *); +typedef IVirtualMachine *(*GETEXPORT)(unsigned int); + +int main() +{ + SourcePawnEngine engine; + IVirtualMachine *vm; + ICompilation *co; + sp_plugin_t *plugin = NULL; + sp_context_t *ctx = NULL; + cell_t result; + int err; + + /* Note: for now this is hardcoded for testing purposes! + * The ..\ should be one above msvc8. + */ + + FILE *fp = fopen("..\\test.smx", "rb"); + if (!fp) + { + return 0; + } + plugin = engine.LoadFromFilePointer(fp, &err); + if (err != SP_ERR_NONE) + { + printf("Error loading: %d", err); + return 0; + } + HMODULE dll = LoadLibrary("..\\jit\\x86\\msvc8\\Debug\\jit-x86.dll"); + if (dll == NULL) + { + printf("Error loading DLL: %d\n", GetLastError()); + return 0; + } + GIVEENGINE give_eng = (GIVEENGINE)GetProcAddress(dll, "GiveEnginePointer"); + if (!give_eng) + { + printf("Error getting \"GiveEnginePointer!\"!\n"); + return 0; + } + give_eng(&engine); + GETEXPORT getex = (GETEXPORT)GetProcAddress(dll, "GetExport"); + if ((vm=getex(0)) == NULL) + { + printf("GetExport() returned no VM!\n"); + return 0; + } + + co = vm->StartCompilation(plugin); + ctx = vm->CompileToContext(co, &err); + + IPluginContext *base = engine.CreateBaseContext(ctx); + + base->PushCell(1); + base->PushCell(5); + err = base->Execute(0, &result); + printf("Result: %d Error: %d\n", result, err); + + engine.FreeBaseContext(base); + + fclose(fp); + FreeLibrary(dll); +}