1.1 --- a/core/sourcemod.cpp Mon Jul 23 18:56:20 2007 +0000
1.2 +++ b/core/sourcemod.cpp Mon Jul 23 19:12:54 2007 +0000
1.3 @@ -56,6 +56,7 @@
1.4 float g_StillTime = 0.0f;
1.5
1.6 typedef int (*GIVEENGINEPOINTER)(ISourcePawnEngine *);
1.7 +typedef int (*GIVEENGINEPOINTER2)(ISourcePawnEngine *, unsigned int api_version);
1.8 typedef unsigned int (*GETEXPORTCOUNT)();
1.9 typedef IVirtualMachine *(*GETEXPORT)(unsigned int);
1.10 typedef void (*NOTIFYSHUTDOWN)();
1.11 @@ -157,25 +158,43 @@
1.12 }
1.13
1.14 int err;
1.15 - GIVEENGINEPOINTER jit_init = (GIVEENGINEPOINTER)g_pJIT->GetSymbolAddress("GiveEnginePointer");
1.16 - if (!jit_init)
1.17 +
1.18 + GIVEENGINEPOINTER2 jit_init2 = (GIVEENGINEPOINTER2)g_pJIT->GetSymbolAddress("GiveEnginePointer2");
1.19 + if (!jit_init2)
1.20 {
1.21 - ShutdownJIT();
1.22 - if (error && maxlength)
1.23 + GIVEENGINEPOINTER jit_init = (GIVEENGINEPOINTER)g_pJIT->GetSymbolAddress("GiveEnginePointer");
1.24 + if (!jit_init)
1.25 {
1.26 - snprintf(error, maxlength, "Failed to find GiveEnginePointer in JIT!");
1.27 + ShutdownJIT();
1.28 + if (error && maxlength)
1.29 + {
1.30 + snprintf(error, maxlength, "Failed to find GiveEnginePointer in JIT!");
1.31 + }
1.32 + return false;
1.33 }
1.34 - return false;
1.35 - }
1.36
1.37 - if ((err=jit_init(g_pSourcePawn)) != 0)
1.38 - {
1.39 - ShutdownJIT();
1.40 - if (error && maxlength)
1.41 + if ((err=jit_init(g_pSourcePawn)) != 0)
1.42 {
1.43 - snprintf(error, maxlength, "GiveEnginePointer returned %d in the JIT", err);
1.44 + ShutdownJIT();
1.45 + if (error && maxlength)
1.46 + {
1.47 + snprintf(error, maxlength, "GiveEnginePointer returned %d in the JIT", err);
1.48 + }
1.49 + return false;
1.50 }
1.51 - return false;
1.52 + } else {
1.53 + /* On version bumps, we should check for older versions as well, if the new version fails.
1.54 + * We can then check the exports to see if any VM versions will be sufficient.
1.55 + */
1.56 + if ((err=jit_init2(g_pSourcePawn, SOURCEPAWN_ENGINE_API_VERSION)) != SP_ERROR_NONE)
1.57 + {
1.58 + ShutdownJIT();
1.59 + if (error && maxlength)
1.60 + {
1.61 + snprintf(error, maxlength, "JIT incompatible with SourceMod version");
1.62 + }
1.63 + return false;
1.64 + }
1.65 }
1.66
1.67 GETEXPORTCOUNT jit_getnum = (GETEXPORTCOUNT)g_pJIT->GetSymbolAddress("GetExportCount");
1.68 @@ -191,7 +210,7 @@
1.69 }
1.70
1.71 unsigned int num = jit_getnum();
1.72 - if (!num || ((g_pVM=jit_get(0)) == NULL))
1.73 + if (!num)
1.74 {
1.75 ShutdownJIT();
1.76 if (error && maxlength)
1.77 @@ -201,15 +220,36 @@
1.78 return false;
1.79 }
1.80
1.81 - unsigned int api = g_pVM->GetAPIVersion();
1.82 - /* :TODO: clean this up (see amb398) */
1.83 - if (api > SOURCEPAWN_VM_API_VERSION || api < 2)
1.84 + unsigned int api_version;
1.85 + for (unsigned int i=0; i<num; i++)
1.86 + {
1.87 + if ((g_pVM=jit_get(i)) == NULL)
1.88 + {
1.89 + if (error && maxlength)
1.90 + {
1.91 + snprintf(error, maxlength, "JIT did not export any virtual machines!");
1.92 + }
1.93 + continue;
1.94 + }
1.95 + /* Refuse any API that we might not be able to deal with.
1.96 + * Also refuse anything < 3 because we need fake natives.
1.97 + */
1.98 + api_version = g_pVM->GetAPIVersion();
1.99 + if (api_version < 3 || api_version > SOURCEPAWN_VM_API_VERSION)
1.100 + {
1.101 + if (error && maxlength)
1.102 + {
1.103 + snprintf(error, maxlength, "JIT is not a compatible version");
1.104 + }
1.105 + g_pVM = NULL;
1.106 + continue;
1.107 + }
1.108 + break;
1.109 + }
1.110 +
1.111 + if (!g_pVM)
1.112 {
1.113 ShutdownJIT();
1.114 - if (error && maxlength)
1.115 - {
1.116 - snprintf(error, maxlength, "JIT is not a compatible version");
1.117 - }
1.118 return false;
1.119 }
1.120