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:
parent
4b6c4f11af
commit
d2cb27e20c
@ -20,7 +20,7 @@
|
|||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
ConfigurationType="1"
|
ConfigurationType="1"
|
||||||
CharacterSet="1"
|
CharacterSet="2"
|
||||||
>
|
>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCPreBuildEventTool"
|
Name="VCPreBuildEventTool"
|
||||||
@ -44,7 +44,7 @@
|
|||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="1"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
Detect64BitPortabilityProblems="false"
|
Detect64BitPortabilityProblems="false"
|
||||||
@ -183,6 +183,10 @@
|
|||||||
RelativePath="..\sp_vm_engine.cpp"
|
RelativePath="..\sp_vm_engine.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\test_main.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
|
@ -51,6 +51,8 @@ int BaseContext::Execute(uint32_t public_func, cell_t *result)
|
|||||||
{
|
{
|
||||||
IVirtualMachine *vm = (IVirtualMachine *)ctx->vmbase;
|
IVirtualMachine *vm = (IVirtualMachine *)ctx->vmbase;
|
||||||
|
|
||||||
|
uint32_t pushcount = ctx->pushcount;
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
sp_public_t *pubfunc;
|
sp_public_t *pubfunc;
|
||||||
if ((err=GetPublicByIndex(public_func, &pubfunc)) != SP_ERR_NONE)
|
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;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
PushCell(ctx->pushcount);
|
PushCell(pushcount++);
|
||||||
ctx->pushcount = 0;
|
ctx->pushcount = 0;
|
||||||
|
|
||||||
cell_t save_sp = ctx->sp;
|
cell_t save_sp = ctx->sp;
|
||||||
cell_t save_hp = ctx->hp;
|
cell_t save_hp = ctx->hp;
|
||||||
|
|
||||||
err = vm->ContextExecute(ctx, pubfunc->offs, result);
|
err = vm->ContextExecute(ctx, pubfunc->offs, result);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* :TODO: turn this into an error check
|
||||||
|
*/
|
||||||
|
|
||||||
ctx->sp = save_sp;
|
#if defined _DEBUG
|
||||||
ctx->hp = save_hp;
|
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;
|
return err;
|
||||||
}
|
}
|
||||||
@ -89,8 +105,8 @@ int BaseContext::HeapAlloc(unsigned int cells, cell_t *local_addr, cell_t **phys
|
|||||||
realmem = cells * sizeof(cell_t);
|
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)
|
if ((cell_t)(ctx->sp - ctx->hp - realmem) < STACKMARGIN)
|
||||||
{
|
{
|
||||||
return SP_ERR_HEAPLOW;
|
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)))
|
if ((ctx->hp + STACKMARGIN) > (cell_t)(ctx->sp - sizeof(cell_t)))
|
||||||
{
|
{
|
||||||
return SP_ERR_STACKERR;
|
return SP_ERR_STACKLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->sp -= sizeof(cell_t);
|
ctx->sp -= sizeof(cell_t);
|
||||||
|
@ -70,18 +70,18 @@ namespace SourcePawn
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates executable memory.
|
* Allocates executable memory.
|
||||||
*
|
*
|
||||||
* @param size Size of memory to allocate.
|
* @param size Size of memory to allocate.
|
||||||
* @return Pointer to memory, NULL if allocation failed.
|
* @return Pointer to memory, NULL if allocation failed.
|
||||||
*/
|
*/
|
||||||
void *ExecAlloc(size_t size);
|
void *ExecAlloc(size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees executable memory.
|
* Frees executable memory.
|
||||||
*
|
*
|
||||||
* @param mem Address to free.
|
* @param mem Address to free.
|
||||||
*/
|
*/
|
||||||
void ExecFree(void *address);
|
void ExecFree(void *address);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
72
sourcepawn/vm/test_main.cpp
Normal file
72
sourcepawn/vm/test_main.cpp
Normal 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);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user