landed massive refactoring of the JIT. contexts are actually contexts now, and a higher level structure wraps sp_plugin_t info. on that note, both sp_plugin_t and sp_context_t are entirely opaque, and not even core has access to them. amazingly, i managed to keep binary compatibility here although a large number of functions are deprecated (and core should eventually stop calling them).
NOTE: the JIT is now embeddable out-of-box and usable by other projects which is pretty cool. I will commit a shell app demonstrating this soon --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%402400
This commit is contained in:
@@ -1,73 +0,0 @@
|
||||
# (C)2004-2008 SourceMod Development Team
|
||||
# Makefile written by David "BAILOPAN" Anderson
|
||||
|
||||
SMSDK = ../../..
|
||||
|
||||
#####################################
|
||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
||||
#####################################
|
||||
|
||||
PROJECT = sourcepawn.jit.x86
|
||||
|
||||
OBJECTS = dll_exports.cpp jit_x86.cpp opcode_helpers.cpp
|
||||
|
||||
##############################################
|
||||
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
||||
##############################################
|
||||
|
||||
C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing
|
||||
C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
|
||||
C_GCC4_FLAGS = -fvisibility=hidden
|
||||
CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
|
||||
CPP = gcc-4.1
|
||||
|
||||
LINK = -static-libgcc
|
||||
|
||||
INCLUDE = -I. -I.. -I$(SMSDK)/public -I$(SMSDK)/public/jit -I$(SMSDK)/public/jit/x86 \
|
||||
-I$(SMSDK)/public/sourcepawn
|
||||
|
||||
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
|
||||
CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti
|
||||
|
||||
################################################
|
||||
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
|
||||
################################################
|
||||
|
||||
ifeq "$(DEBUG)" "true"
|
||||
BIN_DIR = Debug
|
||||
CFLAGS += $(C_DEBUG_FLAGS)
|
||||
else
|
||||
BIN_DIR = Release
|
||||
CFLAGS += $(C_OPT_FLAGS)
|
||||
endif
|
||||
|
||||
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
|
||||
ifeq "$(GCC_VERSION)" "4"
|
||||
CFLAGS += $(C_GCC4_FLAGS)
|
||||
CPPFLAGS += $(CPP_GCC4_FLAGS)
|
||||
endif
|
||||
|
||||
BINARY = $(PROJECT).so
|
||||
|
||||
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
|
||||
|
||||
$(BIN_DIR)/%.o: %.cpp
|
||||
$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
|
||||
|
||||
all:
|
||||
mkdir -p $(BIN_DIR)
|
||||
$(MAKE) -f Makefile jit
|
||||
|
||||
jit: $(OBJ_LINUX)
|
||||
$(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
|
||||
|
||||
debug:
|
||||
$(MAKE) -f Makefile all DEBUG=true
|
||||
|
||||
default: all
|
||||
|
||||
clean:
|
||||
rm -rf $(BIN_DIR)/*.o
|
||||
rm -rf $(BIN_DIR)/$(BINARY)
|
||||
@@ -1,99 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include <sp_vm_api.h>
|
||||
#include <malloc.h>
|
||||
#include "jit_x86.h"
|
||||
#include "dll_exports.h"
|
||||
|
||||
SourcePawn::ISourcePawnEngine *engine = NULL;
|
||||
JITX86 g_jit;
|
||||
|
||||
EXPORTFUNC int GiveEnginePointer2(SourcePawn::ISourcePawnEngine *engine_p, unsigned int api_version)
|
||||
{
|
||||
engine = engine_p;
|
||||
|
||||
if (api_version > SOURCEPAWN_ENGINE_API_VERSION || api_version < 2)
|
||||
{
|
||||
return SP_ERROR_PARAM;
|
||||
}
|
||||
|
||||
return SP_ERROR_NONE;
|
||||
}
|
||||
|
||||
EXPORTFUNC unsigned int GetExportCount()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
EXPORTFUNC SourcePawn::IVirtualMachine *GetExport(unsigned int exportnum)
|
||||
{
|
||||
/* Don't return anything if we're not initialized yet */
|
||||
if (!engine)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We only have one export - 0 */
|
||||
if (exportnum)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &g_jit;
|
||||
}
|
||||
|
||||
#if defined __linux__
|
||||
extern "C" void __cxa_pure_virtual(void)
|
||||
{
|
||||
}
|
||||
|
||||
void *operator new(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void *operator new[](size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void operator delete(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void operator delete[](void * ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SOURCEPAWN_JIT_X86_DLL_H_
|
||||
#define _INCLUDE_SOURCEPAWN_JIT_X86_DLL_H_
|
||||
|
||||
#include <sp_vm_base.h>
|
||||
|
||||
#if defined WIN32
|
||||
#define EXPORTFUNC extern "C" __declspec(dllexport)
|
||||
#elif defined __GNUC__
|
||||
#if __GNUC__ >= 3
|
||||
#define EXPORTFUNC extern "C" __attribute__((visibility("default")))
|
||||
#else
|
||||
#define EXPORTFUNC extern "C"
|
||||
#endif //__GNUC__ >= 3
|
||||
#endif //defined __GNUC__
|
||||
|
||||
#endif //_INCLUDE_SOURCEPAWN_JIT_X86_DLL_H_
|
||||
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_JIT_VERSION_H_
|
||||
#define _INCLUDE_JIT_VERSION_H_
|
||||
|
||||
#define SVN_FULL_VERSION "1.1.0-svn"
|
||||
#define SVN_FILE_VERSION 1,1,0,2218
|
||||
|
||||
#endif //_INCLUDE_JIT_VERSION_H_
|
||||
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_JIT_VERSION_H_
|
||||
#define _INCLUDE_JIT_VERSION_H_
|
||||
|
||||
#define SVN_FULL_VERSION "$PMAJOR$.$PMINOR$.$PREVISION$-svn"
|
||||
#define SVN_FILE_VERSION $PMAJOR$,$PMINOR$,$PREVISION$,$LOCAL_BUILD$
|
||||
|
||||
#endif //_INCLUDE_JIT_VERSION_H_
|
||||
+204
-216
@@ -35,12 +35,24 @@
|
||||
#include "jit_x86.h"
|
||||
#include "opcode_helpers.h"
|
||||
#include <x86_macros.h>
|
||||
#include "jit_version.h"
|
||||
#include "../jit_version.h"
|
||||
#include "../sp_vm_engine.h"
|
||||
#include "../engine2.h"
|
||||
#include "../BaseRuntime.h"
|
||||
#include "../sp_vm_basecontext.h"
|
||||
|
||||
#if defined USE_UNGEN_OPCODES
|
||||
#include "ungen_opcodes.h"
|
||||
#endif
|
||||
|
||||
JITX86 g_Jit1;
|
||||
ISourcePawnEngine *engine = &g_engine1;
|
||||
|
||||
inline sp_plugin_t *GETPLUGIN(sp_context_t *ctx)
|
||||
{
|
||||
return (sp_plugin_t *)(ctx->vm[JITVARS_PLUGIN]);
|
||||
}
|
||||
|
||||
inline void WriteOp_Move_Pri(JitWriter *jit)
|
||||
{
|
||||
//mov eax, edx
|
||||
@@ -1318,12 +1330,12 @@ inline void WriteOp_Retn(JitWriter *jit)
|
||||
|
||||
void ProfCallGate_Begin(sp_context_t *ctx, const char *name)
|
||||
{
|
||||
ctx->profiler->OnFunctionBegin(ctx->context, name);
|
||||
((IProfiler *)ctx->vm[JITVARS_PROFILER])->OnFunctionBegin((IPluginContext *)ctx->vm[JITVARS_BASECTX], name);
|
||||
}
|
||||
|
||||
void ProfCallGate_End(sp_context_t *ctx)
|
||||
{
|
||||
ctx->profiler->OnFunctionEnd();
|
||||
((IProfiler *)ctx->vm[JITVARS_PROFILER])->OnFunctionEnd();
|
||||
}
|
||||
|
||||
const char *find_func_name(sp_plugin_t *plugin, uint32_t offs)
|
||||
@@ -2264,8 +2276,11 @@ inline void WriteOp_FloatCompare(JitWriter *jit)
|
||||
cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
|
||||
{
|
||||
sp_native_t *native;
|
||||
sp_plugin_t *plugin;
|
||||
|
||||
plugin = (sp_plugin_t *)ctx->vm[JITVARS_PLUGIN];
|
||||
|
||||
native = &ctx->natives[native_idx];
|
||||
native = &plugin->natives[native_idx];
|
||||
|
||||
ctx->n_idx = native_idx;
|
||||
|
||||
@@ -2276,15 +2291,18 @@ cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return native->pfn(ctx->context, params);
|
||||
return native->pfn(GET_CONTEXT(ctx), params);
|
||||
}
|
||||
|
||||
cell_t NativeCallback_Profile(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
|
||||
{
|
||||
cell_t val;
|
||||
sp_native_t *native;
|
||||
sp_plugin_t *plugin;
|
||||
|
||||
native = &ctx->natives[native_idx];
|
||||
plugin = (sp_plugin_t *)ctx->vm[JITVARS_PLUGIN];
|
||||
|
||||
native = &plugin->natives[native_idx];
|
||||
|
||||
ctx->n_idx = native_idx;
|
||||
|
||||
@@ -2295,9 +2313,9 @@ cell_t NativeCallback_Profile(sp_context_t *ctx, ucell_t native_idx, cell_t *par
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->profiler->OnNativeBegin(ctx->context, native);
|
||||
val = native->pfn(ctx->context, params);
|
||||
ctx->profiler->OnNativeEnd();
|
||||
plugin->profiler->OnNativeBegin(GET_CONTEXT(ctx), native);
|
||||
val = native->pfn(GET_CONTEXT(ctx), params);
|
||||
plugin->profiler->OnNativeEnd();
|
||||
|
||||
return val;
|
||||
}
|
||||
@@ -2307,9 +2325,11 @@ cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *param
|
||||
cell_t save_sp = ctx->sp;
|
||||
cell_t save_hp = ctx->hp;
|
||||
|
||||
sp_plugin_t *pl = GETPLUGIN(ctx);
|
||||
|
||||
ctx->n_idx = native_idx;
|
||||
|
||||
if (ctx->hp < ctx->heap_base)
|
||||
if (ctx->hp < (cell_t)pl->data_size)
|
||||
{
|
||||
ctx->n_err = SP_ERROR_HEAPMIN;
|
||||
return 0;
|
||||
@@ -2321,7 +2341,7 @@ cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *param
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((uint32_t)ctx->sp >= ctx->mem_size)
|
||||
if ((uint32_t)ctx->sp >= pl->mem_size)
|
||||
{
|
||||
ctx->n_err = SP_ERROR_STACKMIN;
|
||||
return 0;
|
||||
@@ -2353,9 +2373,11 @@ cell_t NativeCallback_Debug_Profile(sp_context_t *ctx, ucell_t native_idx, cell_
|
||||
cell_t save_sp = ctx->sp;
|
||||
cell_t save_hp = ctx->hp;
|
||||
|
||||
sp_plugin_t *pl = GETPLUGIN(ctx);
|
||||
|
||||
ctx->n_idx = native_idx;
|
||||
|
||||
if (ctx->hp < ctx->heap_base)
|
||||
if (ctx->hp < (cell_t)pl->data_size)
|
||||
{
|
||||
ctx->n_err = SP_ERROR_HEAPMIN;
|
||||
return 0;
|
||||
@@ -2367,7 +2389,7 @@ cell_t NativeCallback_Debug_Profile(sp_context_t *ctx, ucell_t native_idx, cell_
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((uint32_t)ctx->sp >= ctx->mem_size)
|
||||
if ((uint32_t)ctx->sp >= pl->mem_size)
|
||||
{
|
||||
ctx->n_err = SP_ERROR_STACKMIN;
|
||||
return 0;
|
||||
@@ -2396,10 +2418,7 @@ cell_t NativeCallback_Debug_Profile(sp_context_t *ctx, ucell_t native_idx, cell_
|
||||
|
||||
static cell_t InvalidNative(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
sp_context_t *ctx = pCtx->GetContext();
|
||||
ctx->n_err = SP_ERROR_INVALID_NATIVE;
|
||||
|
||||
return 0;
|
||||
return pCtx->ThrowNativeErrorEx(SP_ERROR_INVALID_NATIVE, "Invalid native");
|
||||
}
|
||||
|
||||
jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative)
|
||||
@@ -2457,11 +2476,27 @@ void WriteErrorRoutines(CompData *data, JitWriter *jit)
|
||||
Write_GetError(jit);
|
||||
}
|
||||
|
||||
sp_context_t *JITX86::CompileToContext(ICompilation *co, int *err)
|
||||
bool JITX86::Compile(ICompilation *co, BaseRuntime *prt, int *err)
|
||||
{
|
||||
CompData *data = (CompData *)co;
|
||||
sp_plugin_t *plugin = data->plugin;
|
||||
|
||||
if (data->plugin == NULL)
|
||||
{
|
||||
if (data->debug && !(prt->m_pPlugin->flags & SP_FLAG_DEBUG))
|
||||
{
|
||||
if (err != NULL)
|
||||
{
|
||||
*err = SP_ERROR_NOTDEBUGGING;
|
||||
}
|
||||
co->Abort();
|
||||
return false;
|
||||
}
|
||||
|
||||
data->SetRuntime(prt);
|
||||
plugin = data->plugin;
|
||||
}
|
||||
|
||||
/* The first phase is to browse */
|
||||
uint8_t *code = plugin->pcode;
|
||||
uint8_t *end_cip = plugin->pcode + plugin->pcode_size;
|
||||
@@ -2584,8 +2619,8 @@ jit_rewind:
|
||||
if (data->error_set != SP_ERROR_NONE)
|
||||
{
|
||||
*err = data->error_set;
|
||||
AbortCompilation(co);
|
||||
return NULL;
|
||||
co->Abort();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/* Write these last because error jumps should be unpredicted, and thus forward */
|
||||
@@ -2627,23 +2662,29 @@ jit_rewind:
|
||||
* FOURTH PASS - Context Setup
|
||||
*************/
|
||||
|
||||
sp_context_t *ctx = new sp_context_t;
|
||||
memset(ctx, 0, sizeof(sp_context_t));
|
||||
|
||||
/* setup basics */
|
||||
ctx->codebase = writer.outbase;
|
||||
ctx->plugin = plugin;
|
||||
ctx->vmbase = this;
|
||||
ctx->flags = (data->debug ? SPFLAG_PLUGIN_DEBUG : 0);
|
||||
sp_context_t *ctx = data->runtime->GetBaseContext()->GetCtx();
|
||||
|
||||
/* Clear out any old cruft */
|
||||
if (plugin->codebase != NULL)
|
||||
{
|
||||
FreePluginVars(data->runtime->m_pPlugin);
|
||||
FreeContextVars(ctx);
|
||||
}
|
||||
|
||||
plugin->codebase = writer.outbase;
|
||||
plugin->jit_codesize = codemem;
|
||||
plugin->jit_memsize = 0;
|
||||
|
||||
/* setup memory */
|
||||
ctx->memory = new uint8_t[plugin->memory];
|
||||
memcpy(ctx->memory, plugin->data, plugin->data_size);
|
||||
ctx->mem_size = plugin->memory;
|
||||
ctx->heap_base = plugin->data_size;
|
||||
ctx->hp = ctx->heap_base;
|
||||
ctx->sp = ctx->mem_size - sizeof(cell_t);
|
||||
ctx->prof_flags = data->profile;
|
||||
|
||||
ctx->hp = plugin->data_size;
|
||||
ctx->sp = plugin->mem_size - sizeof(cell_t);
|
||||
ctx->frm = ctx->sp;
|
||||
ctx->n_err = SP_ERROR_NONE;
|
||||
ctx->n_idx = SP_ERROR_NONE;
|
||||
plugin->prof_flags = data->profile;
|
||||
plugin->flags = data->debug ? SPFLAG_PLUGIN_DEBUG : 0;
|
||||
|
||||
const char *strbase = plugin->info.stringbase;
|
||||
uint32_t max, iter;
|
||||
@@ -2651,39 +2692,42 @@ jit_rewind:
|
||||
/* relocate public info */
|
||||
if ((max = plugin->info.publics_num))
|
||||
{
|
||||
ctx->publics = new sp_public_t[max];
|
||||
plugin->publics = new sp_public_t[max];
|
||||
plugin->jit_memsize += sizeof(sp_public_t) * max;
|
||||
for (iter=0; iter<max; iter++)
|
||||
{
|
||||
ctx->publics[iter].name = strbase + plugin->info.publics[iter].name;
|
||||
ctx->publics[iter].code_offs = RelocLookup(jit, plugin->info.publics[iter].address, false);
|
||||
plugin->publics[iter].name = strbase + plugin->info.publics[iter].name;
|
||||
plugin->publics[iter].code_offs = RelocLookup(jit, plugin->info.publics[iter].address, false);
|
||||
/* Encode the ID as a straight code offset */
|
||||
ctx->publics[iter].funcid = (ctx->publics[iter].code_offs << 1);
|
||||
plugin->publics[iter].funcid = (plugin->publics[iter].code_offs << 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* relocate pubvar info */
|
||||
if ((max = plugin->info.pubvars_num))
|
||||
{
|
||||
uint8_t *dat = ctx->memory;
|
||||
ctx->pubvars = new sp_pubvar_t[max];
|
||||
uint8_t *dat = plugin->memory;
|
||||
plugin->pubvars = new sp_pubvar_t[max];
|
||||
plugin->jit_memsize += sizeof(sp_pubvar_t) * max;
|
||||
for (iter=0; iter<max; iter++)
|
||||
{
|
||||
ctx->pubvars[iter].name = strbase + plugin->info.pubvars[iter].name;
|
||||
ctx->pubvars[iter].offs = (cell_t *)(dat + plugin->info.pubvars[iter].address);
|
||||
plugin->pubvars[iter].name = strbase + plugin->info.pubvars[iter].name;
|
||||
plugin->pubvars[iter].offs = (cell_t *)(dat + plugin->info.pubvars[iter].address);
|
||||
}
|
||||
}
|
||||
|
||||
/* relocate native info */
|
||||
if ((max = plugin->info.natives_num))
|
||||
{
|
||||
ctx->natives = new sp_native_t[max];
|
||||
plugin->natives = new sp_native_t[max];
|
||||
plugin->jit_memsize += sizeof(sp_native_t) * max;
|
||||
for (iter=0; iter<max; iter++)
|
||||
{
|
||||
ctx->natives[iter].name = strbase + plugin->info.natives[iter].name;
|
||||
ctx->natives[iter].pfn = &InvalidNative;
|
||||
ctx->natives[iter].status = SP_NATIVE_UNBOUND;
|
||||
ctx->natives[iter].flags = 0;
|
||||
ctx->natives[iter].user = NULL;
|
||||
plugin->natives[iter].name = strbase + plugin->info.natives[iter].name;
|
||||
plugin->natives[iter].pfn = &InvalidNative;
|
||||
plugin->natives[iter].status = SP_NATIVE_UNBOUND;
|
||||
plugin->natives[iter].flags = 0;
|
||||
plugin->natives[iter].user = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2696,20 +2740,22 @@ jit_rewind:
|
||||
|
||||
/* relocate files */
|
||||
max = plugin->debug.files_num;
|
||||
ctx->files = new sp_debug_file_t[max];
|
||||
plugin->files = new sp_debug_file_t[max];
|
||||
plugin->jit_memsize += sizeof(sp_debug_file_t) * max;
|
||||
for (iter=0; iter<max; iter++)
|
||||
{
|
||||
ctx->files[iter].addr = RelocLookup(jit, plugin->debug.files[iter].addr, false);
|
||||
ctx->files[iter].name = strbase + plugin->debug.files[iter].name;
|
||||
plugin->files[iter].addr = RelocLookup(jit, plugin->debug.files[iter].addr, false);
|
||||
plugin->files[iter].name = strbase + plugin->debug.files[iter].name;
|
||||
}
|
||||
|
||||
/* relocate lines */
|
||||
max = plugin->debug.lines_num;
|
||||
ctx->lines = new sp_debug_line_t[max];
|
||||
plugin->lines = new sp_debug_line_t[max];
|
||||
plugin->jit_memsize += sizeof(sp_debug_line_t) * max;
|
||||
for (iter=0; iter<max; iter++)
|
||||
{
|
||||
ctx->lines[iter].addr = RelocLookup(jit, plugin->debug.lines[iter].addr, false);
|
||||
ctx->lines[iter].line = plugin->debug.lines[iter].line;
|
||||
plugin->lines[iter].addr = RelocLookup(jit, plugin->debug.lines[iter].addr, false);
|
||||
plugin->lines[iter].line = plugin->debug.lines[iter].line;
|
||||
}
|
||||
|
||||
/* relocate arrays */
|
||||
@@ -2718,7 +2764,8 @@ jit_rewind:
|
||||
uint8_t *cursor = (uint8_t *)(plugin->debug.symbols);
|
||||
|
||||
max = plugin->debug.syms_num;
|
||||
ctx->symbols = new sp_debug_symbol_t[max];
|
||||
plugin->symbols = new sp_debug_symbol_t[max];
|
||||
plugin->jit_memsize += sizeof(sp_debug_symbol_t) * max;
|
||||
for (iter=0; iter<max; iter++)
|
||||
{
|
||||
sym = (sp_fdbg_symbol_t *)cursor;
|
||||
@@ -2730,52 +2777,50 @@ jit_rewind:
|
||||
*/
|
||||
if (sym->codestart > data->codesize)
|
||||
{
|
||||
ctx->symbols[iter].codestart = 0;
|
||||
plugin->symbols[iter].codestart = 0;
|
||||
} else {
|
||||
ctx->symbols[iter].codestart = RelocLookup(jit, sym->codestart, false);
|
||||
plugin->symbols[iter].codestart = RelocLookup(jit, sym->codestart, false);
|
||||
}
|
||||
if (sym->codeend > data->codesize)
|
||||
{
|
||||
ctx->symbols[iter].codeend = data->codesize;
|
||||
plugin->symbols[iter].codeend = data->codesize;
|
||||
} else {
|
||||
ctx->symbols[iter].codeend = RelocLookup(jit, sym->codeend, false);
|
||||
plugin->symbols[iter].codeend = RelocLookup(jit, sym->codeend, false);
|
||||
}
|
||||
ctx->symbols[iter].name = strbase + sym->name;
|
||||
ctx->symbols[iter].sym = sym;
|
||||
plugin->symbols[iter].name = strbase + sym->name;
|
||||
plugin->symbols[iter].sym = sym;
|
||||
|
||||
if (sym->dimcount > 0)
|
||||
{
|
||||
cursor += sizeof(sp_fdbg_symbol_t);
|
||||
arr = (sp_fdbg_arraydim_t *)cursor;
|
||||
ctx->symbols[iter].dims = arr;
|
||||
plugin->symbols[iter].dims = arr;
|
||||
cursor += sizeof(sp_fdbg_arraydim_t) * sym->dimcount;
|
||||
continue;
|
||||
}
|
||||
|
||||
ctx->symbols[iter].dims = NULL;
|
||||
plugin->symbols[iter].dims = NULL;
|
||||
cursor += sizeof(sp_fdbg_symbol_t);
|
||||
}
|
||||
}
|
||||
|
||||
tracker_t *trk = new tracker_t;
|
||||
ctx->vm[JITVARS_TRACKER] = trk;
|
||||
ctx->vm[JITVARS_BASECTX] = data->runtime->GetDefaultContext();
|
||||
ctx->vm[JITVARS_PROFILER] = g_engine2.GetProfiler();
|
||||
ctx->vm[JITVARS_PLUGIN] = data->runtime->m_pPlugin;
|
||||
trk->pBase = (ucell_t *)malloc(1024);
|
||||
trk->pCur = trk->pBase;
|
||||
trk->size = 1024 / sizeof(cell_t);
|
||||
|
||||
functracker_t *fnc = new functracker_t;
|
||||
ctx->vm[JITVARS_FUNCINFO] = fnc;
|
||||
ctx->vm[JITVARS_REBASE] = data->rebase;
|
||||
fnc->code_size = codemem;
|
||||
fnc->num_functions = data->func_idx;
|
||||
plugin->jit_memsize += trk->size;
|
||||
|
||||
/* clean up relocation+compilation memory */
|
||||
data->rebase = NULL;
|
||||
AbortCompilation(co);
|
||||
co->Abort();
|
||||
|
||||
*err = SP_ERROR_NONE;
|
||||
|
||||
return ctx;
|
||||
return true;
|
||||
}
|
||||
|
||||
SPVM_NATIVE_FUNC JITX86::CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData)
|
||||
@@ -2851,126 +2896,149 @@ void JITX86::DestroyFakeNative(SPVM_NATIVE_FUNC func)
|
||||
engine->FreePageMemory((void *)func);
|
||||
}
|
||||
|
||||
const char *JITX86::GetVMName()
|
||||
{
|
||||
return "JIT (x86)";
|
||||
}
|
||||
|
||||
int JITX86::ContextExecute(sp_context_t *ctx, uint32_t code_idx, cell_t *result)
|
||||
int JITX86::ContextExecute(sp_plugin_t *pl, sp_context_t *ctx, uint32_t code_idx, cell_t *result)
|
||||
{
|
||||
typedef int (*CONTEXT_EXECUTE)(sp_context_t *, uint32_t, cell_t *);
|
||||
CONTEXT_EXECUTE fn = (CONTEXT_EXECUTE)ctx->codebase;
|
||||
CONTEXT_EXECUTE fn = (CONTEXT_EXECUTE)pl->codebase;
|
||||
return fn(ctx, code_idx, result);
|
||||
}
|
||||
|
||||
void JITX86::FreeContext(sp_context_t *ctx)
|
||||
{
|
||||
engine->FreePageMemory(ctx->codebase);
|
||||
delete [] ctx->memory;
|
||||
delete [] ctx->files;
|
||||
delete [] ctx->lines;
|
||||
delete [] ctx->natives;
|
||||
delete [] ctx->publics;
|
||||
delete [] ctx->pubvars;
|
||||
delete [] ctx->symbols;
|
||||
engine->BaseFree(ctx->vm[JITVARS_REBASE]);
|
||||
free(((tracker_t *)(ctx->vm[JITVARS_TRACKER]))->pBase);
|
||||
delete (tracker_t *)ctx->vm[JITVARS_TRACKER];
|
||||
delete (functracker_t *)ctx->vm[JITVARS_FUNCINFO];
|
||||
delete ctx;
|
||||
}
|
||||
|
||||
ICompilation *JITX86::StartCompilation(sp_plugin_t *plugin)
|
||||
ICompilation *JITX86::StartCompilation()
|
||||
{
|
||||
CompData *data = new CompData;
|
||||
|
||||
data->jit_float_table = NULL;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void CompData::SetRuntime(BaseRuntime *runtime)
|
||||
{
|
||||
plugin = runtime->m_pPlugin;
|
||||
|
||||
uint32_t max_natives = plugin->info.natives_num;
|
||||
const char *strbase = plugin->info.stringbase;
|
||||
|
||||
data->plugin = plugin;
|
||||
data->inline_level = JIT_INLINE_ERRORCHECKS|JIT_INLINE_NATIVES;
|
||||
data->error_set = SP_ERROR_NONE;
|
||||
this->runtime = runtime;
|
||||
|
||||
data->jit_float_table = new floattbl_t[max_natives];
|
||||
inline_level = JIT_INLINE_ERRORCHECKS|JIT_INLINE_NATIVES;
|
||||
error_set = SP_ERROR_NONE;
|
||||
|
||||
jit_float_table = new floattbl_t[max_natives];
|
||||
for (uint32_t i=0; i<max_natives; i++)
|
||||
{
|
||||
const char *name = strbase + plugin->info.natives[i].name;
|
||||
if (!strcmp(name, "FloatAbs"))
|
||||
{
|
||||
data->jit_float_table[i].found = true;
|
||||
data->jit_float_table[i].index = OP_FABS;
|
||||
jit_float_table[i].found = true;
|
||||
jit_float_table[i].index = OP_FABS;
|
||||
} else if (!strcmp(name, "FloatAdd")) {
|
||||
data->jit_float_table[i].found = true;
|
||||
data->jit_float_table[i].index = OP_FLOATADD;
|
||||
jit_float_table[i].found = true;
|
||||
jit_float_table[i].index = OP_FLOATADD;
|
||||
} else if (!strcmp(name, "FloatSub")) {
|
||||
data->jit_float_table[i].found = true;
|
||||
data->jit_float_table[i].index = OP_FLOATSUB;
|
||||
jit_float_table[i].found = true;
|
||||
jit_float_table[i].index = OP_FLOATSUB;
|
||||
} else if (!strcmp(name, "FloatMul")) {
|
||||
data->jit_float_table[i].found = true;
|
||||
data->jit_float_table[i].index = OP_FLOATMUL;
|
||||
jit_float_table[i].found = true;
|
||||
jit_float_table[i].index = OP_FLOATMUL;
|
||||
} else if (!strcmp(name, "FloatDiv")) {
|
||||
data->jit_float_table[i].found = true;
|
||||
data->jit_float_table[i].index = OP_FLOATDIV;
|
||||
jit_float_table[i].found = true;
|
||||
jit_float_table[i].index = OP_FLOATDIV;
|
||||
} else if (!strcmp(name, "float")) {
|
||||
data->jit_float_table[i].found = true;
|
||||
data->jit_float_table[i].index = OP_FLOAT;
|
||||
jit_float_table[i].found = true;
|
||||
jit_float_table[i].index = OP_FLOAT;
|
||||
} else if (!strcmp(name, "FloatCompare")) {
|
||||
data->jit_float_table[i].found = true;
|
||||
data->jit_float_table[i].index = OP_FLOATCMP;
|
||||
jit_float_table[i].found = true;
|
||||
jit_float_table[i].index = OP_FLOATCMP;
|
||||
} else if (!strcmp(name, "RoundToZero")) {
|
||||
data->jit_float_table[i].found = true;
|
||||
data->jit_float_table[i].index = OP_RND_TO_ZERO;
|
||||
jit_float_table[i].found = true;
|
||||
jit_float_table[i].index = OP_RND_TO_ZERO;
|
||||
} else if (!strcmp(name, "RoundToCeil")) {
|
||||
data->jit_float_table[i].found = true;
|
||||
data->jit_float_table[i].index = OP_RND_TO_CEIL;
|
||||
jit_float_table[i].found = true;
|
||||
jit_float_table[i].index = OP_RND_TO_CEIL;
|
||||
} else if (!strcmp(name, "RoundToFloor")) {
|
||||
data->jit_float_table[i].found = true;
|
||||
data->jit_float_table[i].index = OP_RND_TO_FLOOR;
|
||||
jit_float_table[i].found = true;
|
||||
jit_float_table[i].index = OP_RND_TO_FLOOR;
|
||||
} else if (!strcmp(name, "RoundToNearest")) {
|
||||
data->jit_float_table[i].found = true;
|
||||
data->jit_float_table[i].index = OP_RND_TO_NEAREST;
|
||||
jit_float_table[i].found = true;
|
||||
jit_float_table[i].index = OP_RND_TO_NEAREST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ICompilation *JITX86::StartCompilation(BaseRuntime *runtime)
|
||||
{
|
||||
CompData *data = new CompData;
|
||||
|
||||
data->SetRuntime(runtime);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void JITX86::AbortCompilation(ICompilation *co)
|
||||
void CompData::Abort()
|
||||
{
|
||||
if (((CompData *)co)->rebase)
|
||||
if (rebase)
|
||||
{
|
||||
engine->BaseFree(((CompData *)co)->rebase);
|
||||
engine->BaseFree(rebase);
|
||||
}
|
||||
delete [] ((CompData *)co)->jit_float_table;
|
||||
delete (CompData *)co;
|
||||
delete [] jit_float_table;
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool JITX86::SetCompilationOption(ICompilation *co, const char *key, const char *val)
|
||||
void JITX86::FreeContextVars(sp_context_t *ctx)
|
||||
{
|
||||
CompData *data = (CompData *)co;
|
||||
free(((tracker_t *)(ctx->vm[JITVARS_TRACKER]))->pBase);
|
||||
delete (tracker_t *)ctx->vm[JITVARS_TRACKER];
|
||||
}
|
||||
|
||||
void JITX86::FreePluginVars(sp_plugin_t *pl)
|
||||
{
|
||||
delete [] pl->files;
|
||||
delete [] pl->lines;
|
||||
delete [] pl->natives;
|
||||
delete [] pl->publics;
|
||||
delete [] pl->pubvars;
|
||||
delete [] pl->symbols;
|
||||
|
||||
if (pl->codebase != NULL)
|
||||
{
|
||||
g_engine1.FreePageMemory(pl->codebase);
|
||||
pl->codebase = NULL;
|
||||
}
|
||||
|
||||
pl->files = NULL;
|
||||
pl->lines = NULL;
|
||||
pl->natives = NULL;
|
||||
pl->publics = NULL;
|
||||
pl->pubvars = NULL;
|
||||
pl->symbols = NULL;
|
||||
}
|
||||
|
||||
bool CompData::SetOption(const char *key, const char *val)
|
||||
{
|
||||
if (strcmp(key, SP_JITCONF_DEBUG) == 0)
|
||||
{
|
||||
if ((atoi(val) == 1) || !strcmp(val, "yes"))
|
||||
{
|
||||
data->debug = true;
|
||||
debug = true;
|
||||
} else {
|
||||
data->debug = false;
|
||||
debug = false;
|
||||
}
|
||||
if (data->debug && !(data->plugin->flags & SP_FLAG_DEBUG))
|
||||
if (debug && plugin && !(plugin->flags & SP_FLAG_DEBUG))
|
||||
{
|
||||
data->debug = false;
|
||||
debug = false;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (strcmp(key, SP_JITCONF_PROFILE) == 0)
|
||||
{
|
||||
data->profile = atoi(val);
|
||||
profile = atoi(val);
|
||||
|
||||
/** Callbacks must be profiled to profile functions! */
|
||||
if ((data->profile & SP_PROF_FUNCTIONS) == SP_PROF_FUNCTIONS)
|
||||
if ((profile & SP_PROF_FUNCTIONS) == SP_PROF_FUNCTIONS)
|
||||
{
|
||||
data->profile |= SP_PROF_CALLBACKS;
|
||||
profile |= SP_PROF_CALLBACKS;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -2979,83 +3047,3 @@ bool JITX86::SetCompilationOption(ICompilation *co, const char *key, const char
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int JITX86::GetAPIVersion()
|
||||
{
|
||||
return SOURCEPAWN_VM_API_VERSION;
|
||||
}
|
||||
|
||||
bool JITX86::FunctionPLookup(const sp_context_t *ctx, uint32_t code_addr, unsigned int *result)
|
||||
{
|
||||
uint8_t *rebase = (uint8_t *)ctx->vm[JITVARS_REBASE];
|
||||
|
||||
/* Is this within the pcode bounds? */
|
||||
if (code_addr >= ctx->plugin->pcode_size - sizeof(uint32_t))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Relocate this */
|
||||
code_addr = *(jitoffs_t *)(rebase + code_addr);
|
||||
|
||||
/* Check if this is in the relocation bounds */
|
||||
functracker_t *fnc = (functracker_t *)ctx->vm[JITVARS_FUNCINFO];
|
||||
if (code_addr >= fnc->code_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get the function info and sanity check */
|
||||
funcinfo_t *f = (funcinfo_t *)((char *)ctx->codebase + code_addr - sizeof(funcinfo_t));
|
||||
if (f->magic != JIT_FUNCMAGIC || f->index >= fnc->num_functions)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
*result = f->index;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JITX86::FunctionLookup(const sp_context_t *ctx, uint32_t code_addr, unsigned int *result)
|
||||
{
|
||||
/* Check if this is in the relocation bounds */
|
||||
functracker_t *fnc = (functracker_t *)ctx->vm[JITVARS_FUNCINFO];
|
||||
if (code_addr >= fnc->code_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get the function info and sanity check */
|
||||
funcinfo_t *f = (funcinfo_t *)((char *)ctx->codebase + code_addr - sizeof(funcinfo_t));
|
||||
if (f->magic != JIT_FUNCMAGIC || f->index >= fnc->num_functions)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
*result = f->index;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int JITX86::FunctionCount(const sp_context_t *ctx)
|
||||
{
|
||||
functracker_t *fnc = (functracker_t *)ctx->vm[JITVARS_FUNCINFO];
|
||||
|
||||
return fnc->num_functions;
|
||||
}
|
||||
|
||||
const char *JITX86::GetVersionString()
|
||||
{
|
||||
return SVN_FULL_VERSION;
|
||||
}
|
||||
|
||||
const char *JITX86::GetCPUOptimizations()
|
||||
{
|
||||
return "Generic i686";
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <sp_vm_types.h>
|
||||
#include <sp_vm_api.h>
|
||||
#include <jit_helpers.h>
|
||||
#include "../jit_shared.h"
|
||||
#include "../BaseRuntime.h"
|
||||
|
||||
using namespace SourcePawn;
|
||||
|
||||
@@ -44,11 +46,14 @@ using namespace SourcePawn;
|
||||
#define JIT_FUNCMAGIC 0x214D4148 //magic function offset
|
||||
|
||||
#define JITVARS_TRACKER 0 //important: don't change this to avoid trouble
|
||||
#define JITVARS_FUNCINFO 1 //important: don't change this aWOAWOGJQG I LIKE HAM
|
||||
#define JITVARS_REBASE 2 //important: hi, i'm bail
|
||||
#define JITVARS_BASECTX 1 //important: don't change this aWOAWOGJQG I LIKE HAM
|
||||
#define JITVARS_PROFILER 2 //profiler
|
||||
#define JITVARS_PLUGIN 3 //sp_plugin_t
|
||||
|
||||
#define sDIMEN_MAX 5 //this must mirror what the compiler has.
|
||||
|
||||
#define GET_CONTEXT(c) ((IPluginContext *)c->vm[JITVARS_BASECTX])
|
||||
|
||||
typedef struct tracker_s
|
||||
{
|
||||
size_t size;
|
||||
@@ -87,7 +92,11 @@ public:
|
||||
error_set(SP_ERROR_NONE), func_idx(0)
|
||||
{
|
||||
};
|
||||
bool SetOption(const char *key, const char *val);
|
||||
void SetRuntime(BaseRuntime *runtime);
|
||||
void Abort();
|
||||
public:
|
||||
BaseRuntime *runtime; /* runtime handle */
|
||||
sp_plugin_t *plugin; /* plugin handle */
|
||||
bool debug; /* whether to compile debug mode */
|
||||
int profile; /* profiling flags */
|
||||
@@ -116,22 +125,15 @@ public:
|
||||
uint32_t codesize; /* total codesize */
|
||||
};
|
||||
|
||||
class JITX86 : public IVirtualMachine
|
||||
class JITX86
|
||||
{
|
||||
public:
|
||||
const char *GetVMName();
|
||||
ICompilation *StartCompilation(sp_plugin_t *plugin);
|
||||
bool SetCompilationOption(ICompilation *co, const char *key, const char *val);
|
||||
sp_context_t *CompileToContext(ICompilation *co, int *err);
|
||||
void AbortCompilation(ICompilation *co);
|
||||
void FreeContext(sp_context_t *ctx);
|
||||
int ContextExecute(sp_context_t *ctx, uint32_t code_idx, cell_t *result);
|
||||
unsigned int GetAPIVersion();
|
||||
bool FunctionLookup(const sp_context_t *ctx, uint32_t code_addr, unsigned int *result);
|
||||
bool FunctionPLookup(const sp_context_t *ctx, uint32_t code_addr, unsigned int *result);
|
||||
unsigned int FunctionCount(const sp_context_t *ctx);
|
||||
const char *GetVersionString();
|
||||
const char *GetCPUOptimizations();
|
||||
ICompilation *StartCompilation(BaseRuntime *runtime);
|
||||
ICompilation *StartCompilation();
|
||||
bool Compile(ICompilation *co, BaseRuntime *runtime, int *err);
|
||||
void FreePluginVars(sp_plugin_t *pl);
|
||||
void FreeContextVars(sp_context_t *ctx);
|
||||
int ContextExecute(sp_plugin_t *pl, sp_context_t *ctx, uint32_t code_idx, cell_t *result);
|
||||
SPVM_NATIVE_FUNC CreateFakeNative(SPVM_FAKENATIVE_FUNC callback, void *pData);
|
||||
void DestroyFakeNative(SPVM_NATIVE_FUNC func);
|
||||
};
|
||||
@@ -157,6 +159,6 @@ jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative=false);
|
||||
#define AMX_INFO_CONTEXT 12 //physical
|
||||
#define AMX_INFO_STACKTOP 16 //relocated
|
||||
|
||||
extern ISourcePawnEngine *engine;
|
||||
extern JITX86 g_Jit1;
|
||||
|
||||
#endif //_INCLUDE_SOURCEPAWN_JIT_X86_H_
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jit-x86", "jit-x86.vcproj", "{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,296 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="jit-x86"
|
||||
ProjectGUID="{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}"
|
||||
RootNamespace="jitx86"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\..\..\public\jit;..\..\..\..\public\jit\x86;..\..\..\..\public\sourcepawn"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;JITX86_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\sourcepawn.jit.x86.dll"
|
||||
LinkIncremental="2"
|
||||
IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMT"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="..\..\..\..\public\jit;..\..\..\..\public\jit\x86;..\..\..\..\public\sourcepawn"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;JITX86_EXPORTS"
|
||||
RuntimeLibrary="0"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)\sourcepawn.jit.x86.dll"
|
||||
LinkIncremental="1"
|
||||
IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMTD"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\dll_exports.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\jit_x86.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\opcode_helpers.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\dll_exports.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\public\jit\jit_helpers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\jit_version.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\jit_x86.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\opcode_helpers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\ungen_opcodes.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\public\jit\x86\x86_macros.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\jit_version.tpl"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\opcode_switch.inc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\ungen_opcode_switch.inc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\version.rc"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="SDK"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\jit_helpers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\public\sourcepawn\sp_file_headers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\public\sourcepawn\sp_typeutil.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\public\sourcepawn\sp_vm_api.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\public\sourcepawn\sp_vm_base.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\..\public\sourcepawn\sp_vm_types.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
jitoffs_t Write_Execute_Function(JitWriter *jit)
|
||||
{
|
||||
CompData *co = (CompData *)jit->data;
|
||||
/**
|
||||
* The variables we're passed in:
|
||||
* sp_context_t *ctx, uint32_t code_idx, cell_t *result
|
||||
@@ -76,14 +77,14 @@ jitoffs_t Write_Execute_Function(JitWriter *jit)
|
||||
//mov [esi+12], eax - store context into info pointer
|
||||
//mov ecx, [eax+<offs>] - get heap pointer
|
||||
//mov [esi+4], ecx - store heap into info pointer
|
||||
//mov ebp, [eax+<offs>] - get data pointer
|
||||
//mov ebp, <addr> - get data pointer
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, 16);
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_EAX, AMX_INFO_RETVAL);
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, 8);
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_EAX, AMX_INFO_CONTEXT);
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, hp));
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_HEAP);
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_DAT, REG_EAX, offsetof(sp_context_t, memory));
|
||||
IA32_Mov_Reg_Imm32(jit, AMX_REG_DAT, jit_int32_t(co->plugin->memory));
|
||||
|
||||
/* Frame setup */
|
||||
//mov edi, [eax+<offs>] - get stack pointer
|
||||
@@ -97,15 +98,23 @@ jitoffs_t Write_Execute_Function(JitWriter *jit)
|
||||
//mov ecx, [eax+<offs>] - copy memsize to temp var
|
||||
//add ecx, ebp - relocate
|
||||
//mov [esi+x], ecx - store relocated
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, mem_size));
|
||||
IA32_Mov_Reg_Imm32(jit, REG_ECX, co->plugin->mem_size);
|
||||
IA32_Add_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_DAT, MOD_REG);
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_STACKTOP);
|
||||
|
||||
/* Remaining needed vars */
|
||||
//mov ecx, [esp+(4*(NUM_INFO_PARAMS+3))+12] - get code index (normally esp+12, but we have another array on the stack)
|
||||
//add ecx, [eax+<offs>] - add code base to index
|
||||
//push eax
|
||||
//mov eax, <addr of addr of code>
|
||||
//mov eax, [eax]
|
||||
//add ecx, eax
|
||||
//pop eax
|
||||
IA32_Mov_Reg_Esp_Disp8(jit, REG_ECX, 12+(4*(NUM_INFO_PARAMS+3)));
|
||||
IA32_Add_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, codebase));
|
||||
IA32_Push_Reg(jit, REG_EAX);
|
||||
IA32_Mov_Reg_Imm32(jit, REG_EAX, jit_int32_t(&co->plugin->codebase));
|
||||
IA32_Mov_Reg_Rm(jit, REG_EAX, REG_EAX, MOD_MEM_REG);
|
||||
IA32_Add_Reg_Rm(jit, REG_ECX, REG_EAX, MOD_REG);
|
||||
IA32_Pop_Reg(jit, REG_EAX);
|
||||
|
||||
/* by now, everything is set up, so we can call into the plugin */
|
||||
//call ecx
|
||||
@@ -161,36 +170,30 @@ void Write_BreakDebug(JitWriter *jit)
|
||||
//push edi
|
||||
//mov edi, ecx
|
||||
//mov ecx, [esi+ctx]
|
||||
//cmp [ecx+dbreak], 0
|
||||
//jnz :nocall
|
||||
IA32_Push_Reg(jit, REG_EDI);
|
||||
IA32_Mov_Reg_Rm(jit, REG_EDI, REG_ECX, MOD_REG);
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
|
||||
IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, dbreak), 0);
|
||||
jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_Z, 0);
|
||||
|
||||
//:TODO: align the stack to 16bytes like in sysreq.x
|
||||
/* NOTE, Hack! PUSHAD pushes EDI last which still has the CIP */
|
||||
//pushad
|
||||
//push [esi+frm]
|
||||
//push ctx
|
||||
//mov ecx, [ecx+dbreak]
|
||||
//push [ctx+basectx]
|
||||
//mov ecx, <dbreak>
|
||||
//call ecx
|
||||
//add esp, 8
|
||||
//popad
|
||||
IA32_Pushad(jit);
|
||||
IA32_Push_Rm_Disp8(jit, AMX_REG_INFO, AMX_INFO_FRAME); //:TODO: move to regs and push? and dont disp for 0
|
||||
IA32_Push_Reg(jit, AMX_REG_TMP);
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_TMP, offsetof(sp_context_t, dbreak));
|
||||
IA32_Push_Rm_Disp8(jit, AMX_REG_TMP, offsetof(sp_context_t, vm[JITVARS_BASECTX]));
|
||||
IA32_Mov_Reg_Imm32(jit, AMX_REG_TMP, jit_int32_t(((CompData *)jit->data)->plugin->dbreak));
|
||||
IA32_Call_Reg(jit, AMX_REG_TMP);
|
||||
IA32_Add_Rm_Imm8(jit, REG_ESP, 4*2, MOD_REG);
|
||||
IA32_Popad(jit);
|
||||
|
||||
//:nocall
|
||||
//pop edi
|
||||
//ret
|
||||
IA32_Pop_Reg(jit, REG_EDI);
|
||||
IA32_Send_Jump8_Here(jit, jmp);
|
||||
IA32_Return(jit);
|
||||
}
|
||||
|
||||
@@ -314,7 +317,7 @@ void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg)
|
||||
/* Part 1: Check if we're in the memory bounds */
|
||||
//cmp <reg>, <stpu>
|
||||
//jae :error
|
||||
IA32_Cmp_Rm_Imm32(jit, MOD_REG, reg, ((CompData *)jit->data)->plugin->memory);
|
||||
IA32_Cmp_Rm_Imm32(jit, MOD_REG, reg, ((CompData *)jit->data)->plugin->mem_size);
|
||||
IA32_Jump_Cond_Imm32_Abs(jit, CC_AE, ((CompData *)jit->data)->jit_error_memaccess);
|
||||
|
||||
/* Part 2: Check if we're in the invalid region between HP and SP */
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
#include "jit_version.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION SVN_FILE_VERSION
|
||||
PRODUCTVERSION SVN_FILE_VERSION
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "000004b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "SourcePawn JIT"
|
||||
VALUE "FileDescription", "SourcePawn JIT/Virtual Machine"
|
||||
VALUE "FileVersion", SVN_FULL_VERSION
|
||||
VALUE "InternalName", "sourcemod"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2004-2008, AlliedModders LLC"
|
||||
VALUE "OriginalFilename", "sourcepawn.jit.x86.dll"
|
||||
VALUE "ProductName", "SourcePawn JIT"
|
||||
VALUE "ProductVersion", SVN_FULL_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0, 1200
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
Reference in New Issue
Block a user