new jit api versioning scheme for amb398
authorDavid Anderson <dvander@alliedmods.net>
Mon Jul 23 19:12:54 2007 +0000 (2007-07-23)
changeset 1147437e1f00a590
parent 1146 ee44bbf5b70f
child 1148 c523115e1124
new jit api versioning scheme for amb398
core/sourcemod.cpp
core/vm/sp_vm_engine.cpp
core/vm/sp_vm_engine.h
public/sourcepawn/sp_vm_api.h
sourcepawn/jit/x86/dll_exports.cpp
     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()