core/sourcemod.cpp
author David Anderson <dvander@alliedmods.net>
Wed Nov 08 07:32:44 2006 +0000 (2006-11-08)
changeset 160 c056af9b4aaf
child 176 c1699993453c
permissions -rw-r--r--
began JIT integration
     1 #include <stdio.h>
     2 #include "sourcemod.h"
     3 #include "sourcemm_api.h"
     4 #include "systems/LibrarySys.h"
     5 #include "vm/sp_vm_engine.h"
     6 #include <sh_string.h>
     7 
     8 SourcePawnEngine g_SourcePawn;
     9 SourceModBase g_SourceMod;
    10 
    11 ILibrary *g_pJIT = NULL;
    12 SourceHook::String g_BaseDir;
    13 ISourcePawnEngine *g_pSourcePawn = &g_SourcePawn;
    14 IVirtualMachine *g_pVM;
    15 
    16 typedef int (*GIVEENGINEPOINTER)(ISourcePawnEngine *);
    17 typedef unsigned int (*GETEXPORTCOUNT)();
    18 typedef IVirtualMachine *(*GETEXPORT)(unsigned int);
    19 typedef void (*NOTIFYSHUTDOWN)();
    20 
    21 void ShutdownJIT()
    22 {
    23 	NOTIFYSHUTDOWN notify = (NOTIFYSHUTDOWN)g_pJIT->GetSymbolAddress("NotifyShutdown");
    24 	if (notify)
    25 	{
    26 		notify();
    27 	}
    28 
    29 	g_pJIT->CloseLibrary();
    30 }
    31 
    32 bool SourceModBase::InitializeSourceMod(char *error, size_t err_max, bool late)
    33 {
    34 	//:TODO: we need a localinfo system!
    35 	g_BaseDir.assign(g_SMAPI->GetBaseDir());
    36 
    37 	/* Attempt to load the JIT! */
    38 	char file[PLATFORM_MAX_PATH];
    39 	char myerror[255];
    40 	g_SMAPI->PathFormat(file, sizeof(file), "%s/addons/sourcemod/bin/sourcepawn.jit.x86.%s",
    41 		g_BaseDir.c_str(),
    42 		PLATFORM_LIB_EXT
    43 		);
    44 
    45 	g_pJIT = g_LibSys.OpenLibrary(file, myerror, sizeof(myerror));
    46 	if (!g_pJIT)
    47 	{
    48 		if (error && err_max)
    49 		{
    50 			snprintf(error, err_max, "%s (failed to load bin/sourcepawn.jit.x86.%s)", 
    51 				myerror,
    52 				PLATFORM_LIB_EXT);
    53 		}
    54 		return false;
    55 	}
    56 
    57 	int err;
    58 	GIVEENGINEPOINTER jit_init = (GIVEENGINEPOINTER)g_pJIT->GetSymbolAddress("GiveEnginePointer");
    59 	if (!jit_init)
    60 	{
    61 		ShutdownJIT();
    62 		if (error && err_max)
    63 		{
    64 			snprintf(error, err_max, "Failed to find GiveEnginePointer in JIT!");
    65 		}
    66 		return false;
    67 	}
    68 
    69 	if ((err=jit_init(g_pSourcePawn)) != 0)
    70 	{
    71 		ShutdownJIT();
    72 		if (error && err_max)
    73 		{
    74 			snprintf(error, err_max, "GiveEnginePointer returned %d in the JIT", err);
    75 		}
    76 		return false;
    77 	}
    78 
    79 	GETEXPORTCOUNT jit_getnum = (GETEXPORTCOUNT)g_pJIT->GetSymbolAddress("GetExportCount");
    80 	GETEXPORT jit_get = (GETEXPORT)g_pJIT->GetSymbolAddress("GetExport");
    81 	if (!jit_get)
    82 	{
    83 		ShutdownJIT();
    84 		if (error && err_max)
    85 		{
    86 			snprintf(error, err_max, "JIT is missing a necessary export!");
    87 		}
    88 		return false;
    89 	}
    90 
    91 	unsigned int num = jit_getnum();
    92 	if (!num || ((g_pVM=jit_get(0)) == NULL))
    93 	{
    94 		ShutdownJIT();
    95 		if (error && err_max)
    96 		{
    97 			snprintf(error, err_max, "JIT did not export any virtual machines!");
    98 		}
    99 		return false;
   100 	}
   101 
   102 	return true;
   103 }