sourcepawn/jit/sp_vm_engine.cpp
changeset 2226 d10b38524be3
parent 2195 5b70179559f9
child 2228 83a7d6b44e3c
     1.1 --- a/sourcepawn/jit/sp_vm_engine.cpp	Sun Aug 10 05:39:25 2008 +0000
     1.2 +++ b/sourcepawn/jit/sp_vm_engine.cpp	Fri Aug 15 05:22:26 2008 +0000
     1.3 @@ -30,23 +30,18 @@
     1.4   */
     1.5  
     1.6  #include "sp_vm_types.h"
     1.7 -#include <sh_memory.h>
     1.8 -/* HACK to avoid including sourcehook.h for just the SH_ASSERT definition */
     1.9 -#if !defined  SH_ASSERT
    1.10 -	#define SH_ASSERT(x, info)
    1.11 -	#include <sh_pagealloc.h>
    1.12 -	#undef SH_ASSERT
    1.13 -#else
    1.14 -	#include <sh_pagealloc.h>
    1.15 -#endif
    1.16 -
    1.17  #include <malloc.h>
    1.18  #include <string.h>
    1.19  #include <assert.h>
    1.20 +#include <KeCodeAllocator.h>
    1.21  #include "sp_file_headers.h"
    1.22  #include "sp_vm_engine.h"
    1.23  #include "zlib/zlib.h"
    1.24  #include "sp_vm_basecontext.h"
    1.25 +#include "jit_x86.h"
    1.26 +#if defined __GNUC__
    1.27 +#include <unistd.h>
    1.28 +#endif
    1.29  
    1.30  SourcePawnEngine g_engine1;
    1.31  
    1.32 @@ -57,12 +52,8 @@
    1.33   #include <sys/mman.h>
    1.34  #endif
    1.35  
    1.36 -#define INVALID_CIP			0xFFFFFFFF
    1.37 -
    1.38  using namespace SourcePawn;
    1.39  
    1.40 -SourceHook::CPageAlloc g_ExeMemory(16);
    1.41 -
    1.42  #define ERROR_MESSAGE_MAX		25
    1.43  static const char *g_ErrorMsgTable[] = 
    1.44  {
    1.45 @@ -92,6 +83,8 @@
    1.46  	"Native detected error",
    1.47  	"Plugin not runnable",
    1.48  	"Call was aborted",
    1.49 +	"Plugin format is too old",
    1.50 +	"Plugin format is too new",
    1.51  };
    1.52  
    1.53  const char *SourcePawnEngine::GetErrorString(int error)
    1.54 @@ -107,33 +100,10 @@
    1.55  SourcePawnEngine::SourcePawnEngine()
    1.56  {
    1.57  	m_pDebugHook = NULL;
    1.58 -	m_CallStack = NULL;
    1.59 -	m_FreedCalls = NULL;
    1.60 -	m_CurChain = 0;
    1.61 -#if 0
    1.62 -	m_pFreeFuncs = NULL;
    1.63 -#endif
    1.64  }
    1.65  
    1.66  SourcePawnEngine::~SourcePawnEngine()
    1.67  {
    1.68 -	TracedCall *pTemp;
    1.69 -	while (m_FreedCalls)
    1.70 -	{
    1.71 -		pTemp = m_FreedCalls->next;
    1.72 -		delete m_FreedCalls;
    1.73 -		m_FreedCalls = pTemp;
    1.74 -	}
    1.75 -
    1.76 -#if 0
    1.77 -	CFunction *pNext;
    1.78 -	while (m_pFreeFuncs)
    1.79 -	{
    1.80 -		pNext = m_pFreeFuncs->m_pNext;
    1.81 -		delete m_pFreeFuncs;
    1.82 -		m_pFreeFuncs = pNext;
    1.83 -	}
    1.84 -#endif
    1.85  }
    1.86  
    1.87  void *SourcePawnEngine::ExecAlloc(size_t size)
    1.88 @@ -153,22 +123,22 @@
    1.89  
    1.90  void *SourcePawnEngine::AllocatePageMemory(size_t size)
    1.91  {
    1.92 -	return g_ExeMemory.Alloc(size);
    1.93 +	return g_Jit.AllocCode(size);
    1.94  }
    1.95  
    1.96  void SourcePawnEngine::SetReadExecute(void *ptr)
    1.97  {
    1.98 -	g_ExeMemory.SetRE(ptr);
    1.99 +	/* already re */
   1.100  }
   1.101  
   1.102  void SourcePawnEngine::SetReadWrite(void *ptr)
   1.103  {
   1.104 -	g_ExeMemory.SetRW(ptr);
   1.105 +	/* already rw */
   1.106  }
   1.107  
   1.108  void SourcePawnEngine::FreePageMemory(void *ptr)
   1.109  {
   1.110 -	g_ExeMemory.Free(ptr);
   1.111 +	g_Jit.FreeCode(ptr);
   1.112  }
   1.113  
   1.114  void SourcePawnEngine::ExecFree(void *address)
   1.115 @@ -180,6 +150,12 @@
   1.116  #endif
   1.117  }
   1.118  
   1.119 +void SourcePawnEngine::SetReadWriteExecute(void *ptr)
   1.120 +{
   1.121 +//:TODO:	g_ExeMemory.SetRWE(ptr);
   1.122 +	SetReadExecute(ptr);
   1.123 +}
   1.124 +
   1.125  void *SourcePawnEngine::BaseAlloc(size_t size)
   1.126  {
   1.127  	return malloc(size);
   1.128 @@ -224,142 +200,38 @@
   1.129  	return old;
   1.130  }
   1.131  
   1.132 -unsigned int SourcePawnEngine::GetContextCallCount()
   1.133 -{
   1.134 -	if (!m_CallStack)
   1.135 -	{
   1.136 -		return 0;
   1.137 -	}
   1.138 -
   1.139 -	return m_CallStack->chain;
   1.140 -}
   1.141 -
   1.142 -TracedCall *SourcePawnEngine::MakeTracedCall(bool new_chain)
   1.143 -{
   1.144 -	TracedCall *pCall;
   1.145 -
   1.146 -	if (!m_FreedCalls)
   1.147 -	{
   1.148 -		pCall = new TracedCall;
   1.149 -	} else {
   1.150 -		/* Unlink the head node from the free list */
   1.151 -		pCall = m_FreedCalls;
   1.152 -		m_FreedCalls = m_FreedCalls->next;
   1.153 -	}
   1.154 -
   1.155 -	/* Link as the head node into the call stack */
   1.156 -	pCall->next = m_CallStack;
   1.157 -
   1.158 -	if (new_chain)
   1.159 -	{
   1.160 -		pCall->chain = ++m_CurChain;
   1.161 -	} else {
   1.162 -		pCall->chain = m_CurChain;
   1.163 -	}
   1.164 -
   1.165 -	m_CallStack = pCall;
   1.166 -
   1.167 -	return pCall;
   1.168 -}
   1.169 -
   1.170 -void SourcePawnEngine::FreeTracedCall(TracedCall *pCall)
   1.171 -{
   1.172 -	/* Check if this is the top of the call stack */
   1.173 -	if (pCall == m_CallStack)
   1.174 -	{
   1.175 -		m_CallStack = m_CallStack->next;
   1.176 -	}
   1.177 -
   1.178 -	/* Add this to our linked list of freed calls */
   1.179 -	if (!m_FreedCalls)
   1.180 -	{
   1.181 -		m_FreedCalls = pCall;
   1.182 -		m_FreedCalls->next = NULL;
   1.183 -	} else {
   1.184 -		pCall->next = m_FreedCalls;
   1.185 -		m_FreedCalls = pCall;
   1.186 -	}
   1.187 -}
   1.188 -
   1.189 -void SourcePawnEngine::PushTracer(BaseContext *ctx)
   1.190 -{
   1.191 -	TracedCall *pCall = MakeTracedCall(true);
   1.192 -
   1.193 -	pCall->cip = INVALID_CIP;
   1.194 -	pCall->ctx = ctx;
   1.195 -	pCall->frm = INVALID_CIP;
   1.196 -}
   1.197 -
   1.198 -void SourcePawnEngine::RunTracer(BaseContext *ctx, uint32_t frame, uint32_t codeip)
   1.199 -{
   1.200 -	assert(m_CallStack != NULL);
   1.201 -	assert(m_CallStack->ctx == ctx);
   1.202 -	assert(m_CallStack->chain == m_CurChain);
   1.203 -
   1.204 -	if (m_CallStack->cip == INVALID_CIP)
   1.205 -	{
   1.206 -		/* We aren't logging anything yet, so begin the trace */
   1.207 -		m_CallStack->cip = codeip;
   1.208 -		m_CallStack->frm = frame;
   1.209 -	} else {
   1.210 -		if (m_CallStack->frm > frame)
   1.211 -		{
   1.212 -			/* The last frame has moved down the stack, 
   1.213 -			 * so we have to push a new call onto our list.
   1.214 -			 */
   1.215 -			TracedCall *pCall = MakeTracedCall(false);
   1.216 -			pCall->ctx = ctx;
   1.217 -			pCall->frm = frame;
   1.218 -		} else if (m_CallStack->frm < frame) {
   1.219 -			/* The last frame has moved up the stack,
   1.220 -			 * so we have to pop the call from our list.
   1.221 -			 */
   1.222 -			FreeTracedCall(m_CallStack);
   1.223 -		}
   1.224 -		/* no matter where we are, update the cip */
   1.225 -		m_CallStack->cip = codeip;
   1.226 -	}
   1.227 -}
   1.228 -
   1.229 -void SourcePawnEngine::PopTracer(int error, const char *msg)
   1.230 -{
   1.231 -	assert(m_CallStack != NULL);
   1.232 -
   1.233 -	if (error != SP_ERROR_NONE && m_pDebugHook)
   1.234 -	{
   1.235 -		uint32_t native = INVALID_CIP;
   1.236 -
   1.237 -		if (m_CallStack->ctx->GetCtx()->n_err)
   1.238 -		{
   1.239 -			native = m_CallStack->ctx->GetCtx()->n_idx;
   1.240 -		}
   1.241 -
   1.242 -		CContextTrace trace(m_CallStack, error, msg, native);
   1.243 -		m_pDebugHook->OnContextExecuteError(m_CallStack->ctx, &trace);
   1.244 -	}
   1.245 -
   1.246 -	/* Now pop the error chain  */
   1.247 -	while (m_CallStack && m_CallStack->chain == m_CurChain)
   1.248 -	{
   1.249 -		FreeTracedCall(m_CallStack);
   1.250 -	}
   1.251 -
   1.252 -	m_CurChain--;
   1.253 -}
   1.254 -
   1.255  unsigned int SourcePawnEngine::GetEngineAPIVersion()
   1.256  {
   1.257  	return SOURCEPAWN_ENGINE_API_VERSION;
   1.258  }
   1.259  
   1.260 -CContextTrace::CContextTrace(TracedCall *pStart, int error, const char *msg, uint32_t native) : 
   1.261 - m_Error(error), m_pMsg(msg), m_pStart(pStart), m_pIterator(pStart), m_Native(native)
   1.262 +unsigned int SourcePawnEngine::GetContextCallCount()
   1.263 +{
   1.264 +	return 0;
   1.265 +}
   1.266 +
   1.267 +void SourcePawnEngine::ReportError(BaseRuntime *runtime, int err, const char *errstr, cell_t rp_start)
   1.268  {
   1.269 +	if (m_pDebugHook == NULL)
   1.270 +	{
   1.271 +		return;
   1.272 +	}
   1.273 +
   1.274 +	CContextTrace trace(runtime, err, errstr, rp_start);
   1.275 +
   1.276 +	m_pDebugHook->OnContextExecuteError(runtime->GetDefaultContext(), &trace);
   1.277 +}
   1.278 +
   1.279 +CContextTrace::CContextTrace(BaseRuntime *pRuntime, int err, const char *errstr, cell_t start_rp) 
   1.280 +: m_pRuntime(pRuntime), m_Error(err), m_pMsg(errstr), m_StartRp(start_rp), m_Level(0)
   1.281 +{
   1.282 +	m_ctx = pRuntime->m_pCtx->GetCtx();
   1.283 +	m_pDebug = m_pRuntime->GetDebugInfo();
   1.284  }
   1.285  
   1.286  bool CContextTrace::DebugInfoAvailable()
   1.287  {
   1.288 -	return m_pStart->ctx->IsDebugging();
   1.289 +	return (m_pDebug != NULL);
   1.290  }
   1.291  
   1.292  const char *CContextTrace::GetCustomErrorString()
   1.293 @@ -374,83 +246,99 @@
   1.294  
   1.295  const char *CContextTrace::GetErrorString()
   1.296  {
   1.297 -	if (m_Error > ERROR_MESSAGE_MAX || 
   1.298 -		m_Error < 1)
   1.299 +	if (m_Error > ERROR_MESSAGE_MAX || m_Error < 1)
   1.300  	{
   1.301  		return "Invalid error code";
   1.302 -	} else {
   1.303 +	}
   1.304 +	else
   1.305 +	{
   1.306  		return g_ErrorMsgTable[m_Error];
   1.307  	}
   1.308  }
   1.309  
   1.310  void CContextTrace::ResetTrace()
   1.311  {
   1.312 -	m_pIterator = m_pStart;
   1.313 +	m_Level = 0;
   1.314  }
   1.315  
   1.316  bool CContextTrace::GetTraceInfo(CallStackInfo *trace)
   1.317  {
   1.318 -	if (!m_pIterator || (m_pIterator->chain != m_pStart->chain))
   1.319 +	cell_t cip;
   1.320 +
   1.321 +	if (m_Level == 0)
   1.322  	{
   1.323 -		return false;
   1.324 +		cip = m_ctx->err_cip;
   1.325  	}
   1.326 -
   1.327 -	if (m_pIterator->cip == INVALID_CIP)
   1.328 +	else if (m_ctx->rp > 0)
   1.329  	{
   1.330 -		return false;
   1.331 -	}
   1.332 +		/* Entries go from ctx.rp - 1 to m_StartRp */
   1.333 +		cell_t offs, start, end;
   1.334 +
   1.335 +		offs = m_Level - 1;
   1.336 +		start = m_ctx->rp - 1;
   1.337 +		end = m_StartRp;
   1.338  
   1.339 -	IPluginContext *pContext = m_pIterator->ctx;
   1.340 -	IPluginDebugInfo *pInfo = pContext->GetRuntime()->GetDebugInfo();
   1.341 +		if (start - offs < end)
   1.342 +		{
   1.343 +			return false;
   1.344 +		}
   1.345  
   1.346 -	if (!pInfo)
   1.347 +		cip = m_ctx->rstk_cips[start - offs];
   1.348 +	}
   1.349 +	else
   1.350  	{
   1.351  		return false;
   1.352  	}
   1.353  
   1.354 -	if (!trace)
   1.355 +	if (trace == NULL)
   1.356  	{
   1.357 -		m_pIterator = m_pIterator->next;
   1.358 +		m_Level++;
   1.359  		return true;
   1.360  	}
   1.361  
   1.362 -	if (pInfo->LookupFile(m_pIterator->cip, &(trace->filename)) != SP_ERROR_NONE)
   1.363 +	if (m_pDebug->LookupFile(cip, &(trace->filename)) != SP_ERROR_NONE)
   1.364  	{
   1.365  		trace->filename = NULL;
   1.366  	}
   1.367  
   1.368 -	if (pInfo->LookupFunction(m_pIterator->cip, &(trace->function)) != SP_ERROR_NONE)
   1.369 +	if (m_pDebug->LookupFunction(cip, &(trace->function)) != SP_ERROR_NONE)
   1.370  	{
   1.371  		trace->function = NULL;
   1.372  	}
   1.373  
   1.374 -	if (pInfo->LookupLine(m_pIterator->cip, &(trace->line)) != SP_ERROR_NONE)
   1.375 +	if (m_pDebug->LookupLine(cip, &(trace->line)) != SP_ERROR_NONE)
   1.376  	{
   1.377  		trace->line = 0;
   1.378  	}
   1.379  
   1.380 -	m_pIterator = m_pIterator->next;
   1.381 +	m_Level++;
   1.382  
   1.383  	return true;
   1.384  }
   1.385  
   1.386  const char *CContextTrace::GetLastNative(uint32_t *index)
   1.387  {
   1.388 -	if (m_Native == INVALID_CIP)
   1.389 +	if (m_ctx->n_err == SP_ERROR_NONE)
   1.390  	{
   1.391  		return NULL;
   1.392  	}
   1.393  
   1.394  	sp_native_t *native;
   1.395 -	if (m_pIterator->ctx->GetNativeByIndex(m_Native, &native) != SP_ERROR_NONE)
   1.396 +	if (m_pRuntime->GetNativeByIndex(m_ctx->n_idx, &native) != SP_ERROR_NONE)
   1.397  	{
   1.398  		return NULL;
   1.399  	}
   1.400  
   1.401  	if (index)
   1.402  	{
   1.403 -		*index = m_Native;
   1.404 +		*index = m_ctx->n_idx;
   1.405  	}
   1.406  
   1.407  	return native->name;
   1.408  }
   1.409 +
   1.410 +IDebugListener *SourcePawnEngine::GetDebugHook()
   1.411 +{
   1.412 +	return m_pDebugHook;
   1.413 +}
   1.414 +