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
This commit is contained in:
David Anderson 2006-10-10 02:06:50 +00:00
parent 4b6c4f11af
commit d2cb27e20c
4 changed files with 109 additions and 17 deletions

View File

@ -20,7 +20,7 @@
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
@ -44,7 +44,7 @@
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@ -183,6 +183,10 @@
RelativePath="..\sp_vm_engine.cpp"
>
</File>
<File
RelativePath="..\test_main.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"

View File

@ -51,6 +51,8 @@ int BaseContext::Execute(uint32_t public_func, cell_t *result)
{
IVirtualMachine *vm = (IVirtualMachine *)ctx->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);

View File

@ -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);
};
};

View File

@ -0,0 +1,72 @@
#include <stdio.h>
#include <sp_vm_api.h>
#include "sp_vm_engine.h"
#include "sp_vm_basecontext.h"
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
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);
}