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