core/sourcemod.cpp
author David Anderson <dvander@alliedmods.net>
Sat Nov 11 11:10:24 2006 +0000 (2006-11-11)
changeset 177 d29ade52d953
parent 176 c1699993453c
child 180 fe406c5f2aeb
permissions -rw-r--r--
Fleshed out forward system and extensively documented its design considerations
Implemented and did basic tests on new IPluginFunction type
Split function types into a separate file
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@160
     8
dvander@160
     9
SourcePawnEngine g_SourcePawn;
dvander@160
    10
SourceModBase g_SourceMod;
dvander@160
    11
dvander@160
    12
ILibrary *g_pJIT = NULL;
dvander@160
    13
SourceHook::String g_BaseDir;
dvander@160
    14
ISourcePawnEngine *g_pSourcePawn = &g_SourcePawn;
dvander@160
    15
IVirtualMachine *g_pVM;
dvander@160
    16
dvander@160
    17
typedef int (*GIVEENGINEPOINTER)(ISourcePawnEngine *);
dvander@160
    18
typedef unsigned int (*GETEXPORTCOUNT)();
dvander@160
    19
typedef IVirtualMachine *(*GETEXPORT)(unsigned int);
dvander@160
    20
typedef void (*NOTIFYSHUTDOWN)();
dvander@160
    21
dvander@160
    22
void ShutdownJIT()
dvander@160
    23
{
dvander@160
    24
	NOTIFYSHUTDOWN notify = (NOTIFYSHUTDOWN)g_pJIT->GetSymbolAddress("NotifyShutdown");
dvander@160
    25
	if (notify)
dvander@160
    26
	{
dvander@160
    27
		notify();
dvander@160
    28
	}
dvander@160
    29
dvander@160
    30
	g_pJIT->CloseLibrary();
dvander@160
    31
}
dvander@160
    32
dvander@160
    33
bool SourceModBase::InitializeSourceMod(char *error, size_t err_max, bool late)
dvander@160
    34
{
dvander@160
    35
	//:TODO: we need a localinfo system!
dvander@160
    36
	g_BaseDir.assign(g_SMAPI->GetBaseDir());
dvander@160
    37
dvander@160
    38
	/* Attempt to load the JIT! */
dvander@160
    39
	char file[PLATFORM_MAX_PATH];
dvander@160
    40
	char myerror[255];
dvander@160
    41
	g_SMAPI->PathFormat(file, sizeof(file), "%s/addons/sourcemod/bin/sourcepawn.jit.x86.%s",
dvander@160
    42
		g_BaseDir.c_str(),
dvander@160
    43
		PLATFORM_LIB_EXT
dvander@160
    44
		);
dvander@160
    45
dvander@160
    46
	g_pJIT = g_LibSys.OpenLibrary(file, myerror, sizeof(myerror));
dvander@160
    47
	if (!g_pJIT)
dvander@160
    48
	{
dvander@160
    49
		if (error && err_max)
dvander@160
    50
		{
dvander@160
    51
			snprintf(error, err_max, "%s (failed to load bin/sourcepawn.jit.x86.%s)", 
dvander@160
    52
				myerror,
dvander@160
    53
				PLATFORM_LIB_EXT);
dvander@160
    54
		}
dvander@160
    55
		return false;
dvander@160
    56
	}
dvander@160
    57
dvander@160
    58
	int err;
dvander@160
    59
	GIVEENGINEPOINTER jit_init = (GIVEENGINEPOINTER)g_pJIT->GetSymbolAddress("GiveEnginePointer");
dvander@160
    60
	if (!jit_init)
dvander@160
    61
	{
dvander@160
    62
		ShutdownJIT();
dvander@160
    63
		if (error && err_max)
dvander@160
    64
		{
dvander@160
    65
			snprintf(error, err_max, "Failed to find GiveEnginePointer in JIT!");
dvander@160
    66
		}
dvander@160
    67
		return false;
dvander@160
    68
	}
dvander@160
    69
dvander@160
    70
	if ((err=jit_init(g_pSourcePawn)) != 0)
dvander@160
    71
	{
dvander@160
    72
		ShutdownJIT();
dvander@160
    73
		if (error && err_max)
dvander@160
    74
		{
dvander@160
    75
			snprintf(error, err_max, "GiveEnginePointer returned %d in the JIT", err);
dvander@160
    76
		}
dvander@160
    77
		return false;
dvander@160
    78
	}
dvander@160
    79
dvander@160
    80
	GETEXPORTCOUNT jit_getnum = (GETEXPORTCOUNT)g_pJIT->GetSymbolAddress("GetExportCount");
dvander@160
    81
	GETEXPORT jit_get = (GETEXPORT)g_pJIT->GetSymbolAddress("GetExport");
dvander@160
    82
	if (!jit_get)
dvander@160
    83
	{
dvander@160
    84
		ShutdownJIT();
dvander@160
    85
		if (error && err_max)
dvander@160
    86
		{
dvander@160
    87
			snprintf(error, err_max, "JIT is missing a necessary export!");
dvander@160
    88
		}
dvander@160
    89
		return false;
dvander@160
    90
	}
dvander@160
    91
dvander@160
    92
	unsigned int num = jit_getnum();
dvander@160
    93
	if (!num || ((g_pVM=jit_get(0)) == NULL))
dvander@160
    94
	{
dvander@160
    95
		ShutdownJIT();
dvander@160
    96
		if (error && err_max)
dvander@160
    97
		{
dvander@160
    98
			snprintf(error, err_max, "JIT did not export any virtual machines!");
dvander@160
    99
		}
dvander@160
   100
		return false;
dvander@160
   101
	}
dvander@160
   102
dvander@176
   103
	unsigned int api = g_pVM->GetAPIVersion();
dvander@176
   104
	if (api != SOURCEPAWN_VM_API_VERSION)
dvander@176
   105
	{
dvander@176
   106
		ShutdownJIT();
dvander@176
   107
		if (error && err_max)
dvander@176
   108
		{
dvander@176
   109
			snprintf(error, err_max, "JIT is not a compatible version");
dvander@176
   110
		}
dvander@176
   111
		return false;
dvander@176
   112
	}
dvander@176
   113
dvander@177
   114
#if 0
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@177
   118
	cell_t result = 2;
dvander@177
   119
	cell_t val = 6;
dvander@177
   120
	func->PushCell(1);
dvander@177
   121
	func->PushCellByRef(&val, SMFUNC_COPYBACK_ONCE);
dvander@177
   122
	func->Execute(&result, NULL);
dvander@176
   123
	g_PluginMngr.UnloadPlugin(pPlugin);
dvander@177
   124
#endif
dvander@176
   125
dvander@160
   126
	return true;
dvander@160
   127
}