core/sourcemod.cpp
author David Anderson <dvander@alliedmods.net>
Fri Dec 08 20:59:25 2006 +0000 (2006-12-08)
changeset 198 7086e8d2815e
parent 183 78488edd8873
child 209 fae1894d884c
permissions -rw-r--r--
removed debug code
     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 #include "PluginSys.h"
     8 #include "ForwardSys.h"
     9 
    10 SourcePawnEngine g_SourcePawn;
    11 SourceModBase g_SourceMod;
    12 
    13 ILibrary *g_pJIT = NULL;
    14 SourceHook::String g_BaseDir;
    15 ISourcePawnEngine *g_pSourcePawn = &g_SourcePawn;
    16 IVirtualMachine *g_pVM;
    17 
    18 typedef int (*GIVEENGINEPOINTER)(ISourcePawnEngine *);
    19 typedef unsigned int (*GETEXPORTCOUNT)();
    20 typedef IVirtualMachine *(*GETEXPORT)(unsigned int);
    21 typedef void (*NOTIFYSHUTDOWN)();
    22 
    23 void ShutdownJIT()
    24 {
    25 	NOTIFYSHUTDOWN notify = (NOTIFYSHUTDOWN)g_pJIT->GetSymbolAddress("NotifyShutdown");
    26 	if (notify)
    27 	{
    28 		notify();
    29 	}
    30 
    31 	g_pJIT->CloseLibrary();
    32 }
    33 
    34 bool SourceModBase::InitializeSourceMod(char *error, size_t err_max, bool late)
    35 {
    36 	//:TODO: we need a localinfo system!
    37 	g_BaseDir.assign(g_SMAPI->GetBaseDir());
    38 
    39 	/* Attempt to load the JIT! */
    40 	char file[PLATFORM_MAX_PATH];
    41 	char myerror[255];
    42 	g_SMAPI->PathFormat(file, sizeof(file), "%s/addons/sourcemod/bin/sourcepawn.jit.x86.%s",
    43 		g_BaseDir.c_str(),
    44 		PLATFORM_LIB_EXT
    45 		);
    46 
    47 	g_pJIT = g_LibSys.OpenLibrary(file, myerror, sizeof(myerror));
    48 	if (!g_pJIT)
    49 	{
    50 		if (error && err_max)
    51 		{
    52 			snprintf(error, err_max, "%s (failed to load bin/sourcepawn.jit.x86.%s)", 
    53 				myerror,
    54 				PLATFORM_LIB_EXT);
    55 		}
    56 		return false;
    57 	}
    58 
    59 	int err;
    60 	GIVEENGINEPOINTER jit_init = (GIVEENGINEPOINTER)g_pJIT->GetSymbolAddress("GiveEnginePointer");
    61 	if (!jit_init)
    62 	{
    63 		ShutdownJIT();
    64 		if (error && err_max)
    65 		{
    66 			snprintf(error, err_max, "Failed to find GiveEnginePointer in JIT!");
    67 		}
    68 		return false;
    69 	}
    70 
    71 	if ((err=jit_init(g_pSourcePawn)) != 0)
    72 	{
    73 		ShutdownJIT();
    74 		if (error && err_max)
    75 		{
    76 			snprintf(error, err_max, "GiveEnginePointer returned %d in the JIT", err);
    77 		}
    78 		return false;
    79 	}
    80 
    81 	GETEXPORTCOUNT jit_getnum = (GETEXPORTCOUNT)g_pJIT->GetSymbolAddress("GetExportCount");
    82 	GETEXPORT jit_get = (GETEXPORT)g_pJIT->GetSymbolAddress("GetExport");
    83 	if (!jit_get)
    84 	{
    85 		ShutdownJIT();
    86 		if (error && err_max)
    87 		{
    88 			snprintf(error, err_max, "JIT is missing a necessary export!");
    89 		}
    90 		return false;
    91 	}
    92 
    93 	unsigned int num = jit_getnum();
    94 	if (!num || ((g_pVM=jit_get(0)) == NULL))
    95 	{
    96 		ShutdownJIT();
    97 		if (error && err_max)
    98 		{
    99 			snprintf(error, err_max, "JIT did not export any virtual machines!");
   100 		}
   101 		return false;
   102 	}
   103 
   104 	unsigned int api = g_pVM->GetAPIVersion();
   105 	if (api != SOURCEPAWN_VM_API_VERSION)
   106 	{
   107 		ShutdownJIT();
   108 		if (error && err_max)
   109 		{
   110 			snprintf(error, err_max, "JIT is not a compatible version");
   111 		}
   112 		return false;
   113 	}
   114 
   115 	g_SMAPI->PathFormat(file, sizeof(file), "%s/addons/sourcemod/plugins/test.smx", g_BaseDir.c_str());
   116 	IPlugin *pPlugin = g_PluginMngr.LoadPlugin(file, false, PluginType_Global, error, err_max);
   117 	IPluginFunction *func = pPlugin->GetFunctionByName("Test");
   118 	IPluginFunction *func2 = pPlugin->GetFunctionByName("Test2");
   119 	cell_t result = 2;
   120 	cell_t val = 6;
   121 	ParamType types[] = {Param_Cell, Param_CellByRef};
   122 	va_list ap = va_start(ap, late);
   123 	CForward *fwd = CForward::CreateForward(NULL, ET_Custom, 2, types, ap);
   124 	fwd->AddFunction(func);
   125 	fwd->AddFunction(func2);
   126 	fwd->PushCell(1);
   127 	fwd->PushCellByRef(&val, 0);
   128 	fwd->Execute(&result, NULL);
   129 	g_PluginMngr.UnloadPlugin(pPlugin);
   130 
   131 	return true;
   132 }