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