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 +