new jit api versioning scheme for
amb398
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
2.1 --- a/core/vm/sp_vm_engine.cpp Mon Jul 23 18:56:20 2007 +0000
2.2 +++ b/core/vm/sp_vm_engine.cpp Mon Jul 23 19:12:54 2007 +0000
2.3 @@ -536,6 +536,11 @@
2.4 m_CurChain--;
2.5 }
2.6
2.7 +unsigned int SourcePawnEngine::GetEngineAPIVersion()
2.8 +{
2.9 + return SOURCEPAWN_ENGINE_API_VERSION;
2.10 +}
2.11 +
2.12 CContextTrace::CContextTrace(TracedCall *pStart, int error, const char *msg, uint32_t native) :
2.13 m_Error(error), m_pMsg(msg), m_pStart(pStart), m_pIterator(pStart), m_Native(native)
2.14 {
3.1 --- a/core/vm/sp_vm_engine.h Mon Jul 23 18:56:20 2007 +0000
3.2 +++ b/core/vm/sp_vm_engine.h Mon Jul 23 19:12:54 2007 +0000
3.3 @@ -65,6 +65,7 @@
3.4 void ExecFree(void *address);
3.5 IDebugListener *SetDebugListener(IDebugListener *pListener);
3.6 unsigned int GetContextCallCount();
3.7 + unsigned int GetEngineAPIVersion();
3.8 public: //Debugger Stuff
3.9 /**
3.10 * @brief Pushes a context onto the top of the call tracer.
4.1 --- a/public/sourcepawn/sp_vm_api.h Mon Jul 23 18:56:20 2007 +0000
4.2 +++ b/public/sourcepawn/sp_vm_api.h Mon Jul 23 19:12:54 2007 +0000
4.3 @@ -27,6 +27,9 @@
4.4 #include <stdio.h>
4.5 #include "sp_vm_types.h"
4.6
4.7 +/** SourcePawn Engine API Version */
4.8 +#define SOURCEPAWN_ENGINE_API_VERSION 1
4.9 +
4.10 /** SourcePawn VM API Version */
4.11 #define SOURCEPAWN_VM_API_VERSION 3
4.12
4.13 @@ -730,6 +733,13 @@
4.14 * @return Number of contexts in the call stack.
4.15 */
4.16 virtual unsigned int GetContextCallCount() =0;
4.17 +
4.18 + /**
4.19 + * @brief Returns the engine API version.
4.20 + *
4.21 + * @return Engine API version.
4.22 + */
4.23 + virtual unsigned int GetEngineAPIVersion() =0;
4.24 };
4.25
4.26
5.1 --- a/sourcepawn/jit/x86/dll_exports.cpp Mon Jul 23 18:56:20 2007 +0000
5.2 +++ b/sourcepawn/jit/x86/dll_exports.cpp Mon Jul 23 19:12:54 2007 +0000
5.3 @@ -20,11 +20,16 @@
5.4 SourcePawn::ISourcePawnEngine *engine = NULL;
5.5 JITX86 g_jit;
5.6
5.7 -EXPORTFUNC int GiveEnginePointer(SourcePawn::ISourcePawnEngine *engine_p)
5.8 +EXPORTFUNC int GiveEnginePointer2(SourcePawn::ISourcePawnEngine *engine_p, unsigned int api_version)
5.9 {
5.10 engine = engine_p;
5.11
5.12 - return 0;
5.13 + if (api_version > SOURCEPAWN_ENGINE_API_VERSION)
5.14 + {
5.15 + return SP_ERROR_PARAM;
5.16 + }
5.17 +
5.18 + return SP_ERROR_NONE;
5.19 }
5.20
5.21 EXPORTFUNC unsigned int GetExportCount()