Merge pull request #271 from alliedmodders/rm-jit-function

Rename some horrible classes.
This commit is contained in:
David Anderson 2015-02-23 16:28:28 -08:00
commit b8d2be9a0d
16 changed files with 163 additions and 149 deletions

View File

@ -30,12 +30,12 @@ if binary.compiler.cc.behavior == 'msvc':
binary.sources += [
'BaseRuntime.cpp',
'engine2.cpp',
'compiled-function.cpp',
'dll_exports.cpp',
'jit_function.cpp',
'engine2.cpp',
'sp_vm_basecontext.cpp',
'sp_vm_engine.cpp',
'sp_vm_function.cpp',
'scripted-invoker.cpp',
'opcodes.cpp',
'interpreter.cpp',
'watchdog_timer.cpp',

View File

@ -277,10 +277,10 @@ int BaseRuntime::CreateFromMemory(sp_file_hdr_t *hdr, uint8_t *base)
}
if (m_plugin.num_publics > 0) {
m_PubFuncs = new CFunction *[m_plugin.num_publics];
memset(m_PubFuncs, 0, sizeof(CFunction *) * m_plugin.num_publics);
m_PubJitFuncs = new JitFunction *[m_plugin.num_publics];
memset(m_PubJitFuncs, 0, sizeof(JitFunction *) * m_plugin.num_publics);
m_PubFuncs = new ScriptedInvoker *[m_plugin.num_publics];
memset(m_PubFuncs, 0, sizeof(ScriptedInvoker *) * m_plugin.num_publics);
m_PubJitFuncs = new CompiledFunction *[m_plugin.num_publics];
memset(m_PubJitFuncs, 0, sizeof(CompiledFunction *) * m_plugin.num_publics);
}
MD5 md5_pcode;
@ -298,18 +298,18 @@ int BaseRuntime::CreateFromMemory(sp_file_hdr_t *hdr, uint8_t *base)
SetupFloatNativeRemapping();
function_map_size_ = m_plugin.pcode_size / sizeof(cell_t) + 1;
function_map_ = new JitFunction *[function_map_size_];
memset(function_map_, 0, function_map_size_ * sizeof(JitFunction *));
function_map_ = new CompiledFunction *[function_map_size_];
memset(function_map_, 0, function_map_size_ * sizeof(CompiledFunction *));
return SP_ERROR_NONE;
}
void
BaseRuntime::AddJittedFunction(JitFunction *fn)
BaseRuntime::AddJittedFunction(CompiledFunction *fn)
{
m_JitFunctions.append(fn);
cell_t pcode_offset = fn->GetPCodeAddress();
cell_t pcode_offset = fn->GetCodeOffset();
assert(pcode_offset % 4 == 0);
uint32_t pcode_index = pcode_offset / 4;
@ -318,7 +318,7 @@ BaseRuntime::AddJittedFunction(JitFunction *fn)
function_map_[pcode_index] = fn;
}
JitFunction *
CompiledFunction *
BaseRuntime::GetJittedFunctionByOffset(cell_t pcode_offset)
{
assert(pcode_offset % 4 == 0);
@ -483,7 +483,7 @@ BaseRuntime::GetDebugInfo()
IPluginFunction *
BaseRuntime::GetFunctionById(funcid_t func_id)
{
CFunction *pFunc = NULL;
ScriptedInvoker *pFunc = NULL;
if (func_id & 1) {
func_id >>= 1;
@ -491,7 +491,7 @@ BaseRuntime::GetFunctionById(funcid_t func_id)
return NULL;
pFunc = m_PubFuncs[func_id];
if (!pFunc) {
m_PubFuncs[func_id] = new CFunction(this, (func_id << 1) | 1, func_id);
m_PubFuncs[func_id] = new ScriptedInvoker(this, (func_id << 1) | 1, func_id);
pFunc = m_PubFuncs[func_id];
}
}
@ -499,15 +499,15 @@ BaseRuntime::GetFunctionById(funcid_t func_id)
return pFunc;
}
CFunction *
ScriptedInvoker *
BaseRuntime::GetPublicFunction(size_t index)
{
CFunction *pFunc = m_PubFuncs[index];
ScriptedInvoker *pFunc = m_PubFuncs[index];
if (!pFunc) {
sp_public_t *pub = NULL;
GetPublicByIndex(index, &pub);
if (pub)
m_PubFuncs[index] = new CFunction(this, (index << 1) | 1, index);
m_PubFuncs[index] = new ScriptedInvoker(this, (index << 1) | 1, index);
pFunc = m_PubFuncs[index];
}

View File

@ -6,10 +6,10 @@
#include <am-vector.h>
#include <am-inlinelist.h>
#include "jit_shared.h"
#include "sp_vm_function.h"
#include "compiled-function.h"
#include "scripted-invoker.h"
class BaseContext;
class JitFunction;
class DebugInfo : public IPluginDebugInfo
{
@ -67,11 +67,11 @@ class BaseRuntime
virtual size_t GetMemUsage();
virtual unsigned char *GetCodeHash();
virtual unsigned char *GetDataHash();
JitFunction *GetJittedFunctionByOffset(cell_t pcode_offset);
void AddJittedFunction(JitFunction *fn);
CompiledFunction *GetJittedFunctionByOffset(cell_t pcode_offset);
void AddJittedFunction(CompiledFunction *fn);
void SetName(const char *name);
unsigned GetNativeReplacement(size_t index);
CFunction *GetPublicFunction(size_t index);
ScriptedInvoker *GetPublicFunction(size_t index);
BaseContext *GetBaseContext();
const sp_plugin_t *plugin() const {
@ -81,7 +81,7 @@ class BaseRuntime
size_t NumJitFunctions() const {
return m_JitFunctions.length();
}
JitFunction *GetJitFunction(size_t i) const {
CompiledFunction *GetJitFunction(size_t i) const {
return m_JitFunctions[i];
}
@ -94,15 +94,15 @@ class BaseRuntime
unsigned int m_NumFuncs;
unsigned int m_MaxFuncs;
floattbl_t *float_table_;
JitFunction **function_map_;
CompiledFunction **function_map_;
size_t function_map_size_;
ke::Vector<JitFunction *> m_JitFunctions;
ke::Vector<CompiledFunction *> m_JitFunctions;
public:
DebugInfo m_Debug;
BaseContext *m_pCtx;
CFunction **m_PubFuncs;
JitFunction **m_PubJitFuncs;
ScriptedInvoker **m_PubFuncs;
CompiledFunction **m_PubJitFuncs;
private:
ICompilation *co_;

View File

@ -14,11 +14,11 @@ OBJECTS = dll_exports.cpp \
x86/jit_x86.cpp \
sp_vm_basecontext.cpp \
sp_vm_engine.cpp \
sp_vm_function.cpp \
scripted-invoker.cpp \
engine2.cpp \
BaseRuntime.cpp \
opcodes.cpp \
jit_function.cpp \
compiled-function.cpp \
md5/md5.cpp \
zlib/adler32.c \
zlib/compress.c \

View File

@ -14,10 +14,10 @@ OBJECTS = dll_exports.cpp \
x86/jit_x86.cpp \
sp_vm_basecontext.cpp \
sp_vm_engine.cpp \
sp_vm_function.cpp \
scripted-invoker.cpp \
engine2.cpp \
BaseRuntime.cpp \
jit_function.cpp \
compiled-function.cpp \
opcodes.cpp \
watchdog_timer.cpp \
interpreter.cpp \
@ -58,7 +58,7 @@ INCLUDE = -I. -I.. -I$(SMSDK)/public -I$(SMSDK)/public/jit -I$(SMSDK)/public/jit
CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \
-D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -DHAVE_STDINT_H \
-m32 -Wno-uninitialized -Werror -DSPSHELL -ggdb3 -Wno-unused
CXXFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti -Wno-delete-non-virtual-dtor
CXXFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti -Wno-delete-non-virtual-dtor -std=c++11
################################################
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###

View File

@ -0,0 +1,27 @@
// vim: set sts=2 ts=8 sw=2 tw=99 et:
//
// Copyright (C) 2006-2015 AlliedModders LLC
//
// This file is part of SourcePawn. SourcePawn is free software: you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// You should have received a copy of the GNU General Public License along with
// SourcePawn. If not, see http://www.gnu.org/licenses/.
//
#include "compiled-function.h"
#include "sp_vm_engine.h"
#include "jit_x86.h"
CompiledFunction::CompiledFunction(void *entry_addr, cell_t pcode_offs, FixedArray<LoopEdge> *edges)
: entry_(entry_addr),
code_offset_(pcode_offs),
edges_(edges)
{
}
CompiledFunction::~CompiledFunction()
{
g_Jit.FreeCode(entry_);
}

View File

@ -0,0 +1,58 @@
// vim: set sts=2 ts=8 sw=2 tw=99 et:
//
// Copyright (C) 2006-2015 AlliedModders LLC
//
// This file is part of SourcePawn. SourcePawn is free software: you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// You should have received a copy of the GNU General Public License along with
// SourcePawn. If not, see http://www.gnu.org/licenses/.
//
#ifndef _INCLUDE_SOURCEPAWN_JIT2_FUNCTION_H_
#define _INCLUDE_SOURCEPAWN_JIT2_FUNCTION_H_
#include <sp_vm_types.h>
#include <am-fixedarray.h>
#include <am-refcounting.h>
namespace sp {
using namespace ke;
struct LoopEdge
{
uint32_t offset;
int32_t disp32;
};
class CompiledFunction
{
public:
CompiledFunction(void *entry_addr, cell_t pcode_offs, FixedArray<LoopEdge> *edges);
~CompiledFunction();
public:
void *GetEntryAddress() const {
return entry_;
}
cell_t GetCodeOffset() const {
return code_offset_;
}
uint32_t NumLoopEdges() const {
return edges_->length();
}
const LoopEdge &GetLoopEdge(size_t i) const {
return edges_->at(i);
}
private:
void *entry_;
cell_t code_offset_;
AutoPtr<FixedArray<LoopEdge>> edges_;
};
}
#endif //_INCLUDE_SOURCEPAWN_JIT2_FUNCTION_H_

View File

@ -1,31 +0,0 @@
// vim: set ts=8 ts=2 sw=2 tw=99 et:
#include "jit_function.h"
#include "sp_vm_engine.h"
#include "jit_x86.h"
JitFunction::JitFunction(void *entry_addr, cell_t pcode_offs, LoopEdge *edges, uint32_t nedges)
: m_pEntryAddr(entry_addr),
m_PcodeOffs(pcode_offs),
edges_(edges),
nedges_(nedges)
{
}
JitFunction::~JitFunction()
{
delete [] edges_;
g_Jit.FreeCode(m_pEntryAddr);
}
void *
JitFunction::GetEntryAddress() const
{
return m_pEntryAddr;
}
cell_t
JitFunction::GetPCodeAddress() const
{
return m_PcodeOffs;
}

View File

@ -1,38 +0,0 @@
// vim: set ts=8 sts=2 sw=2 tw=99 et:
#ifndef _INCLUDE_SOURCEPAWN_JIT2_FUNCTION_H_
#define _INCLUDE_SOURCEPAWN_JIT2_FUNCTION_H_
#include <sp_vm_types.h>
#include <am-vector.h>
struct LoopEdge
{
uint32_t offset;
int32_t disp32;
};
class JitFunction
{
public:
JitFunction(void *entry_addr, cell_t pcode_offs, LoopEdge *edges, uint32_t nedges);
~JitFunction();
public:
void *GetEntryAddress() const;
cell_t GetPCodeAddress() const;
uint32_t NumLoopEdges() const {
return nedges_;
}
const LoopEdge &GetLoopEdge(size_t i) const {
assert(i < nedges_);
return edges_[i];
}
private:
void *m_pEntryAddr;
cell_t m_PcodeOffs;
LoopEdge *edges_;
uint32_t nedges_;
};
#endif //_INCLUDE_SOURCEPAWN_JIT2_FUNCTION_H_

View File

@ -13,43 +13,43 @@
#include <stdio.h>
#include <string.h>
#include "sp_vm_function.h"
#include "scripted-invoker.h"
#include "BaseRuntime.h"
/********************
* FUNCTION CALLING *
********************/
CFunction::~CFunction()
ScriptedInvoker::~ScriptedInvoker()
{
delete [] full_name_;
}
bool
CFunction::IsRunnable()
ScriptedInvoker::IsRunnable()
{
return !m_pRuntime->IsPaused();
}
int
CFunction::CallFunction(const cell_t *params, unsigned int num_params, cell_t *result)
ScriptedInvoker::CallFunction(const cell_t *params, unsigned int num_params, cell_t *result)
{
return CallFunction2(m_pRuntime->GetDefaultContext(), params, num_params, result);
}
int
CFunction::CallFunction2(IPluginContext *pContext, const cell_t *params, unsigned int num_params, cell_t *result)
ScriptedInvoker::CallFunction2(IPluginContext *pContext, const cell_t *params, unsigned int num_params, cell_t *result)
{
return pContext->Execute2(this, params, num_params, result);
}
IPluginContext *
CFunction::GetParentContext()
ScriptedInvoker::GetParentContext()
{
return m_pRuntime->GetDefaultContext();
}
CFunction::CFunction(BaseRuntime *runtime, funcid_t id, uint32_t pub_id)
ScriptedInvoker::ScriptedInvoker(BaseRuntime *runtime, funcid_t id, uint32_t pub_id)
: m_curparam(0),
m_errorstate(SP_ERROR_NONE),
m_FnId(id)
@ -67,7 +67,7 @@ CFunction::CFunction(BaseRuntime *runtime, funcid_t id, uint32_t pub_id)
strcpy(&full_name_[rt_len + 2], public_->name);
}
int CFunction::PushCell(cell_t cell)
int ScriptedInvoker::PushCell(cell_t cell)
{
if (m_curparam >= SP_MAX_EXEC_PARAMS)
return SetError(SP_ERROR_PARAMS_MAX);
@ -80,13 +80,13 @@ int CFunction::PushCell(cell_t cell)
}
int
CFunction::PushCellByRef(cell_t *cell, int flags)
ScriptedInvoker::PushCellByRef(cell_t *cell, int flags)
{
return PushArray(cell, 1, flags);
}
int
CFunction::PushFloat(float number)
ScriptedInvoker::PushFloat(float number)
{
cell_t val = *(cell_t *)&number;
@ -94,13 +94,13 @@ CFunction::PushFloat(float number)
}
int
CFunction::PushFloatByRef(float *number, int flags)
ScriptedInvoker::PushFloatByRef(float *number, int flags)
{
return PushCellByRef((cell_t *)number, flags);
}
int
CFunction::PushArray(cell_t *inarray, unsigned int cells, int copyback)
ScriptedInvoker::PushArray(cell_t *inarray, unsigned int cells, int copyback)
{
if (m_curparam >= SP_MAX_EXEC_PARAMS)
{
@ -121,19 +121,19 @@ CFunction::PushArray(cell_t *inarray, unsigned int cells, int copyback)
}
int
CFunction::PushString(const char *string)
ScriptedInvoker::PushString(const char *string)
{
return _PushString(string, SM_PARAM_STRING_COPY, 0, strlen(string)+1);
}
int
CFunction::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags)
ScriptedInvoker::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags)
{
return _PushString(buffer, sz_flags, cp_flags, length);
}
int
CFunction::_PushString(const char *string, int sz_flags, int cp_flags, size_t len)
ScriptedInvoker::_PushString(const char *string, int sz_flags, int cp_flags, size_t len)
{
if (m_curparam >= SP_MAX_EXEC_PARAMS)
return SetError(SP_ERROR_PARAMS_MAX);
@ -153,7 +153,7 @@ CFunction::_PushString(const char *string, int sz_flags, int cp_flags, size_t le
}
void
CFunction::Cancel()
ScriptedInvoker::Cancel()
{
if (!m_curparam)
return;
@ -163,13 +163,13 @@ CFunction::Cancel()
}
int
CFunction::Execute(cell_t *result)
ScriptedInvoker::Execute(cell_t *result)
{
return Execute2(m_pRuntime->GetDefaultContext(), result);
}
int
CFunction::Execute2(IPluginContext *ctx, cell_t *result)
ScriptedInvoker::Execute2(IPluginContext *ctx, cell_t *result)
{
int err = SP_ERROR_NONE;
@ -303,19 +303,19 @@ CFunction::Execute2(IPluginContext *ctx, cell_t *result)
}
IPluginRuntime *
CFunction::GetParentRuntime()
ScriptedInvoker::GetParentRuntime()
{
return m_pRuntime;
}
funcid_t
CFunction::GetFunctionID()
ScriptedInvoker::GetFunctionID()
{
return m_FnId;
}
int
CFunction::SetError(int err)
ScriptedInvoker::SetError(int err)
{
m_errorstate = err;

View File

@ -34,15 +34,14 @@ struct ParamInfo
};
class CPlugin;
class JitFunction;
class CFunction : public IPluginFunction
class ScriptedInvoker : public IPluginFunction
{
friend class SourcePawnEngine;
public:
CFunction(BaseRuntime *pRuntime, funcid_t fnid, uint32_t pub_id);
~CFunction();
ScriptedInvoker(BaseRuntime *pRuntime, funcid_t fnid, uint32_t pub_id);
~ScriptedInvoker();
public:
virtual int PushCell(cell_t cell);

View File

@ -525,7 +525,7 @@ BaseContext::Execute2(IPluginFunction *function, const cell_t *params, unsigned
int ir;
int serial;
cell_t *sp;
JitFunction *fn;
CompiledFunction *fn;
cell_t _ignore_result;
EnterProfileScope profileScope("SourcePawn", "EnterJIT");
@ -538,7 +538,7 @@ BaseContext::Execute2(IPluginFunction *function, const cell_t *params, unsigned
return SP_ERROR_INVALID_ADDRESS;
unsigned public_id = fnid >> 1;
CFunction *cfun = m_pRuntime->GetPublicFunction(public_id);
ScriptedInvoker *cfun = m_pRuntime->GetPublicFunction(public_id);
if (!cfun)
return SP_ERROR_NOT_FOUND;

View File

@ -14,7 +14,7 @@
#define _INCLUDE_SOURCEPAWN_BASECONTEXT_H_
#include "sp_vm_api.h"
#include "sp_vm_function.h"
#include "scripted-invoker.h"
#include "BaseRuntime.h"
#include "jit_shared.h"

View File

@ -14,7 +14,7 @@
#define _INCLUDE_SOURCEPAWN_VM_ENGINE_H_
#include "sp_vm_api.h"
#include "sp_vm_function.h"
#include "scripted-invoker.h"
class BaseContext;
@ -68,8 +68,6 @@ class SourcePawnEngine : public ISourcePawnEngine
void ReportError(BaseRuntime *runtime, int err, const char *errstr, cell_t rp_start);
public: //Plugin function stuff
CFunction *GetFunctionFromPool(funcid_t f, IPluginContext *plugin);
void ReleaseFunctionToPool(CFunction *func);
IDebugListener *GetDebugHook();
private:

View File

@ -280,7 +280,7 @@ CompileFromThunk(BaseRuntime *runtime, cell_t pcode_offs, void **addrp, char *pc
if (!g_WatchdogTimer.HandleInterrupt())
return SP_ERROR_TIMEOUT;
JitFunction *fn = runtime->GetJittedFunctionByOffset(pcode_offs);
CompiledFunction *fn = runtime->GetJittedFunctionByOffset(pcode_offs);
if (!fn) {
int err;
fn = g_Jit.CompileFunction(runtime, pcode_offs, &err);
@ -320,7 +320,7 @@ Compiler::~Compiler()
delete [] jump_map_;
}
JitFunction *
CompiledFunction *
Compiler::emit(int *errp)
{
if (cip_ >= code_end_ || *cip_ != OP_PROC) {
@ -375,13 +375,14 @@ Compiler::emit(int *errp)
return NULL;
}
LoopEdge *edges = new LoopEdge[backward_jumps_.length()];
AutoPtr<FixedArray<LoopEdge>> edges(
new FixedArray<LoopEdge>(backward_jumps_.length()));
for (size_t i = 0; i < backward_jumps_.length(); i++) {
edges[i].offset = backward_jumps_[i];
edges[i].disp32 = *reinterpret_cast<int32_t *>(code + edges[i].offset - 4);
edges->at(i).offset = backward_jumps_[i];
edges->at(i).disp32 = *reinterpret_cast<int32_t *>(code + edges->at(i).offset - 4);
}
return new JitFunction(code, pcode_start_, edges, backward_jumps_.length());
return new CompiledFunction(code, pcode_start_, edges.take());
}
bool
@ -1479,7 +1480,7 @@ Compiler::emitCall()
// Store the CIP of the function we're about to call.
__ movl(Operand(cipAddr()), offset);
JitFunction *fun = rt_->GetJittedFunctionByOffset(offset);
CompiledFunction *fun = rt_->GetJittedFunctionByOffset(offset);
if (!fun) {
// Need to emit a delayed thunk.
CallThunk *thunk = new CallThunk(offset);
@ -1925,11 +1926,11 @@ JITX86::ShutdownJIT()
KE_DestroyCodeCache(g_pCodeCache);
}
JitFunction *
CompiledFunction *
JITX86::CompileFunction(BaseRuntime *prt, cell_t pcode_offs, int *err)
{
Compiler cc(prt, pcode_offs);
JitFunction *fun = cc.emit(err);
CompiledFunction *fun = cc.emit(err);
if (!fun)
return NULL;
@ -2029,12 +2030,12 @@ CompData::SetOption(const char *key, const char *val)
}
int
JITX86::InvokeFunction(BaseRuntime *runtime, JitFunction *fn, cell_t *result)
JITX86::InvokeFunction(BaseRuntime *runtime, CompiledFunction *fn, cell_t *result)
{
sp_context_t *ctx = runtime->GetBaseContext()->GetCtx();
// Note that cip, hp, sp are saved and restored by Execute2().
ctx->cip = fn->GetPCodeAddress();
ctx->cip = fn->GetCodeOffset();
JIT_EXECUTE pfn = (JIT_EXECUTE)m_pJitEntry;
@ -2080,7 +2081,7 @@ JITX86::PatchAllJumpsForTimeout()
for (ke::InlineList<BaseRuntime>::iterator iter = runtimes_.begin(); iter != runtimes_.end(); iter++) {
BaseRuntime *rt = *iter;
for (size_t i = 0; i < rt->NumJitFunctions(); i++) {
JitFunction *fun = rt->GetJitFunction(i);
CompiledFunction *fun = rt->GetJitFunction(i);
uint8_t *base = reinterpret_cast<uint8_t *>(fun->GetEntryAddress());
for (size_t j = 0; j < fun->NumLoopEdges(); j++) {
@ -2099,7 +2100,7 @@ JITX86::UnpatchAllJumpsFromTimeout()
for (ke::InlineList<BaseRuntime>::iterator iter = runtimes_.begin(); iter != runtimes_.end(); iter++) {
BaseRuntime *rt = *iter;
for (size_t i = 0; i < rt->NumJitFunctions(); i++) {
JitFunction *fun = rt->GetJitFunction(i);
CompiledFunction *fun = rt->GetJitFunction(i);
uint8_t *base = reinterpret_cast<uint8_t *>(fun->GetEntryAddress());
for (size_t j = 0; j < fun->NumLoopEdges(); j++) {

View File

@ -25,7 +25,7 @@
#include "jit_shared.h"
#include "BaseRuntime.h"
#include "sp_vm_basecontext.h"
#include "jit_function.h"
#include "compiled-function.h"
#include "opcodes.h"
#include <am-thread-utils.h>
@ -88,7 +88,7 @@ class Compiler
Compiler(BaseRuntime *rt, cell_t pcode_offs);
~Compiler();
JitFunction *emit(int *errp);
CompiledFunction *emit(int *errp);
private:
bool setup(cell_t pcode_offs);
@ -160,9 +160,9 @@ class JITX86
void FreeContextVars(sp_context_t *ctx);
SPVM_NATIVE_FUNC CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData);
void DestroyFakeNative(SPVM_NATIVE_FUNC func);
JitFunction *CompileFunction(BaseRuntime *runtime, cell_t pcode_offs, int *err);
CompiledFunction *CompileFunction(BaseRuntime *runtime, cell_t pcode_offs, int *err);
ICompilation *ApplyOptions(ICompilation *_IN, ICompilation *_OUT);
int InvokeFunction(BaseRuntime *runtime, JitFunction *fn, cell_t *result);
int InvokeFunction(BaseRuntime *runtime, CompiledFunction *fn, cell_t *result);
void RegisterRuntime(BaseRuntime *rt);
void DeregisterRuntime(BaseRuntime *rt);