Whoa! Merged in Pawn! (Small 3.0)
Removed debug handling (will add back in soon) Ported all amx_Exec()s to forward systems Deprecated AMX Mod module support (incompatible with Pawn anyway!) Deprecated many file natives (unused) Deprecated some functionality of pause/unpause Fixed some memory deallocation bugs (thanks fysh) Bumped module API version to 3 (no new M/SDK yet!) Bumped AMX Mod X version to 1.5! Merged in CVector changes
This commit is contained in:
parent
955aa04b41
commit
4609cb409b
@ -396,40 +396,21 @@ void EventsMngr::parseValue(const char *sz)
|
||||
|
||||
void EventsMngr::executeEvents()
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!m_ParseFun)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
try
|
||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
||||
{
|
||||
#endif // #ifdef ENABLEEXEPTIONS
|
||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
||||
if ( (*iter).m_Done )
|
||||
{
|
||||
if ( (*iter).m_Done )
|
||||
{
|
||||
(*iter).m_Done = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
(*iter).m_Stamp = (float)*m_Timer;
|
||||
|
||||
if ((err = amx_Exec((*iter).m_Plugin->getAMX(), NULL, (*iter).m_Func, 1, m_ParseVault ? m_ParseVault[0].iValue : 0)) != AMX_ERR_NONE)
|
||||
{
|
||||
LogError((*iter).m_Plugin->getAMX(), err, "");
|
||||
}
|
||||
(*iter).m_Done = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
(*iter).m_Stamp = (float)*m_Timer;
|
||||
executeForwards((*iter).m_Func, m_ParseVault ? m_ParseVault[0].iValue : 0);
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
AMXXLOG_Log( "[AMXX] fatal error at event execution");
|
||||
}
|
||||
#endif // #ifdef ENABLEEXEPTIONS
|
||||
|
||||
m_CurrentMsgType = -1;
|
||||
m_ParseFun = NULL;
|
||||
|
@ -71,7 +71,7 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
if (iter->pPlugin->isExecutable(iter->func))
|
||||
{
|
||||
// handle strings & arrays
|
||||
int i;
|
||||
int i, ax=0;
|
||||
for (i = 0; i < m_NumParams; ++i)
|
||||
{
|
||||
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
||||
@ -80,7 +80,7 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
amx_Allot(iter->pPlugin->getAMX(),
|
||||
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH,
|
||||
&realParams[i], &tmp);
|
||||
amx_SetString(tmp, (const char *)(params[i]), 0, 0);
|
||||
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
|
||||
physAddrs[i] = tmp;
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
@ -105,9 +105,14 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
realParams[i] = params[i];
|
||||
}
|
||||
}
|
||||
//Push the parameters in reverse order. Weird, unfriendly part of Small 3.0!
|
||||
for (i=m_NumParams-1; i>=0; i--)
|
||||
{
|
||||
amx_Push(iter->pPlugin->getAMX(), realParams[i]);
|
||||
}
|
||||
// exec
|
||||
cell retVal;
|
||||
int err = amx_Execv(iter->pPlugin->getAMX(), &retVal, iter->func, m_NumParams, realParams);
|
||||
int err = amx_Exec(iter->pPlugin->getAMX(), &retVal, iter->func);
|
||||
// log runtime error, if any
|
||||
if (err != AMX_ERR_NONE)
|
||||
LogError(iter->pPlugin->getAMX(), err, "");
|
||||
@ -122,7 +127,7 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
else if (m_ParamTypes[i] == FP_STRINGEX)
|
||||
{
|
||||
// copy back
|
||||
amx_GetString(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
||||
amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
||||
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
@ -216,7 +221,7 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
amx_Allot(m_Amx,
|
||||
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH,
|
||||
&realParams[i], &tmp);
|
||||
amx_SetString(tmp, (const char *)(params[i]), 0, 0);
|
||||
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
|
||||
physAddrs[i] = tmp;
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
@ -241,10 +246,11 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
realParams[i] = params[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i=m_NumParams-1; i>=0; i--)
|
||||
amx_Push(m_Amx, realParams[i]);
|
||||
// exec
|
||||
cell retVal;
|
||||
int err = amx_Execv(m_Amx, &retVal, m_Func, m_NumParams, realParams);
|
||||
int err = amx_Exec(m_Amx, &retVal, m_Func);
|
||||
|
||||
// log runtime error, if any
|
||||
if (err != AMX_ERR_NONE)
|
||||
@ -260,7 +266,7 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
else if (m_ParamTypes[i] == FP_STRINGEX)
|
||||
{
|
||||
// copy back
|
||||
amx_GetString(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
||||
amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
||||
amx_Release(m_Amx, realParams[i]);
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
|
@ -151,7 +151,6 @@ LogEventsMngr::CLogEvent* LogEventsMngr::registerLogEvent( CPluginMngr::CPlugin*
|
||||
|
||||
void LogEventsMngr::executeLogEvents()
|
||||
{
|
||||
int err;
|
||||
bool valid;
|
||||
for(CLogEvent* a = logevents[ logArgc ]; a ; a = a->next)
|
||||
{
|
||||
@ -171,8 +170,7 @@ void LogEventsMngr::executeLogEvents()
|
||||
|
||||
if (valid)
|
||||
{
|
||||
if ((err = amx_Exec(a->plugin->getAMX(), NULL , a->func , 0)) != AMX_ERR_NONE)
|
||||
LogError(a->plugin->getAMX(), err, "");
|
||||
executeForwards(a->func);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ MenuMngr::~MenuMngr()
|
||||
int MenuMngr::findMenuId(const char* name, AMX* amx)
|
||||
{
|
||||
for( MenuIdEle* b = headid; b ; b = b->next) {
|
||||
if ( (!b->amx || amx == b->amx) && strstr(name,b->name.c_str()) )
|
||||
if ( (!amx || !b->amx || amx == b->amx) && strstr(name,b->name.c_str()) )
|
||||
return b->id;
|
||||
}
|
||||
return 0;
|
||||
|
@ -35,11 +35,6 @@
|
||||
#define FAR
|
||||
#endif
|
||||
|
||||
// Old
|
||||
typedef int (FAR *QUERYMOD)(module_info_s**);
|
||||
typedef int (FAR *ATTACHMOD)(pfnamx_engine_g*,pfnmodule_engine_g*);
|
||||
typedef int (FAR *DETACHMOD)(void);
|
||||
|
||||
// New
|
||||
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
||||
typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo*/);
|
||||
@ -47,81 +42,6 @@ typedef int (FAR *ATTACHMOD_NEW)(PFN_REQ_FNPTR /*reqFnptrFunc*/);
|
||||
typedef int (FAR *DETACHMOD_NEW)(void);
|
||||
typedef void (FAR *PLUGINSLOADED_NEW)(void);
|
||||
|
||||
// Old
|
||||
// These functions are needed since Small Abstract Machine 2.5.0
|
||||
int wamx_FindPublic(AMX *amx, char *name, int *index)
|
||||
{ return amx_FindPublic(amx, name, index); }
|
||||
|
||||
int wamx_FindPubVar(AMX *amx, char *varname, cell *amx_addr)
|
||||
{ return amx_FindPubVar(amx, varname, amx_addr); }
|
||||
|
||||
int wamx_GetString(char *dest, cell *source)
|
||||
{ return amx_GetString(dest, source, 0); }
|
||||
|
||||
AMX_NATIVE_INFO *wamx_NativeInfo(char *name, AMX_NATIVE func)
|
||||
{ return amx_NativeInfo(name, func); }
|
||||
|
||||
int wamx_SetString(cell *dest, char *source, int pack)
|
||||
{ return amx_SetString(dest, source, pack, 0); }
|
||||
|
||||
pfnamx_engine_g engAmxFunc = {
|
||||
amx_Align16,
|
||||
amx_Align32,
|
||||
amx_Allot,
|
||||
amx_Callback,
|
||||
amx_Clone,
|
||||
amx_Debug,
|
||||
amx_Exec,
|
||||
amx_Execv,
|
||||
wamx_FindPublic,
|
||||
wamx_FindPubVar,
|
||||
amx_FindTagId,
|
||||
amx_Flags,
|
||||
amx_GetAddr,
|
||||
amx_GetPublic,
|
||||
amx_GetPubVar,
|
||||
wamx_GetString,
|
||||
amx_GetTag,
|
||||
amx_GetUserData,
|
||||
amx_Init,
|
||||
amx_InitJIT,
|
||||
amx_MemInfo,
|
||||
amx_NameLength,
|
||||
wamx_NativeInfo,
|
||||
amx_NumPublics,
|
||||
amx_NumPubVars,
|
||||
amx_NumTags,
|
||||
amx_RaiseError,
|
||||
amx_Register,
|
||||
amx_Release,
|
||||
amx_SetCallback,
|
||||
amx_SetDebugHook,
|
||||
wamx_SetString,
|
||||
amx_SetUserData,
|
||||
amx_StrLen,
|
||||
};
|
||||
|
||||
pfnmodule_engine_g engModuleFunc = {
|
||||
add_amxnatives,
|
||||
build_pathname,
|
||||
copy_amxmemory,
|
||||
format_amxstring,
|
||||
get_amxaddr,
|
||||
get_amxscript,
|
||||
get_amxscriptname,
|
||||
get_amxstring,
|
||||
get_modname,
|
||||
load_amxscript,
|
||||
print_srvconsole,
|
||||
report_error,
|
||||
set_amxnatives,
|
||||
set_amxstring,
|
||||
amxstring_len,
|
||||
unload_amxscript,
|
||||
alloc_amxmemory,
|
||||
free_amxmemory,
|
||||
};
|
||||
|
||||
// *****************************************************
|
||||
// class CModule
|
||||
// *****************************************************
|
||||
@ -150,8 +70,6 @@ void CModule::clear(bool clearFilename)
|
||||
if (clearFilename)
|
||||
m_Filename.assign("unknown");
|
||||
|
||||
// old
|
||||
m_InfoOld = NULL;
|
||||
// new
|
||||
m_Amxx = false;
|
||||
m_InfoNew.author = "unknown";
|
||||
@ -220,17 +138,11 @@ bool CModule::attachModule()
|
||||
m_Status = MODULE_BADLOAD;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
m_Status = MODULE_BADLOAD;
|
||||
}
|
||||
else
|
||||
{
|
||||
// old
|
||||
ATTACHMOD AttachFunc = (ATTACHMOD)DLPROC(m_Handle, "AMX_Attach");
|
||||
|
||||
if (AttachFunc)
|
||||
(*AttachFunc)(&engAmxFunc,&engModuleFunc);
|
||||
m_Status = MODULE_LOADED;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CModule::queryModule()
|
||||
@ -292,44 +204,9 @@ bool CModule::queryModule()
|
||||
}
|
||||
else
|
||||
{
|
||||
// old interface not 64 bit compatible
|
||||
#if SMALL_CELL_SIZE == 64
|
||||
m_Status = MODULE_NOT64BIT;
|
||||
m_Status = MODULE_NOQUERY;
|
||||
m_Amxx = false;
|
||||
return false;
|
||||
#else
|
||||
// Try old interface
|
||||
QUERYMOD queryFunc_Old = (QUERYMOD)DLPROC(m_Handle,"AMX_Query"); // check what version
|
||||
if (!queryFunc_Old)
|
||||
{
|
||||
m_Status = MODULE_NOQUERY;
|
||||
return false;
|
||||
}
|
||||
|
||||
(*queryFunc_Old)(&m_InfoOld);
|
||||
|
||||
if (!m_InfoOld)
|
||||
{
|
||||
m_Status = MODULE_NOINFO;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_InfoOld->ivers != AMX_INTERFACE_VERSION)
|
||||
{
|
||||
m_Status = MODULE_OLD;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for attach
|
||||
if (!DLPROC(m_Handle, "AMX_Attach"))
|
||||
{
|
||||
m_Status = MODULE_NOATTACH;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_InfoOld->serial = (long int)this;
|
||||
m_Status = MODULE_QUERY;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -350,12 +227,6 @@ bool CModule::detachModule()
|
||||
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DETACHMOD detachFunc_Old = (DETACHMOD)DLPROC(m_Handle, "AMX_Detach");
|
||||
if (detachFunc_Old)
|
||||
(*detachFunc_Old)();
|
||||
}
|
||||
#ifndef FAKEMETA
|
||||
if (IsMetamod())
|
||||
{
|
||||
|
@ -66,14 +66,13 @@ struct amxx_module_info_s
|
||||
#define AMXX_PARAM 2 /* Invalid parameter */
|
||||
#define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */
|
||||
|
||||
#define AMXX_INTERFACE_VERSION 2
|
||||
#define AMXX_INTERFACE_VERSION 3
|
||||
|
||||
class CModule
|
||||
{
|
||||
String m_Filename; // Filename
|
||||
bool m_Metamod; // Using metamod?
|
||||
bool m_Amxx; // Using new module interface?
|
||||
module_info_s* m_InfoOld; // module info (old module interface)
|
||||
amxx_module_info_s m_InfoNew; // module info (new module interface)
|
||||
DLHANDLE m_Handle; // handle
|
||||
MODULE_STATUS m_Status; // status
|
||||
@ -93,14 +92,13 @@ public:
|
||||
#endif
|
||||
const char* getStatus() const;
|
||||
inline const char* getType() const { return m_Amxx ? "amxx" : (m_Metamod ? "amx&mm" : "amx"); }
|
||||
inline const char* getAuthor() const { return m_Amxx ? (m_InfoNew.author) : (m_InfoOld ? m_InfoOld->author : "unknown"); }
|
||||
inline const char* getVersion() const { return m_Amxx ? (m_InfoNew.version) : (m_InfoOld ? m_InfoOld->version : "unknown"); }
|
||||
inline const char* getName() const { return m_Amxx ? (m_InfoNew.name) : (m_InfoOld ? m_InfoOld->name : "unknown"); }
|
||||
inline module_info_s* getInfo() const { return m_InfoOld; } // old
|
||||
inline const char* getAuthor() const { return m_InfoNew.author; }
|
||||
inline const char* getVersion() const { return m_InfoNew.version; }
|
||||
inline const char* getName() const { return m_InfoNew.name; }
|
||||
inline const amxx_module_info_s* getInfoNew() const { return &m_InfoNew; } // new
|
||||
inline int getStatusValue() { return m_Status; }
|
||||
inline bool operator==( const char* fname ) { return !strcmp( m_Filename.c_str() , fname ); }
|
||||
inline bool isReloadable() { return m_Amxx ? ((m_Status == MODULE_LOADED) && (m_InfoNew.reload != 0)) : ( (m_Status==MODULE_LOADED) && (m_InfoOld->type==RELOAD_MODULE)); }
|
||||
inline bool isReloadable() { return ((m_Status == MODULE_LOADED) && (m_InfoNew.reload != 0)); }
|
||||
inline bool isAmxx() const { return m_Amxx; }
|
||||
inline const char *getMissingFunc() const { return m_MissingFunc; }
|
||||
inline const char *getFilename() { return m_Filename.c_str(); }
|
||||
|
@ -172,38 +172,12 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p,const char* n, char* e, int d
|
||||
paused_fun = 0;
|
||||
next = 0;
|
||||
id = i;
|
||||
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause");
|
||||
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause");
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin::~CPlugin( )
|
||||
{
|
||||
AMX_DBG *pDbg = (AMX_DBG *)amx.userdata[0];
|
||||
|
||||
if (pDbg)
|
||||
{
|
||||
if (pDbg->files)
|
||||
{
|
||||
for (int i=0; i<pDbg->numFiles; i++)
|
||||
{
|
||||
if (pDbg->files[i])
|
||||
{
|
||||
free(pDbg->files[i]);
|
||||
pDbg->files[i] = NULL;
|
||||
}
|
||||
}
|
||||
free(pDbg->files);
|
||||
}
|
||||
AMX_TRACE *pTrace = pDbg->head;
|
||||
AMX_TRACE *pNext = NULL;
|
||||
while (pTrace)
|
||||
{
|
||||
pNext = pTrace->next;
|
||||
free(pTrace);
|
||||
pTrace = pNext;
|
||||
}
|
||||
free(pDbg);
|
||||
amx.userdata[0] = NULL;
|
||||
}
|
||||
|
||||
unload_amxscript( &amx, &code );
|
||||
}
|
||||
|
||||
@ -232,16 +206,8 @@ void CPluginMngr::CPlugin::pausePlugin()
|
||||
if (isValid())
|
||||
{
|
||||
// call plugin_pause if provided
|
||||
int func;
|
||||
cell retval;
|
||||
if (amx_FindPublic(&amx, "plugin_pause", &func) == AMX_ERR_NONE)
|
||||
{
|
||||
if (isExecutable(func))
|
||||
{
|
||||
|
||||
amx_Exec(&amx, &retval, func, 0);
|
||||
}
|
||||
}
|
||||
if (m_PauseFwd != -1)
|
||||
executeForwards(m_PauseFwd);
|
||||
|
||||
setStatus(ps_paused);
|
||||
}
|
||||
@ -256,14 +222,7 @@ void CPluginMngr::CPlugin::unpausePlugin()
|
||||
|
||||
setStatus(ps_running);
|
||||
// call plugin_unpause if provided
|
||||
int func;
|
||||
cell retval;
|
||||
if (amx_FindPublic(&amx, "plugin_unpause", &func) == AMX_ERR_NONE)
|
||||
{
|
||||
if (isExecutable(func))
|
||||
{
|
||||
amx_Exec(&amx, &retval, func, 0);
|
||||
}
|
||||
}
|
||||
if (m_UnpauseFwd != -1)
|
||||
executeForwards(m_UnpauseFwd);
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,8 @@ public:
|
||||
String title;
|
||||
String author;
|
||||
String errorMsg;
|
||||
int m_PauseFwd;
|
||||
int m_UnpauseFwd;
|
||||
int paused_fun;
|
||||
int status;
|
||||
CPlugin* next;
|
||||
@ -88,8 +90,8 @@ public:
|
||||
inline void setError( const char* n ) { errorMsg.assign(n); }
|
||||
inline bool isValid() const { return ((status != ps_bad_load) && (status != ps_locked)); }
|
||||
inline bool isPaused() const { return ( (status == ps_paused) || (status == ps_stopped)); }
|
||||
inline bool isFunctionPaused( int id ) const { return (paused_fun & (1<<id)) ? true : false; }
|
||||
inline bool isExecutable(int id) const { return (isValid() && !isPaused() && !isFunctionPaused(id)); }
|
||||
//inline bool isFunctionPaused( int id ) const { return (paused_fun & (1<<id)) ? true : false; }
|
||||
inline bool isExecutable(int id) const { return (isValid() && !isPaused()); }
|
||||
void pausePlugin();
|
||||
void unpausePlugin();
|
||||
void pauseFunction( int id );
|
||||
|
@ -48,7 +48,8 @@ template <class T> class CVector
|
||||
return false;
|
||||
if (m_Data)
|
||||
{
|
||||
memcpy(newData, m_Data, m_Size * sizeof(T));
|
||||
for (size_t i=0; i<m_CurrentUsedSize; i++)
|
||||
newData[i] = m_Data[i];
|
||||
delete [] m_Data;
|
||||
}
|
||||
m_Data = newData;
|
||||
@ -74,7 +75,9 @@ template <class T> class CVector
|
||||
return false;
|
||||
if (m_Data)
|
||||
{
|
||||
memcpy(newData, m_Data, (m_Size < size) ? (m_Size * sizeof(T)) : (size * sizeof(T)));
|
||||
size_t end = (m_Size < size) ? (m_Size) : size;
|
||||
for (size_t i=0; i<end; i++)
|
||||
newData[i] = m_Data[i];
|
||||
delete [] m_Data;
|
||||
}
|
||||
if (m_Size < size)
|
||||
@ -251,10 +254,11 @@ public:
|
||||
CVector<T>(const CVector<T> & other)
|
||||
{
|
||||
// copy data
|
||||
m_Data = new T [other.m_Size];
|
||||
m_Size = other.m_Size;
|
||||
m_Data = new T [other.m_CurrentUsedSize];
|
||||
m_Size = other.m_CurrentUsedSize;
|
||||
m_CurrentUsedSize = other.m_CurrentUsedSize;
|
||||
memcpy(m_Data, other.m_Data, m_CurrentUsedSize * sizeof(T));
|
||||
for (size_t i=0; i<other.m_CurrentUsedSize; i++)
|
||||
m_Data[i] = other.m_Data[i];
|
||||
}
|
||||
|
||||
~CVector<T>()
|
||||
|
BIN
amxmodx/JIT/amxexecn.o
Executable file
BIN
amxmodx/JIT/amxexecn.o
Executable file
Binary file not shown.
BIN
amxmodx/JIT/amxexecn.obj
Executable file
BIN
amxmodx/JIT/amxexecn.obj
Executable file
Binary file not shown.
BIN
amxmodx/JIT/amxjitsn.o
Executable file
BIN
amxmodx/JIT/amxjitsn.o
Executable file
Binary file not shown.
BIN
amxmodx/JIT/amxjitsn.obj
Executable file
BIN
amxmodx/JIT/amxjitsn.obj
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
1548
amxmodx/amx.cpp
1548
amxmodx/amx.cpp
File diff suppressed because it is too large
Load Diff
275
amxmodx/amx.h
275
amxmodx/amx.h
@ -1,6 +1,6 @@
|
||||
/* Abstract Machine for the Small compiler
|
||||
/* Pawn Abstract Machine (for the Pawn language)
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 1997-2004
|
||||
* Copyright (c) ITB CompuPhase, 1997-2005
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
@ -21,54 +21,98 @@
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#if defined __linux__
|
||||
#if defined FREEBSD && !defined __FreeBSD__
|
||||
#define __FreeBSD__
|
||||
#endif
|
||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||
#include <sclinux.h>
|
||||
#endif
|
||||
|
||||
#ifndef AMX_H_INCLUDED
|
||||
#define AMX_H_INCLUDED
|
||||
|
||||
#if defined __LCC__ || defined __DMC__ || defined __linux__
|
||||
#if defined HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
||||
* here, these types are probably undefined.
|
||||
*/
|
||||
#if defined __FreeBSD__
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
typedef short int int16_t;
|
||||
typedef unsigned short int uint16_t;
|
||||
#if defined SN_TARGET_PS2
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
#if defined __LCC__ || defined __DMC__ || defined LINUX
|
||||
#if defined HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
typedef long int int32_t;
|
||||
typedef unsigned long int uint32_t;
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
// evilspy's fix for mingw
|
||||
#if defined __GNUC__
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#define HAVE_I64
|
||||
#elif defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#define HAVE_I64
|
||||
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
||||
* here, these types are probably undefined.
|
||||
*/
|
||||
#if defined __MACH__
|
||||
#include <ppc/types.h>
|
||||
typedef unsigned short int uint16_t;
|
||||
typedef unsigned long int uint32_t;
|
||||
#elif defined __FreeBSD__
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
typedef short int int16_t;
|
||||
typedef unsigned short int uint16_t;
|
||||
#if defined SN_TARGET_PS2
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
typedef long int int32_t;
|
||||
typedef unsigned long int uint32_t;
|
||||
#endif
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#define HAVE_I64
|
||||
#elif defined __GNUC__
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#define HAVE_I64
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#define HAVE_STDINT_H
|
||||
#endif
|
||||
#if defined _LP64 || defined WIN64 || defined _WIN64
|
||||
#if !defined __64BIT__
|
||||
#define __64BIT__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
|
||||
#if !defined alloca
|
||||
#define alloca(n) _alloca(n)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined arraysize
|
||||
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if PAWN_CELL_SIZE==32
|
||||
#define REAL float
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
#define REAL double
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
#endif
|
||||
|
||||
#if defined PAWN_DLL
|
||||
#if !defined AMX_NATIVE_CALL
|
||||
#define AMX_NATIVE_CALL __stdcall
|
||||
#endif
|
||||
#if !defined AMXAPI
|
||||
#define AMXAPI __stdcall
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* calling convention for native functions */
|
||||
#if !defined AMX_NATIVE_CALL
|
||||
#define AMX_NATIVE_CALL
|
||||
@ -79,6 +123,8 @@ extern "C" {
|
||||
#define AMXAPI __stdcall
|
||||
#elif defined CDECL
|
||||
#define AMXAPI __cdecl
|
||||
#elif defined GCC_HASCLASSVISIBILITY
|
||||
#define AMXAPI __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define AMXAPI
|
||||
#endif
|
||||
@ -96,46 +142,36 @@ extern "C" {
|
||||
* 5 (tagnames table) 4
|
||||
* 6 (reformatted header) 6
|
||||
* 7 (name table, opcodes SYMTAG & SYSREQ.D) 7
|
||||
* 8 (opcode STMT, renewed debug interface) 8
|
||||
*/
|
||||
#define CUR_FILE_VERSION 7 /* current file version; also the current AMX version */
|
||||
#define CUR_FILE_VERSION 8 /* current file version; also the current AMX version */
|
||||
#define MIN_FILE_VERSION 6 /* lowest supported file format version for the current AMX version */
|
||||
#define MIN_AMX_VERSION 7 /* minimum AMX version needed to support the current file format */
|
||||
#define MIN_AMX_VERSION 8 /* minimum AMX version needed to support the current file format */
|
||||
|
||||
#if defined BIT16
|
||||
#define SMALL_CELL_SIZE 16 /* for backward compatibility */
|
||||
#if !defined PAWN_CELL_SIZE
|
||||
#define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
|
||||
#endif
|
||||
#if !defined SMALL_CELL_SIZE
|
||||
#define SMALL_CELL_SIZE 32 /* by default, use 32-bit cells */
|
||||
#endif
|
||||
#if SMALL_CELL_SIZE==16
|
||||
#if PAWN_CELL_SIZE==16
|
||||
typedef uint16_t ucell;
|
||||
typedef int16_t cell;
|
||||
#elif SMALL_CELL_SIZE==32
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
typedef uint32_t ucell;
|
||||
typedef int32_t cell;
|
||||
#elif SMALL_CELL_SIZE==64
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
typedef uint64_t ucell;
|
||||
typedef int64_t cell;
|
||||
#else
|
||||
#error Unsupported cell size (SMALL_CELL_SIZE)
|
||||
#error Unsupported cell size (PAWN_CELL_SIZE)
|
||||
#endif
|
||||
|
||||
#if SMALL_CELL_SIZE==32
|
||||
#define REAL float
|
||||
#elif SMALL_CELL_SIZE==64
|
||||
#define REAL double
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
#endif
|
||||
|
||||
#define UNPACKEDMAX ((1 << (sizeof(cell)-1)*8) - 1)
|
||||
#define UNPACKEDMAX ((1L << (sizeof(cell)-1)*8) - 1)
|
||||
#define UNLIMITED (~1u >> 1)
|
||||
|
||||
struct tagAMX;
|
||||
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
|
||||
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
|
||||
cell *result, cell *params);
|
||||
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
||||
typedef int (AMXAPI *AMX_DEBUGCALL)(struct tagAMX *amx, int mode);
|
||||
#if !defined _FAR
|
||||
#define _FAR
|
||||
#endif
|
||||
@ -149,7 +185,7 @@ typedef int (AMXAPI *AMX_DEBUGCALL)(struct tagAMX *amx, int mode);
|
||||
/* Some compilers do not support the #pragma align, which should be fine. Some
|
||||
* compilers give a warning on unknown #pragmas, which is not so fine...
|
||||
*/
|
||||
#if defined SN_TARGET_PS2 || defined __GNUC__
|
||||
#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN
|
||||
#define AMX_NO_ALIGN
|
||||
#endif
|
||||
|
||||
@ -160,8 +196,10 @@ typedef int (AMXAPI *AMX_DEBUGCALL)(struct tagAMX *amx, int mode);
|
||||
#endif
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined __linux__
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=mac68k
|
||||
#else
|
||||
#pragma pack(push)
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
@ -171,25 +209,30 @@ typedef int (AMXAPI *AMX_DEBUGCALL)(struct tagAMX *amx, int mode);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
typedef struct tagAMX_NATIVE_INFO {
|
||||
const char _FAR *name PACKED;
|
||||
AMX_NATIVE func PACKED;
|
||||
} AMX_NATIVE_INFO;
|
||||
} PACKED AMX_NATIVE_INFO;
|
||||
|
||||
#define AMX_USERNUM 4
|
||||
#define sEXPMAX 19 /* maximum name length for file version <= 6 */
|
||||
#define sNAMEMAX 31 /* maximum name length of symbol name */
|
||||
|
||||
typedef struct tagAMX_FUNCSTUB {
|
||||
ucell address PACKED;
|
||||
const char name[sEXPMAX+1] PACKED;
|
||||
} AMX_FUNCSTUB;
|
||||
ucell address PACKED;
|
||||
char name[sEXPMAX+1] PACKED;
|
||||
} PACKED AMX_FUNCSTUB;
|
||||
|
||||
typedef struct tagFUNCSTUBNT {
|
||||
ucell address PACKED;
|
||||
ucell nameofs PACKED; //we need this for amxx to be backwards comaptible
|
||||
} PACKED AMX_FUNCSTUBNT;
|
||||
|
||||
/* The AMX structure is the internal structure for many functions. Not all
|
||||
* fields are valid at all times; many fields are cached in local variables.
|
||||
*/
|
||||
typedef struct tagAMX {
|
||||
unsigned char _FAR *base PACKED; /* points to the AMX header ("amxhdr") plus the code, optionally also the data */
|
||||
unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
|
||||
unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
|
||||
AMX_CALLBACK callback PACKED;
|
||||
AMX_DEBUG debug PACKED; /* debug callback */
|
||||
@ -201,28 +244,23 @@ typedef struct tagAMX {
|
||||
cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
|
||||
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
|
||||
int flags PACKED; /* current status, see amx_Flags() */
|
||||
/* for assertions and debug hook */
|
||||
cell curline PACKED;
|
||||
cell curfile PACKED;
|
||||
int dbgcode PACKED;
|
||||
cell dbgaddr PACKED;
|
||||
cell dbgparam PACKED;
|
||||
char _FAR *dbgname PACKED;
|
||||
/* user data */
|
||||
long usertags[AMX_USERNUM] PACKED;
|
||||
void _FAR *userdata[AMX_USERNUM] PACKED;
|
||||
/* native functions can raise an error */
|
||||
int error PACKED;
|
||||
/* passing parameters requires a "count" field */
|
||||
int paramcount;
|
||||
/* the sleep opcode needs to store the full AMX status */
|
||||
cell pri PACKED;
|
||||
cell alt PACKED;
|
||||
cell reset_stk PACKED;
|
||||
cell reset_hea PACKED;
|
||||
cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */
|
||||
/* support variables for the JIT */
|
||||
/* support variables for the JIT */
|
||||
int reloc_size PACKED; /* required temporary buffer for relocations */
|
||||
long code_size PACKED; /* estimated memory footprint of the native code */
|
||||
} AMX;
|
||||
} PACKED AMX;
|
||||
|
||||
/* The AMX_HEADER structure is both the memory format as the file format. The
|
||||
* structure is used internaly.
|
||||
@ -244,26 +282,11 @@ typedef struct tagAMX_HEADER {
|
||||
int32_t libraries PACKED; /* offset to the table of libraries */
|
||||
int32_t pubvars PACKED; /* the "public variables" table */
|
||||
int32_t tags PACKED; /* the "public tagnames" table */
|
||||
int32_t nametable PACKED; /* name table, file version 7 only */
|
||||
} AMX_HEADER PACKED;
|
||||
#define AMX_MAGIC 0xf1e0
|
||||
int32_t nametable PACKED; /* name table */
|
||||
} PACKED AMX_HEADER;
|
||||
|
||||
//double linked list for stack
|
||||
typedef struct tagAMX_TRACE
|
||||
{
|
||||
cell line PACKED;
|
||||
cell file PACKED;
|
||||
struct tagAMX_TRACE *next PACKED;
|
||||
struct tagAMX_TRACE *prev PACKED;
|
||||
} AMX_TRACE PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG
|
||||
{
|
||||
int32_t numFiles PACKED; /* number of chars in array */
|
||||
char **files PACKED; /* array of files */
|
||||
AMX_TRACE *head PACKED; /* begin of link list */
|
||||
AMX_TRACE *tail PACKED; /* end of link list */
|
||||
} AMX_DBG PACKED;
|
||||
//This is always the same for us
|
||||
#define AMX_MAGIC 0xf1e0
|
||||
|
||||
enum {
|
||||
AMX_ERR_NONE,
|
||||
@ -280,6 +303,7 @@ enum {
|
||||
AMX_ERR_NATIVE, /* native function failed */
|
||||
AMX_ERR_DIVIDE, /* divide by zero */
|
||||
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
|
||||
AMX_ERR_INVSTATE, /* invalid state for this access */
|
||||
|
||||
AMX_ERR_MEMORY = 16, /* out of memory */
|
||||
AMX_ERR_FORMAT, /* invalid file format */
|
||||
@ -292,29 +316,17 @@ enum {
|
||||
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
|
||||
AMX_ERR_PARAMS, /* parameter error */
|
||||
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
|
||||
};
|
||||
|
||||
enum {
|
||||
DBG_INIT, /* query/initialize */
|
||||
DBG_FILE, /* file number in curfile, filename in name */
|
||||
DBG_LINE, /* line number in curline, file number in curfile */
|
||||
DBG_SYMBOL, /* address in dbgaddr, class/type in dbgparam */
|
||||
DBG_CLRSYM, /* stack address below which locals should be removed. stack address in stk */
|
||||
DBG_CALL, /* function call, address jumped to in dbgaddr */
|
||||
DBG_RETURN, /* function returns */
|
||||
DBG_TERMINATE, /* program ends, code address in dbgaddr, reason in dbgparam */
|
||||
DBG_SRANGE, /* symbol size and dimensions (arrays); level in dbgaddr (!); length in dbgparam */
|
||||
DBG_SYMTAG, /* tag of the most recent symbol (if non-zero), tag in dbgparam */
|
||||
AMX_ERR_GENERAL, /* general error (unknown or unspecific error) */
|
||||
};
|
||||
|
||||
/* AMX_FLAG_CHAR16 0x01 no longer used */
|
||||
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
|
||||
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */
|
||||
#define AMX_FLAG_BIGENDIAN 0x08 /* big endian encoding */
|
||||
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking */
|
||||
#define AMX_FLAG_LINEOPS 0x20 /* line ops are parsed by the JIT [loadtime only flag] */
|
||||
#define AMX_FLAG_TRACED 0x40 /* the file has already been traced */
|
||||
#define AMX_FLAG_BROWSE 0x4000 /* browsing/relocating or executing */
|
||||
#define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */
|
||||
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */
|
||||
#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
|
||||
#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
|
||||
#define AMX_FLAG_BROWSE 0x4000 /* busy browsing */
|
||||
#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
|
||||
|
||||
#define AMX_EXEC_MAIN -1 /* start at program entry point */
|
||||
@ -322,16 +334,18 @@ enum {
|
||||
|
||||
#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24))
|
||||
|
||||
#define AMX_EXPANDMARGIN 64
|
||||
#if !defined AMX_COMPACTMARGIN
|
||||
#define AMX_COMPACTMARGIN 64
|
||||
#endif
|
||||
|
||||
/* for native functions that use floating point parameters, the following
|
||||
* two macros are convenient for casting a "cell" into a "float" type _without_
|
||||
* changing the bit pattern
|
||||
*/
|
||||
#if SMALL_CELL_SIZE==32
|
||||
#if PAWN_CELL_SIZE==32
|
||||
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||
#define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
|
||||
#elif SMALL_CELL_SIZE==64
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||
#define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
|
||||
#else
|
||||
@ -345,7 +359,7 @@ enum {
|
||||
amx_StrLen(amx_cstr_, &amx_length_); \
|
||||
if (amx_length_ > 0 && \
|
||||
((result) = (void*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \
|
||||
amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1); \
|
||||
amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1, amx_length_); \
|
||||
else (result) = NULL; \
|
||||
} while (0)
|
||||
|
||||
@ -354,23 +368,11 @@ uint32_t * AMXAPI amx_Align32(uint32_t *v);
|
||||
#if defined _I64_MAX || defined HAVE_I64
|
||||
uint64_t * AMXAPI amx_Align64(uint64_t *v);
|
||||
#endif
|
||||
|
||||
#if SMALL_CELL_SIZE==32
|
||||
#define amx_AlignCell amx_Align32
|
||||
#elif SMALL_CELL_SIZE==64
|
||||
#define amx_AlignCell amx_Align64
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
#endif
|
||||
|
||||
int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr);
|
||||
int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params);
|
||||
int AMXAPI amx_Cleanup(AMX *amx);
|
||||
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
|
||||
int AMXAPI amx_Debug(AMX *amx); /* default debug procedure, does nothing */
|
||||
int AMXAPI amx_DebugCall(AMX *amx, int mode);
|
||||
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index, int numparams, ...);
|
||||
int AMXAPI amx_Execv(AMX *amx, cell *retval, int index, int numparams, cell params[]);
|
||||
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
|
||||
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index);
|
||||
int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index);
|
||||
int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr);
|
||||
@ -380,37 +382,56 @@ int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr);
|
||||
int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname);
|
||||
int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname);
|
||||
int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr);
|
||||
int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar);
|
||||
int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar, size_t size);
|
||||
int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
|
||||
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
|
||||
int AMXAPI amx_Init(AMX *amx, void *program);
|
||||
int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
|
||||
int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
|
||||
int AMXAPI amx_NameLength(AMX *amx, int *length);
|
||||
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name,AMX_NATIVE func);
|
||||
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func);
|
||||
int AMXAPI amx_NumNatives(AMX *amx, int *number);
|
||||
int AMXAPI amx_NumPublics(AMX *amx, int *number);
|
||||
int AMXAPI amx_NumPubVars(AMX *amx, int *number);
|
||||
int AMXAPI amx_NumTags(AMX *amx, int *number);
|
||||
int AMXAPI amx_Push(AMX *amx, cell value);
|
||||
int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells);
|
||||
int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar);
|
||||
int AMXAPI amx_RaiseError(AMX *amx, int error);
|
||||
int AMXAPI amx_Register(AMX *amx, AMX_NATIVE_INFO *nativelist, int number);
|
||||
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
|
||||
int AMXAPI amx_Release(AMX *amx, cell amx_addr);
|
||||
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
|
||||
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
|
||||
int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar);
|
||||
int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size);
|
||||
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr);
|
||||
int AMXAPI amx_StrLen(cell *cstring, int *length);
|
||||
int AMXAPI amx_StrLen(const cell *cstring, int *length);
|
||||
int AMXAPI amx_UTF8Check(const char *string, int *length);
|
||||
int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value);
|
||||
int AMXAPI amx_UTF8Len(const cell *cstr, int *length);
|
||||
int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value);
|
||||
int AMXAPI amx_UTF8Check(const char *string);
|
||||
int AMXAPI amx_GetLibraries(AMX *amx);
|
||||
const char *AMXAPI amx_GetLibrary(AMX *amx, int index, char *buffer, int len);
|
||||
int AMXAPI amx_SetStringOld(cell *dest,const char *source,int pack,int use_wchar);
|
||||
int AMXAPI amx_GetStringOld(char *dest,const cell *source,int use_wchar);
|
||||
|
||||
//no longer used! void amx_NullNativeTable(AMX *amx);
|
||||
#if PAWN_CELL_SIZE==16
|
||||
#define amx_AlignCell(v) amx_Align16(v)
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
#define amx_AlignCell(v) amx_Align32(v)
|
||||
#elif PAWN_CELL_SIZE==64 && (defined _I64_MAX || defined HAVE_I64)
|
||||
#define amx_AlignCell(v) amx_Align64(v)
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
#endif
|
||||
|
||||
#define amx_RegisterFunc(amx, name, func) \
|
||||
amx_Register((amx), amx_NativeInfo((name),(func)), 1);
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined __linux__
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack() /* reset default packing */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=reset
|
||||
#else
|
||||
#pragma pack(pop) /* reset previous packing */
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Core module for the Small AMX
|
||||
/* Core module for the Pawn AMX
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 1997-2004
|
||||
* Copyright (c) ITB CompuPhase, 1997-2005
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
@ -34,14 +34,7 @@
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
|
||||
// this file does not include amxmodx.h, so we have to include the memory manager here
|
||||
#ifdef MEMORY_TEST
|
||||
#include "mmgr/mmgr.h"
|
||||
#endif // MEMORY_TEST
|
||||
|
||||
#include "amx.h"
|
||||
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined _Windows
|
||||
#include <windows.h>
|
||||
#endif
|
||||
@ -60,14 +53,13 @@
|
||||
# define _tcscpy strcpy
|
||||
# define _tcsdup strdup
|
||||
# define _tcslen strlen
|
||||
# define _stprintf sprintf
|
||||
#endif
|
||||
|
||||
|
||||
#define CHARBITS (8*sizeof(char))
|
||||
typedef unsigned char uchar;
|
||||
|
||||
#if !defined NOPROPLIST
|
||||
#if !defined AMX_NOPROPLIST
|
||||
typedef struct _property_list {
|
||||
struct _property_list *next;
|
||||
cell id;
|
||||
@ -76,7 +68,7 @@ typedef struct _property_list {
|
||||
//??? safe AMX (owner of the property)
|
||||
} proplist;
|
||||
|
||||
static proplist proproot = { NULL };
|
||||
static proplist proproot = { NULL, 0, NULL, 0 };
|
||||
|
||||
static proplist *list_additem(proplist *root)
|
||||
{
|
||||
@ -142,15 +134,13 @@ static proplist *list_finditem(proplist *root,cell id,char *name,cell value,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL numargs(AMX *amx, cell *params)
|
||||
{
|
||||
AMX_HEADER *hdr;
|
||||
uchar *data;
|
||||
cell bytes;
|
||||
|
||||
(void)params;
|
||||
hdr=(AMX_HEADER *)amx->base;
|
||||
data=amx->data ? amx->data : amx->base+(int)hdr->dat;
|
||||
/* the number of bytes is on the stack, at "frm + 2*cell" */
|
||||
@ -190,18 +180,16 @@ static cell AMX_NATIVE_CALL setarg(AMX *amx, cell *params)
|
||||
/* adjust the address in "value" in case of an array access */
|
||||
value+=params[2]*sizeof(cell);
|
||||
/* verify the address */
|
||||
if (value<0 || (value>=amx->hea && value<amx->stk))
|
||||
if (value<0 || value>=amx->hea && value<amx->stk)
|
||||
return 0;
|
||||
/* set the value indirectly */
|
||||
* (cell *)(data+(int)value) = params[3];
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL heapspace(AMX *amx,cell *params)
|
||||
{
|
||||
(void)params;
|
||||
return amx->stk - amx->hea;
|
||||
}
|
||||
|
||||
@ -220,142 +208,22 @@ static cell AMX_NATIVE_CALL funcidx(AMX *amx,cell *params)
|
||||
return 0;
|
||||
} /* if */
|
||||
|
||||
amx_GetString(name,cstr,0);
|
||||
amx_GetString(name,cstr,0,UNLIMITED);
|
||||
err=amx_FindPublic(amx,name,&index);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
index=-1; /* this is not considered a fatal error */
|
||||
return index;
|
||||
}
|
||||
|
||||
int amx_StrPack(cell *dest,cell *source)
|
||||
{
|
||||
int len;
|
||||
|
||||
amx_StrLen(source,&len);
|
||||
if ((ucell)*source>UNPACKEDMAX) {
|
||||
/* source string is already packed */
|
||||
while (len >= 0) {
|
||||
*dest++ = *source++;
|
||||
len-=sizeof(cell);
|
||||
} /* while */
|
||||
} else {
|
||||
/* pack string, from bottom up */
|
||||
cell c;
|
||||
int i;
|
||||
for (c=0,i=0; i<len; i++) {
|
||||
assert((*source & ~0xffL)==0);
|
||||
c=(c<<CHARBITS) | *source++;
|
||||
if (i%sizeof(cell) == sizeof(cell)-1) {
|
||||
*dest++=c;
|
||||
c=0;
|
||||
} /* if */
|
||||
} /* for */
|
||||
if (i%sizeof(cell) != 0) /* store remaining packed characters */
|
||||
*dest=c << (sizeof(cell)-i%sizeof(cell))*CHARBITS;
|
||||
else
|
||||
*dest=0; /* store full cell of zeros */
|
||||
} /* if */
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int amx_StrUnpack(cell *dest,cell *source)
|
||||
{
|
||||
if ((ucell)*source>UNPACKEDMAX) {
|
||||
/* unpack string, from top down (so string can be unpacked in place) */
|
||||
cell c;
|
||||
int i,len;
|
||||
amx_StrLen(source,&len);
|
||||
dest[len]=0;
|
||||
for (i=len-1; i>=0; i--) {
|
||||
c=source[i/sizeof(cell)] >> (sizeof(cell)-i%sizeof(cell)-1)*CHARBITS;
|
||||
dest[i]=c & UCHAR_MAX;
|
||||
} /* for */
|
||||
} else {
|
||||
/* source string is already unpacked */
|
||||
while ((*dest++ = *source++) != 0)
|
||||
/* nothing */;
|
||||
} /* if */
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
static int verify_addr(AMX *amx,cell addr)
|
||||
{
|
||||
int err;
|
||||
cell *cdest;
|
||||
|
||||
err=amx_GetAddr(amx,addr,&cdest);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
amx_RaiseError(amx,err);
|
||||
return err;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL core_strlen(AMX *amx,cell *params)
|
||||
{
|
||||
cell *cptr;
|
||||
int len = 0;
|
||||
|
||||
if (amx_GetAddr(amx,params[1],&cptr)==AMX_ERR_NONE)
|
||||
amx_StrLen(cptr,&len);
|
||||
return len;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL strpack(AMX *amx,cell *params)
|
||||
{
|
||||
cell *cdest,*csrc;
|
||||
int len,needed,err;
|
||||
size_t lastaddr;
|
||||
|
||||
/* calculate number of cells needed for (packed) destination */
|
||||
amx_GetAddr(amx,params[2],&csrc);
|
||||
amx_StrLen(csrc,&len);
|
||||
needed=(len+sizeof(cell))/sizeof(cell); /* # of cells needed */
|
||||
assert(needed>0);
|
||||
lastaddr=(size_t)(params[1]+sizeof(cell)*needed-1);
|
||||
if (verify_addr(amx,(cell)lastaddr)!=AMX_ERR_NONE)
|
||||
return 0;
|
||||
|
||||
amx_GetAddr(amx,params[1],&cdest);
|
||||
err=amx_StrPack(cdest,csrc);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
return amx_RaiseError(amx,err);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL strunpack(AMX *amx,cell *params)
|
||||
{
|
||||
cell *cdest,*csrc;
|
||||
int len,err;
|
||||
size_t lastaddr;
|
||||
|
||||
/* calculate number of cells needed for (packed) destination */
|
||||
amx_GetAddr(amx,params[2],&csrc);
|
||||
amx_StrLen(csrc,&len);
|
||||
assert(len>=0);
|
||||
lastaddr=(size_t)(params[1]+sizeof(cell)*(len+1)-1);
|
||||
if (verify_addr(amx,(cell)lastaddr)!=AMX_ERR_NONE)
|
||||
return 0;
|
||||
|
||||
amx_GetAddr(amx,params[1],&cdest);
|
||||
err=amx_StrUnpack(cdest,csrc);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
return amx_RaiseError(amx,err);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
|
||||
{
|
||||
union {
|
||||
cell c;
|
||||
#if SMALL_CELL_SIZE==16
|
||||
#if PAWN_CELL_SIZE==16
|
||||
uchar b[2];
|
||||
#elif SMALL_CELL_SIZE==32
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
uchar b[4];
|
||||
#elif SMALL_CELL_SIZE==64
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
uchar b[8];
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
@ -363,20 +231,21 @@ static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
|
||||
} value;
|
||||
uchar t;
|
||||
|
||||
(void)amx;
|
||||
assert((size_t)params[0]==sizeof(cell));
|
||||
value.c = params[1];
|
||||
#if SMALL_CELL_SIZE==16
|
||||
#if PAWN_CELL_SIZE==16
|
||||
t = value.b[0];
|
||||
value.b[0] = value.b[1];
|
||||
value.b[1] = t;
|
||||
#elif SMALL_CELL_SIZE==32
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
t = value.b[0];
|
||||
value.b[0] = value.b[3];
|
||||
value.b[3] = t;
|
||||
t = value.b[1];
|
||||
value.b[1] = value.b[2];
|
||||
value.b[2] = t;
|
||||
#elif SMALL_CELL_SIZE==64
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
t = value.b[0];
|
||||
value.b[0] = value.b[7];
|
||||
value.b[7] = t;
|
||||
@ -395,11 +264,9 @@ static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
|
||||
return value.c;
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params)
|
||||
{
|
||||
(void)amx;
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||
return (cell)CharLower((LPTSTR)params[1]);
|
||||
#elif defined _Windows
|
||||
@ -409,11 +276,9 @@ static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params)
|
||||
{
|
||||
(void)amx;
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||
return (cell)CharUpper((LPTSTR)params[1]);
|
||||
#elif defined _Windows
|
||||
@ -423,19 +288,15 @@ static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL core_min(AMX *amx,cell *params)
|
||||
{
|
||||
(void)amx;
|
||||
return params[1] <= params[2] ? params[1] : params[2];
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL core_max(AMX *amx,cell *params)
|
||||
{
|
||||
(void)amx;
|
||||
return params[1] >= params[2] ? params[1] : params[2];
|
||||
}
|
||||
|
||||
@ -451,7 +312,7 @@ static cell AMX_NATIVE_CALL core_clamp(AMX *amx,cell *params)
|
||||
return value;
|
||||
}
|
||||
|
||||
#if !defined NOPROPLIST
|
||||
#if !defined AMX_NOPROPLIST
|
||||
static char *MakePackedString(cell *cptr)
|
||||
{
|
||||
int len;
|
||||
@ -459,10 +320,21 @@ static char *MakePackedString(cell *cptr)
|
||||
|
||||
amx_StrLen(cptr,&len);
|
||||
dest=(char *)malloc(len+sizeof(cell));
|
||||
amx_GetString(dest,cptr,0);
|
||||
amx_GetString(dest,cptr,0,UNLIMITED);
|
||||
return dest;
|
||||
}
|
||||
|
||||
static int verify_addr(AMX *amx,cell addr)
|
||||
{
|
||||
int err;
|
||||
cell *cdest;
|
||||
|
||||
err=amx_GetAddr(amx,addr,&cdest);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
amx_RaiseError(amx,err);
|
||||
return err;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params)
|
||||
{
|
||||
cell *cstr;
|
||||
@ -480,7 +352,7 @@ static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params)
|
||||
return 0;
|
||||
} /* if */
|
||||
amx_GetAddr(amx,params[4],&cstr);
|
||||
amx_SetString(cstr,item->name,1,0);
|
||||
amx_SetString(cstr,item->name,1,0,UNLIMITED);
|
||||
} /* if */
|
||||
free(name);
|
||||
return (item!=NULL) ? item->value : 0;
|
||||
@ -545,12 +417,14 @@ static cell AMX_NATIVE_CALL existproperty(AMX *amx,cell *params)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined AMX_NORANDOM
|
||||
/* This routine comes from the book "Inner Loops" by Rick Booth, Addison-Wesley
|
||||
* (ISBN 0-201-47960-5). This is a "multiplicative congruential random number
|
||||
* generator" that has been extended to 31-bits (the standard C version returns
|
||||
* only 15-bits).
|
||||
*/
|
||||
static unsigned long IL_StandardRandom_seed = 0L;
|
||||
#define INITIAL_SEED 0xcaa938dbL
|
||||
static unsigned long IL_StandardRandom_seed = INITIAL_SEED; /* always use a non-zero seed */
|
||||
#define IL_RMULT 1103515245L
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
@ -562,7 +436,7 @@ static cell AMX_NATIVE_CALL core_random(AMX *amx,cell *params)
|
||||
|
||||
/* one-time initialization (or, mostly one-time) */
|
||||
#if !defined SN_TARGET_PS2 && !defined _WIN32_WCE
|
||||
if (IL_StandardRandom_seed == 0L)
|
||||
if (IL_StandardRandom_seed == INITIAL_SEED)
|
||||
IL_StandardRandom_seed=(unsigned long)time(NULL);
|
||||
#endif
|
||||
|
||||
@ -579,6 +453,7 @@ static cell AMX_NATIVE_CALL core_random(AMX *amx,cell *params)
|
||||
result %= params[1];
|
||||
return (cell)result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
AMX_NATIVE_INFO core_Natives[] = {
|
||||
@ -587,22 +462,13 @@ AMX_NATIVE_INFO core_Natives[] = {
|
||||
{ "setarg", setarg },
|
||||
{ "heapspace", heapspace },
|
||||
{ "funcidx", funcidx },
|
||||
{ "strlen", core_strlen },
|
||||
{ "strpack", strpack },
|
||||
{ "strunpack", strunpack },
|
||||
{ "swapchars", swapchars },
|
||||
{ "tolower", core_tolower },
|
||||
{ "toupper", core_toupper },
|
||||
{ "random", core_random },
|
||||
{ "min", core_min },
|
||||
{ "max", core_max },
|
||||
{ "clamp", core_clamp },
|
||||
#if !defined NOPROPLIST
|
||||
{ "getproperty", getproperty },
|
||||
{ "setproperty", setproperty },
|
||||
{ "deleteproperty",delproperty },
|
||||
{ "existproperty", existproperty },
|
||||
#endif
|
||||
{ "random", core_random },
|
||||
{ NULL, NULL } /* terminator */
|
||||
};
|
||||
|
||||
@ -611,12 +477,10 @@ int AMXEXPORT amx_CoreInit(AMX *amx)
|
||||
return amx_Register(amx, core_Natives, -1);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
int AMXEXPORT amx_CoreCleanup(AMX *amx)
|
||||
{
|
||||
#if !defined NOPROPLIST
|
||||
(void)amx;
|
||||
#if !defined AMX_NOPROPLIST
|
||||
//??? delete only the properties owned by the AMX
|
||||
while (proproot.next!=NULL)
|
||||
list_delete(&proproot,proproot.next);
|
||||
|
86
amxmodx/amxdefn.asm
Executable file
86
amxmodx/amxdefn.asm
Executable file
@ -0,0 +1,86 @@
|
||||
; Definition of the AMX structure for assembler syntax (NASM)
|
||||
|
||||
struc amx_s
|
||||
_base: resd 1
|
||||
_dataseg: resd 1
|
||||
_callback: resd 1
|
||||
_debug: resd 1
|
||||
_cip: resd 1
|
||||
_frm: resd 1
|
||||
_hea: resd 1
|
||||
_hlw: resd 1
|
||||
_stk: resd 1
|
||||
_stp: resd 1
|
||||
_flags: resd 1
|
||||
_usertags: resd 4 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata: resd 4 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_error: resd 1
|
||||
_paramcount: resd 1
|
||||
_pri: resd 1
|
||||
_alt: resd 1
|
||||
_reset_stk: resd 1
|
||||
_reset_hea: resd 1
|
||||
_syscall_d: resd 1
|
||||
%ifdef JIT
|
||||
; the two fields below are for the JIT; they do not exist in
|
||||
; the non-JIT version of the abstract machine
|
||||
_reloc_size: resd 1 ; memory block for relocations
|
||||
_code_size: resd 1 ; memory size of the native code
|
||||
%endif
|
||||
endstruc
|
||||
|
||||
struc amxhead_s
|
||||
_size: resd 1 ; size of the "file"
|
||||
_magic: resw 1 ; signature
|
||||
_file_version: resb 1; file format version
|
||||
_amx_version: resb 1 ; required version of the AMX
|
||||
_h_flags: resw 1
|
||||
_defsize: resw 1 ; size of one public/native function entry
|
||||
_cod: resd 1 ; initial value of COD - code block
|
||||
_dat: resd 1 ; initial value of DAT - data block
|
||||
_h_hea: resd 1 ; initial value of HEA - start of the heap
|
||||
_h_stp: resd 1 ; initial value of STP - stack top
|
||||
_h_cip: resd 1 ; initial value of CIP - the instruction pointer
|
||||
_publics: resd 1 ; offset to the "public functions" table
|
||||
_natives: resd 1 ; offset to the "native functions" table
|
||||
_libraries: resd 1 ; offset to the "library" table
|
||||
_pubvars: resd 1 ; offset to the "public variables" table
|
||||
_tags: resd 1 ; offset to the "public tagnames" table
|
||||
_nametable: resd 1 ; offset to the name table, file version 7 only
|
||||
endstruc
|
||||
|
||||
|
||||
AMX_ERR_NONE EQU 0
|
||||
AMX_ERR_EXIT EQU 1
|
||||
AMX_ERR_ASSERT EQU 2
|
||||
AMX_ERR_STACKERR EQU 3
|
||||
AMX_ERR_BOUNDS EQU 4
|
||||
AMX_ERR_MEMACCESS EQU 5
|
||||
AMX_ERR_INVINSTR EQU 6
|
||||
AMX_ERR_STACKLOW EQU 7
|
||||
AMX_ERR_HEAPLOW EQU 8
|
||||
AMX_ERR_CALLBACK EQU 9
|
||||
AMX_ERR_NATIVE EQU 10
|
||||
AMX_ERR_DIVIDE EQU 11 ; for catching divide errors
|
||||
AMX_ERR_SLEEP EQU 12
|
||||
|
||||
AMX_ERR_MEMORY EQU 16
|
||||
AMX_ERR_FORMAT EQU 17
|
||||
AMX_ERR_VERSION EQU 18
|
||||
AMX_ERR_NOTFOUND EQU 19
|
||||
AMX_ERR_INDEX EQU 20
|
||||
AMX_ERR_DEBUG EQU 21
|
||||
AMX_ERR_INIT EQU 22
|
||||
AMX_ERR_USERDATA EQU 23
|
||||
AMX_ERR_INIT_JIT EQU 24
|
||||
AMX_ERR_PARAMS EQU 25
|
||||
AMX_ERR_DOMAIN EQU 26
|
||||
AMX_ERR_GENERAL EQU 27
|
||||
|
||||
AMX_FLAG_DEBUG EQU 0002h ; symbolic info. available
|
||||
AMX_FLAG_COMPACT EQU 0004h
|
||||
AMX_FLAG_BYTEOPC EQU 0008h
|
||||
AMX_FLAG_NOCHECKS EQU 0010h
|
||||
AMX_FLAG_BROWSE EQU 4000h
|
||||
AMX_FLAG_RELOC EQU 8000h ; jump/call addresses relocated
|
||||
|
@ -1,4 +1,4 @@
|
||||
; AMXEXECN.ASM Abstract Machine for the "Small" language
|
||||
; AMXEXECN.ASM Abstract Machine for the "Pawn" language
|
||||
;
|
||||
|
||||
;Some notes:
|
||||
@ -25,7 +25,7 @@
|
||||
;
|
||||
;Copyright and license of use, please read
|
||||
;-----------------------------------------
|
||||
;The assembler implementation of the abstract machine for the Small language,
|
||||
;The assembler implementation of the abstract machine for the Pawn language,
|
||||
;specifically the file AMXEXEC.ASM, is copyright (c) 1998-2000 by Marc Peter.
|
||||
;
|
||||
;Permission is hereby granted, without written agreement and without paid
|
||||
@ -56,6 +56,8 @@
|
||||
;
|
||||
;History (list of changes)
|
||||
;-------------------------
|
||||
; 17 february 2005 by Thiadmer Riemersms
|
||||
; Addition of the BREAK opcode, removal of the older debugging opcode table.
|
||||
; 6 march 2004 by Thiadmer Riemersma
|
||||
; Corrected a bug in OP_FILL, where a cell preceding the array would
|
||||
; be overwritten (zero'ed out). This bug was brought to my attention
|
||||
@ -95,92 +97,7 @@
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
|
||||
; I could not get NASM's structure definition to work (it appears to confuse
|
||||
; ENDSTRUC with "end segment"). So the definition below uses constants for
|
||||
; the field offsets.
|
||||
;amx_s STRUC
|
||||
_base EQU 00h ;DD ?
|
||||
_dataseg EQU 04h ;DD ?
|
||||
_callback EQU 08h ;DD ?
|
||||
_debug EQU 0ch ;DD ?
|
||||
_cip EQU 10h ;DD ?
|
||||
_frm EQU 14h ;DD ?
|
||||
_hea EQU 18h ;DD ?
|
||||
_hlw EQU 1ch ;DD ?
|
||||
_stk EQU 20h ;DD ?
|
||||
_stp EQU 24h ;DD ?
|
||||
_flags EQU 28h ;DD ?
|
||||
_curline EQU 2ch ;DD ?
|
||||
_curfile EQU 30h ;DD ?
|
||||
_dbgcode EQU 34h ;DD ?
|
||||
_dbgaddr EQU 38h ;DD ?
|
||||
_dbgparam EQU 3ch ;DD ?
|
||||
_dbgname EQU 40h ;DD ?
|
||||
_usertags1 EQU 44h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_usertags2 EQU 44h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_usertags3 EQU 44h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_usertags4 EQU 44h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata1 EQU 54h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata2 EQU 54h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata3 EQU 54h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata4 EQU 54h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_error EQU 64h ;DD ?
|
||||
_pri EQU 68h ;DD ?
|
||||
_alt EQU 6ch ;DD ?
|
||||
_reset_stk EQU 70h ;DD ?
|
||||
_reset_hea EQU 74h ;DD ?
|
||||
_syscall_d EQU 78h ;DD ?
|
||||
; the two fields below are for the JIT; they do not exist in
|
||||
; the non-JIT version of the abstract machine
|
||||
; _reloc_size EQU 7ch ;DD ? ; memory block for relocations
|
||||
; _code_size EQU 80h ;DD ? ; memory size of the native code
|
||||
;amx_s ENDS
|
||||
|
||||
|
||||
AMX_ERR_NONE EQU 0
|
||||
AMX_ERR_EXIT EQU 1
|
||||
AMX_ERR_ASSERT EQU 2
|
||||
AMX_ERR_STACKERR EQU 3
|
||||
AMX_ERR_BOUNDS EQU 4
|
||||
AMX_ERR_MEMACCESS EQU 5
|
||||
AMX_ERR_INVINSTR EQU 6
|
||||
AMX_ERR_STACKLOW EQU 7
|
||||
AMX_ERR_HEAPLOW EQU 8
|
||||
AMX_ERR_CALLBACK EQU 9
|
||||
AMX_ERR_NATIVE EQU 10
|
||||
AMX_ERR_DIVIDE EQU 11 ; MP: added for catching divide errors
|
||||
AMX_ERR_SLEEP EQU 12 ; (TR)
|
||||
|
||||
AMX_ERR_MEMORY EQU 16
|
||||
AMX_ERR_FORMAT EQU 17
|
||||
AMX_ERR_VERSION EQU 18
|
||||
AMX_ERR_NOTFOUND EQU 19
|
||||
AMX_ERR_INDEX EQU 20
|
||||
AMX_ERR_DEBUG EQU 21
|
||||
AMX_ERR_INIT EQU 22
|
||||
AMX_ERR_USERDATA EQU 23
|
||||
AMX_ERR_INIT_JIT EQU 24
|
||||
AMX_ERR_PARAMS EQU 25
|
||||
AMX_ERR_DOMAIN EQU 26
|
||||
|
||||
DBG_INIT EQU 0
|
||||
DBG_FILE EQU 1
|
||||
DBG_LINE EQU 2
|
||||
DBG_SYMBOL EQU 3
|
||||
DBG_CLRSYM EQU 4
|
||||
DBG_CALL EQU 5
|
||||
DBG_RETURN EQU 6
|
||||
DBG_TERMINATE EQU 7
|
||||
DBG_SRANGE EQU 8 ; (TR)
|
||||
DBG_SYMTAG EQU 9 ; (TR)
|
||||
|
||||
AMX_FLAG_CHAR16 EQU 0001h ; characters are 16-bit
|
||||
AMX_FLAG_DEBUG EQU 0002h ; symbolic info. available
|
||||
AMX_FLAG_LINEOPS EQU 0020h ; line op information
|
||||
AMX_FLAG_TRACED EQU 0040h ;
|
||||
AMX_FLAG_BROWSE EQU 4000h
|
||||
AMX_FLAG_RELOC EQU 8000h ; jump/call addresses relocated
|
||||
%include "amxdefn.asm"
|
||||
|
||||
;#define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
|
||||
%macro _PUSH 1
|
||||
@ -659,29 +576,6 @@ OP_POP_ALT:
|
||||
|
||||
;good
|
||||
OP_STACK:
|
||||
mov edx,ecx
|
||||
add ecx,[esi+4]
|
||||
_CHKMARGIN
|
||||
_CHKSTACK
|
||||
mov ebp,amx
|
||||
test DWORD [ebp+_flags],AMX_FLAG_DEBUG
|
||||
jz short op_stk_goon
|
||||
; update several structure fields and call the debug hook
|
||||
mov DWORD [ebp+_dbgcode],DBG_CLRSYM
|
||||
mov [ebp+_stk],ecx
|
||||
push eax
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax ; pass parameter via the stack
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop eax
|
||||
op_stk_goon:
|
||||
add esi,8
|
||||
GO_ON
|
||||
|
||||
OP_STACK_nodebug:
|
||||
mov edx,ecx
|
||||
add ecx,[esi+4]
|
||||
_CHKMARGIN
|
||||
@ -711,35 +605,6 @@ OP_PROC:
|
||||
GO_ON
|
||||
|
||||
OP_RET:
|
||||
_POP ebx
|
||||
_POP esi
|
||||
cmp esi,code ; verify ESI>=code
|
||||
jb err_memaccess
|
||||
cmp esi,codesiz ; verify ESI<codesiz ("end-of-code" pointer)
|
||||
jae err_memaccess
|
||||
mov frm,ebx
|
||||
add ebx,edi
|
||||
mov ebp,amx
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short op_ret_goon
|
||||
; update several structure fields and call the debug hook
|
||||
mov DWORD [ebp+_dbgcode],DBG_RETURN
|
||||
mov [ebp+_dbgparam],eax
|
||||
push eax
|
||||
mov [ebp+_stk],ecx ; store STK
|
||||
mov eax,hea
|
||||
mov [ebp+_hea],eax ; store HEA
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop eax
|
||||
op_ret_goon:
|
||||
GO_ON
|
||||
|
||||
OP_RET_nodebug:
|
||||
_POP ebx
|
||||
_POP esi
|
||||
cmp esi,code ; verify ESI>=code
|
||||
@ -760,107 +625,17 @@ OP_RETN:
|
||||
jae err_memaccess
|
||||
mov frm,ebx
|
||||
add ebx,edi
|
||||
mov ebp,amx
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short op_retn_goon
|
||||
; update several structure fields and call the debug hook
|
||||
mov DWORD [ebp+_dbgcode],DBG_RETURN
|
||||
mov [ebp+_dbgparam],eax
|
||||
push eax
|
||||
mov [ebp+_stk],ecx ; store STK
|
||||
mov eax,hea
|
||||
mov [ebp+_hea],eax ; store HEA
|
||||
mov eax,ebp ; parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
; also send the DBG_CLRSYM code
|
||||
mov eax,[edi+ecx]
|
||||
lea ecx,[ecx+eax+4]
|
||||
mov DWORD [ebp+_dbgcode],DBG_CLRSYM
|
||||
mov [ebp+_stk],ecx
|
||||
mov eax,ebp ; parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop eax
|
||||
; ECX already adjusted
|
||||
GO_ON
|
||||
op_retn_goon:
|
||||
mov ebp,[edi+ecx]
|
||||
lea ecx,[ecx+ebp+4]
|
||||
GO_ON
|
||||
|
||||
OP_RETN_nodebug:
|
||||
_POP ebx
|
||||
_POP esi
|
||||
cmp esi,code ; verify ESI>=code
|
||||
jb err_memaccess
|
||||
cmp esi,codesiz ; verify ESI<codesiz ("end-of-code" pointer)
|
||||
jae err_memaccess
|
||||
mov frm,ebx
|
||||
mov ebp,[edi+ecx]
|
||||
add ebx,edi
|
||||
lea ecx,[ecx+ebp+4]
|
||||
GO_ON
|
||||
|
||||
;good
|
||||
OP_CALL:
|
||||
lea ebp,[esi+8]
|
||||
mov esi,[esi+4]
|
||||
_PUSH ebp
|
||||
mov ebp,amx
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short op_call_goon
|
||||
; update several structure fields and call the debug hook
|
||||
push eax
|
||||
mov eax,[esp+24] ; this is "code", but ESP moved
|
||||
mov [ebp+_dbgaddr],esi
|
||||
sub [ebp+_dbgaddr],eax ; dbgaddr = cip - code
|
||||
mov DWORD [ebp+_dbgcode],DBG_CALL
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop eax
|
||||
op_call_goon:
|
||||
GO_ON
|
||||
|
||||
OP_CALL_nodebug:
|
||||
lea ebp,[esi+8]
|
||||
mov esi,[esi+4]
|
||||
_PUSH ebp
|
||||
GO_ON
|
||||
|
||||
OP_CALL_PRI:
|
||||
lea ebp,[esi+4]
|
||||
mov esi,eax
|
||||
add esi,code ; cip = PRI + code
|
||||
_PUSH ebp
|
||||
mov ebp,amx
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short op_calli_goon
|
||||
; update several structure fields and call the debug hook
|
||||
mov [ebp+_dbgaddr],eax ; dbgaddr = PRI (== cip - code)
|
||||
mov DWORD [ebp+_dbgcode],DBG_CALL
|
||||
push eax
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop eax
|
||||
op_calli_goon:
|
||||
GO_ON
|
||||
|
||||
OP_CALL_PRI_nodebug:
|
||||
lea ebp,[esi+4]
|
||||
mov esi,eax
|
||||
add esi,code ; cip = PRI + code
|
||||
@ -928,7 +703,7 @@ OP_JGRTR:
|
||||
|
||||
OP_JGEQ:
|
||||
cmp eax,edx
|
||||
jae short jump_taken ; unsigned comparison
|
||||
jae short jump_taken ; unsigned comparison
|
||||
add esi,8
|
||||
GO_ON
|
||||
|
||||
@ -941,19 +716,19 @@ OP_JSLESS:
|
||||
;good
|
||||
OP_JSLEQ:
|
||||
cmp eax,edx
|
||||
jle short jump_taken
|
||||
jle near jump_taken
|
||||
add esi,8
|
||||
GO_ON
|
||||
|
||||
OP_JSGRTR:
|
||||
cmp eax,edx
|
||||
jg short jump_taken
|
||||
jg near jump_taken
|
||||
add esi,8
|
||||
GO_ON
|
||||
|
||||
OP_JSGEQ:
|
||||
cmp eax,edx
|
||||
jge near jump_taken ; signed comparison
|
||||
jge near jump_taken ; signed comparison
|
||||
add esi,8
|
||||
GO_ON
|
||||
|
||||
@ -1350,12 +1125,11 @@ OP_CMPS:
|
||||
_VERIFYADDRESS eax ; PRI
|
||||
_VERIFYADDRESS edx ; ALT
|
||||
mov ebp,eax
|
||||
add ebp,[esi+4]
|
||||
dec ebp
|
||||
add ebp,[esi+4] ; size in bytes
|
||||
dec ebp ; EBP = PRI + size - 1
|
||||
_VERIFYADDRESS ebp ; PRI + size - 1
|
||||
mov ebp,edx
|
||||
add ebp,[esi+4]
|
||||
dec ebp
|
||||
sub ebp,eax ; EBP = size - 1
|
||||
add ebp,edx ; EBP = ALT + size - 1
|
||||
_VERIFYADDRESS ebp ; ALT + size - 1
|
||||
|
||||
push ecx
|
||||
@ -1422,19 +1196,6 @@ OP_HALT:
|
||||
mov eax,esi ; EAX=CIP
|
||||
sub eax,code
|
||||
mov [ebp+_cip],eax
|
||||
; optionally call the debug hook
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short halt_goon
|
||||
mov DWORD [ebp+_dbgcode],DBG_TERMINATE
|
||||
mov [ebp+_dbgaddr],eax
|
||||
mov [ebp+_dbgparam],ebx
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
halt_goon:
|
||||
mov eax,ebx ; return the parameter of the HALT opcode
|
||||
jmp _return
|
||||
|
||||
@ -1549,159 +1310,21 @@ OP_FILE:
|
||||
|
||||
OP_LINE:
|
||||
add esi,12
|
||||
mov ebp,amx
|
||||
push eax
|
||||
push edx
|
||||
mov eax,[esi-8] ; get curline
|
||||
mov edx,[esi-4] ; get curfile
|
||||
mov [ebp+_curline],eax
|
||||
mov [ebp+_curfile],edx
|
||||
pop edx
|
||||
pop eax
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short line_goon
|
||||
; update several structure fields
|
||||
mov [ebp+_pri],eax
|
||||
mov [ebp+_alt],edx ; EAX and EDX are now free to use
|
||||
mov eax,frm
|
||||
mov edx,hea
|
||||
mov [ebp+_frm],eax ; store values in AMX structure (STK, FRM & HEA)
|
||||
mov [ebp+_hea],edx
|
||||
mov [ebp+_stk],ecx
|
||||
mov eax,esi
|
||||
sub eax,code ; EAX = CIP (relative to start of code segment)
|
||||
mov [ebp+_cip],eax
|
||||
; call the debugger hook
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
cmp eax,AMX_ERR_NONE
|
||||
je short line_noabort ; continue running
|
||||
mov [ebp+_dbgcode],eax ; save EAX (error code) before restoring all regs
|
||||
_RESTOREREGS ; abort run, but restore stack first
|
||||
mov eax,[ebp+_dbgcode] ; get error code in EAX back again
|
||||
jmp _return ; return error code
|
||||
line_noabort:
|
||||
_RESTOREREGS
|
||||
mov eax,[ebp+_pri] ; restore PRI and ALT
|
||||
mov edx,[ebp+_alt]
|
||||
line_goon:
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_LINE_nodebug:
|
||||
add esi,12
|
||||
mov ebp,amx
|
||||
push eax
|
||||
push edx
|
||||
mov eax,[esi-8] ; get curline
|
||||
mov edx,[esi-4] ; get curfile
|
||||
mov [ebp+_curline],eax
|
||||
mov [ebp+_curfile],edx
|
||||
pop edx
|
||||
pop eax
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_SYMBOL:
|
||||
mov ebp,amx
|
||||
test DWORD [ebp+_flags],AMX_FLAG_DEBUG
|
||||
jz short op_symbol_goon
|
||||
push eax
|
||||
push edx
|
||||
mov eax,[esi+8] ; address
|
||||
mov edx,[esi+12] ; flags
|
||||
mov [ebp+_dbgaddr],eax
|
||||
mov [ebp+_dbgparam],edx
|
||||
mov DWORD [ebp+_dbgcode],DBG_SYMBOL
|
||||
mov eax,esi
|
||||
add eax,16 ; start of symbol name
|
||||
mov [ebp+_dbgname],eax
|
||||
mov edx,[esp+8] ; this is FRM, but offset by two PUSH'es
|
||||
mov [ebp+_frm],edx
|
||||
mov eax,ebp ; parameter of the debugger hook
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debugger hook
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop edx
|
||||
pop eax
|
||||
op_symbol_goon:
|
||||
add esi,[esi+4]
|
||||
add esi,8 ; skip "fixed" part
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_SYMBOL_nodebug:
|
||||
add esi,[esi+4]
|
||||
add esi,8 ; skip "fixed" part
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_SRANGE:
|
||||
mov ebp,amx
|
||||
add esi,12
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short op_srange_goon
|
||||
push eax
|
||||
push edx
|
||||
mov eax,[esi-8] ; get dimensions
|
||||
mov edx,[esi-4] ; get size
|
||||
mov [ebp+_dbgaddr],eax
|
||||
mov [ebp+_dbgparam],edx
|
||||
mov DWORD [ebp+_dbgcode],DBG_SRANGE
|
||||
mov edx,frm
|
||||
mov [ebp+_frm],edx
|
||||
mov [ebp+_stk],ecx ; store values in AMX structure (STK & FRM)
|
||||
; call the debugger hook
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop edx
|
||||
pop eax
|
||||
op_srange_goon:
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_SRANGE_nodebug:
|
||||
add esi,12
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_SYMTAG:
|
||||
mov ebp,amx
|
||||
add esi,8
|
||||
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||
jz short op_symtag_goon
|
||||
mov ebp,amx
|
||||
push eax
|
||||
push edx
|
||||
mov eax,[esi-4] ; get tag
|
||||
mov edx,frm
|
||||
mov DWORD [ebp+_dbgcode],DBG_SRANGE
|
||||
mov [ebp+_dbgparam],eax
|
||||
mov [ebp+_frm],edx
|
||||
mov [ebp+_stk],ecx ; store values in AMX structure (STK & FRM)
|
||||
; call the debugger hook
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
_RESTOREREGS
|
||||
pop edx
|
||||
pop eax
|
||||
op_symtag_goon:
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_SYMTAG_nodebug: ; (TR)
|
||||
add esi,8
|
||||
GO_ON
|
||||
|
||||
@ -1759,6 +1382,45 @@ OP_PUSHADDR:
|
||||
|
||||
|
||||
OP_NOP:
|
||||
add esi,4
|
||||
GO_ON
|
||||
|
||||
|
||||
OP_BREAK:
|
||||
mov ebp,amx ; get amx into ebp
|
||||
add esi,4
|
||||
cmp DWORD [ebp+_debug], 0
|
||||
jnz break_calldebug
|
||||
GO_ON ; debug hook not active, ignore
|
||||
|
||||
break_calldebug:
|
||||
; store the status in the AMX (FRM, STK, HEA, CIP, and PRI + ALT)
|
||||
mov [ebp+_pri],eax
|
||||
mov [ebp+_alt],edx ; EAX and EDX are now free to use
|
||||
mov eax,frm
|
||||
mov edx,hea
|
||||
mov [ebp+_frm],eax ; store values in AMX structure (STK, FRM & HEA)
|
||||
mov [ebp+_hea],edx
|
||||
mov [ebp+_stk],ecx
|
||||
mov eax,esi
|
||||
sub eax,code ; EAX = CIP (relative to start of code segment)
|
||||
mov [ebp+_cip],eax
|
||||
; call the debug hook
|
||||
mov eax,ebp ; 1st parm: amx
|
||||
_SAVEREGS
|
||||
push eax
|
||||
call [ebp+_debug] ; call debug function
|
||||
_DROPARGS 4 ; remove arguments from stack
|
||||
cmp eax,AMX_ERR_NONE
|
||||
je short break_noabort; continue running
|
||||
mov [ebp+_error],eax ; save EAX (error code) before restoring all regs
|
||||
_RESTOREREGS ; abort run, but restore stack first
|
||||
mov eax,[ebp+_error] ; get error code in EAX back again
|
||||
jmp _return ; return error code
|
||||
break_noabort:
|
||||
_RESTOREREGS
|
||||
mov eax,[ebp+_pri] ; restore PRI and ALT
|
||||
mov edx,[ebp+_alt]
|
||||
GO_ON
|
||||
|
||||
|
||||
@ -1796,7 +1458,7 @@ err_divide:
|
||||
|
||||
|
||||
_return:
|
||||
; save a few paraneters, mostly for the "sleep"function
|
||||
; save a few parameters, mostly for the "sleep"function
|
||||
mov ebp,amx ; get amx into ebp
|
||||
mov [ebp+_pri],eax ; store values in AMX structure (PRI, ALT)
|
||||
mov [ebp+_alt],edx ; store values in AMX structure (PRI, ALT)
|
||||
@ -1967,144 +1629,5 @@ _amx_opcodelist DD OP_INVALID
|
||||
DD OP_NOP
|
||||
DD OP_SYSREQ_D
|
||||
DD OP_SYMTAG
|
||||
DD OP_BREAK
|
||||
|
||||
GLOBAL amx_opcodelist_nodebug
|
||||
GLOBAL _amx_opcodelist_nodebug
|
||||
amx_opcodelist_nodebug:
|
||||
_amx_opcodelist_nodebug DD OP_INVALID
|
||||
DD OP_LOAD_PRI
|
||||
DD OP_LOAD_ALT
|
||||
DD OP_LOAD_S_PRI
|
||||
DD OP_LOAD_S_ALT
|
||||
DD OP_LREF_PRI
|
||||
DD OP_LREF_ALT
|
||||
DD OP_LREF_S_PRI
|
||||
DD OP_LREF_S_ALT
|
||||
DD OP_LOAD_I
|
||||
DD OP_LODB_I
|
||||
DD OP_CONST_PRI
|
||||
DD OP_CONST_ALT
|
||||
DD OP_ADDR_PRI
|
||||
DD OP_ADDR_ALT
|
||||
DD OP_STOR_PRI
|
||||
DD OP_STOR_ALT
|
||||
DD OP_STOR_S_PRI
|
||||
DD OP_STOR_S_ALT
|
||||
DD OP_SREF_PRI
|
||||
DD OP_SREF_ALT
|
||||
DD OP_SREF_S_PRI
|
||||
DD OP_SREF_S_ALT
|
||||
DD OP_STOR_I
|
||||
DD OP_STRB_I
|
||||
DD OP_LIDX
|
||||
DD OP_LIDX_B
|
||||
DD OP_IDXADDR
|
||||
DD OP_IDXADDR_B
|
||||
DD OP_ALIGN_PRI
|
||||
DD OP_ALIGN_ALT
|
||||
DD OP_LCTRL
|
||||
DD OP_SCTRL
|
||||
DD OP_MOVE_PRI
|
||||
DD OP_MOVE_ALT
|
||||
DD OP_XCHG
|
||||
DD OP_PUSH_PRI
|
||||
DD OP_PUSH_ALT
|
||||
DD OP_PUSH_R_PRI
|
||||
DD OP_PUSH_C
|
||||
DD OP_PUSH
|
||||
DD OP_PUSH_S
|
||||
DD OP_POP_PRI
|
||||
DD OP_POP_ALT
|
||||
DD OP_STACK_nodebug
|
||||
DD OP_HEAP
|
||||
DD OP_PROC
|
||||
DD OP_RET_nodebug
|
||||
DD OP_RETN_nodebug
|
||||
DD OP_CALL_nodebug
|
||||
DD OP_CALL_PRI_nodebug
|
||||
DD OP_JUMP
|
||||
DD OP_JREL
|
||||
DD OP_JZER
|
||||
DD OP_JNZ
|
||||
DD OP_JEQ
|
||||
DD OP_JNEQ
|
||||
DD OP_JLESS
|
||||
DD OP_JLEQ
|
||||
DD OP_JGRTR
|
||||
DD OP_JGEQ
|
||||
DD OP_JSLESS
|
||||
DD OP_JSLEQ
|
||||
DD OP_JSGRTR
|
||||
DD OP_JSGEQ
|
||||
DD OP_SHL
|
||||
DD OP_SHR
|
||||
DD OP_SSHR
|
||||
DD OP_SHL_C_PRI
|
||||
DD OP_SHL_C_ALT
|
||||
DD OP_SHR_C_PRI
|
||||
DD OP_SHR_C_ALT
|
||||
DD OP_SMUL
|
||||
DD OP_SDIV
|
||||
DD OP_SDIV_ALT
|
||||
DD OP_UMUL
|
||||
DD OP_UDIV
|
||||
DD OP_UDIV_ALT
|
||||
DD OP_ADD
|
||||
DD OP_SUB
|
||||
DD OP_SUB_ALT
|
||||
DD OP_AND
|
||||
DD OP_OR
|
||||
DD OP_XOR
|
||||
DD OP_NOT
|
||||
DD OP_NEG
|
||||
DD OP_INVERT
|
||||
DD OP_ADD_C
|
||||
DD OP_SMUL_C
|
||||
DD OP_ZERO_PRI
|
||||
DD OP_ZERO_ALT
|
||||
DD OP_ZERO
|
||||
DD OP_ZERO_S
|
||||
DD OP_SIGN_PRI
|
||||
DD OP_SIGN_ALT
|
||||
DD OP_EQ
|
||||
DD OP_NEQ
|
||||
DD OP_LESS
|
||||
DD OP_LEQ
|
||||
DD OP_GRTR
|
||||
DD OP_GEQ
|
||||
DD OP_SLESS
|
||||
DD OP_SLEQ
|
||||
DD OP_SGRTR
|
||||
DD OP_SGEQ
|
||||
DD OP_EQ_C_PRI
|
||||
DD OP_EQ_C_ALT
|
||||
DD OP_INC_PRI
|
||||
DD OP_INC_ALT
|
||||
DD OP_INC
|
||||
DD OP_INC_S
|
||||
DD OP_INC_I
|
||||
DD OP_DEC_PRI
|
||||
DD OP_DEC_ALT
|
||||
DD OP_DEC
|
||||
DD OP_DEC_S
|
||||
DD OP_DEC_I
|
||||
DD OP_MOVS
|
||||
DD OP_CMPS
|
||||
DD OP_FILL
|
||||
DD OP_HALT
|
||||
DD OP_BOUNDS
|
||||
DD OP_SYSREQ_PRI
|
||||
DD OP_SYSREQ_C
|
||||
DD OP_FILE
|
||||
DD OP_LINE_nodebug
|
||||
DD OP_SYMBOL_nodebug
|
||||
DD OP_SRANGE_nodebug
|
||||
DD OP_JUMP_PRI
|
||||
DD OP_SWITCH
|
||||
DD OP_CASETBL
|
||||
DD OP_SWAP_PRI
|
||||
DD OP_SWAP_ALT
|
||||
DD OP_PUSHADDR
|
||||
DD OP_NOP
|
||||
DD OP_SYSREQ_D
|
||||
DD OP_SYMTAG_nodebug
|
||||
|
@ -1,4 +1,5 @@
|
||||
; JIT.ASM: Just-In-Time compiler for the Abstract Machine of the "Small"language
|
||||
; AMXJITSN.ASM: Just-In-Time compiler for the Abstract Machine of the "Pawn"
|
||||
; scripting language
|
||||
; (C) 1999-2000, Marc Peter; beta version; provided AS IS WITHOUT ANY WARRANTIES
|
||||
|
||||
; I reached >155 million instr./sec on my AMD K6-2/366 with the Hanoi "bench"
|
||||
@ -20,42 +21,78 @@
|
||||
; step.
|
||||
|
||||
; NOTE 3:
|
||||
; During execution of the compiled code with amx_exec_asm() the x86 processor's
|
||||
; During execution of the compiled code with amx_exec_jit() the x86 processor's
|
||||
; stack is switched into the data section of the abstract machine. This means
|
||||
; that there should always be enough memory left between HEA and STK to provide
|
||||
; stack space for occurring interrupts! (see the STACKRESERVE variable)
|
||||
|
||||
; NOTE 4:
|
||||
; Although the Small compiler doesn't generate the LCTRL, SCTRL and CALL.I
|
||||
; Although the Pawn compiler doesn't generate the LCTRL, SCTRL and CALL.I
|
||||
; instructions, I have to tell that they don't work as expected in a JIT
|
||||
; compiled program, because there is no easy way of transforming AMX code
|
||||
; addresses and JIT translated ones. This might be fixed in a future version.
|
||||
|
||||
; NX ("No eXecute") and XD (eXecution Denied) bits
|
||||
; (by Thiadmer Riemersma)
|
||||
;
|
||||
; AMD defined a bit "No eXecute" for the page table entries (for its 64-bit
|
||||
; processors) and Intel came with the same design, but calling it differently.
|
||||
; The purpose is to make "buffer overrun" security holes impossible, or at least
|
||||
; very, very difficult, by marking the stack and the heap as memory regions
|
||||
; such that an attempt to execute processor instructions will cause a processor
|
||||
; exception (of course, a buffer overrun that is not explictly handled will then
|
||||
; crash the application --instead of executing the rogue code).
|
||||
;
|
||||
; For JIT compilers, this has the impact that you are not allowed to execute the
|
||||
; code that the JIT has generated. To do that, you must adjust the attributes
|
||||
; for the memory page. For Microsoft Windows, you can use VirtualAlloc() to
|
||||
; allocate a memory block with the appropriate fags; on Linux (with a recent
|
||||
; kernel), you would use vmalloc_exec(). Microsoft Windows also offers the
|
||||
; function VirtualProtect() to change the page attributes of an existing memory
|
||||
; block, but there are caveats in its use: if the block spans multiple pages,
|
||||
; these pages must be consecutive, and if there are blocks of memory in a page
|
||||
; unrelated to the JIT, their page attributes will change too.
|
||||
;
|
||||
; The JIT compiler itself requires only read-write access (this is the default
|
||||
; for a memory block that you allocate). The execution of the JIT-compiled code
|
||||
; requires full access to the memory block: read, write and execute. It needs
|
||||
; write access, because the SYSREQ.C opcode is patched to SYSREQ.D after the
|
||||
; first lookup (this is an optimization, look up the address of the native
|
||||
; function only once). For processors that do not support the NX/XD bit,
|
||||
; execution of code is implicitly supported if read access is supported.
|
||||
;
|
||||
; During compilation, the JIT compiler requires write-access to its own code
|
||||
; segment: the JIT-compiler patches P-code parameters into its own code segment
|
||||
; during compilation. This is handled in the support code for amx_InitJIT.
|
||||
;
|
||||
;
|
||||
; CALLING CONVENTIONS
|
||||
; (by Thiadmer Riemersma)
|
||||
;
|
||||
; CALLING CONVENTIONS (by Thiadmer Riemersma)
|
||||
; This version is the JIT that uses the "stack calling convention". In the
|
||||
; original implementation, this meant __cdecl; both for the calling convention
|
||||
; for the _asm_runJIT routine itself as for the callback functions.
|
||||
; The current release supports __stdcall for the callback functions; to
|
||||
; use it, you need to assemble the file with STDECL defined (Since STDCALL is
|
||||
; use it, you need to assemble the file with STDECL defined (Since STDCALL is
|
||||
; a reserved word on the assembler, I had to choose a different name for the
|
||||
; macro, hence STDECL.)
|
||||
|
||||
; Revision History
|
||||
;------------------
|
||||
; 16 September 2004 by David "BAILOPAN" Anderson
|
||||
; Implemented a compile time toggleable debug hook on OP_CALL and OP_RET.
|
||||
; NOTE: JIT has not had debug hooks since 1999.
|
||||
; 8 September 2004 by David "BAILOPAN" Anderson
|
||||
; Changed OP_LINE call to be compile-time toggle-able between compiling
|
||||
; line ops or not.
|
||||
; ----------------
|
||||
; 17 february 2005 by Thiadmer Riemersms
|
||||
; Addition of the BREAK opcode, removal of the older debugging opcode
|
||||
; table. There should now be some debug support (if enabled during the
|
||||
; build of the JIT compiler), but not enough to run a debugger: the JIT
|
||||
; compiler does not keep a list that relates the code addresses of the
|
||||
; P-code versus the native code.
|
||||
; 29 June 2004 by G.W.M. Vissers
|
||||
; Translated the thing into NASM. The actual generation of the code is
|
||||
; put into the data section because the code modifies itself whereas the
|
||||
; text section is usually read-only in the Unix ELF format.
|
||||
; Translated the thing into NASM. The actual generation of the code is
|
||||
; put into the data section because the code modifies itself whereas the
|
||||
; text section is usually read-only in the Unix ELF format.
|
||||
; 6 march 2004 by Thiadmer Riemersma
|
||||
; Corrected a bug in OP_FILL, where a cell preceding the array would
|
||||
; be overwritten (zero'ed out). This bug was brought to my attention
|
||||
; by Robert Daniels.
|
||||
; by Robert Daniels.
|
||||
; 22 december 2003 by Thiadmer Riemersma (TR)
|
||||
; Added the SYMTAG and SYSCALL.D opcodes (these are not really supported;
|
||||
; SYMTAG is a no-op).
|
||||
@ -94,8 +131,8 @@
|
||||
; hanoi bench.
|
||||
; 1999/08/05 MP
|
||||
; * fixed OP_LINE in the case of NODBGCALLS==1, where no compiled address
|
||||
; was stored for the LINE byte code (I.e. SWITCH would jump to totally
|
||||
; wrong addresses.) The same fix was applied to OP_FILL, OP_FILE and
|
||||
; was stored for the LINE byte code (i.e. SWITCH would jump to totally
|
||||
; wrong addresses). The same fix was applied to OP_FILL, OP_FILE and
|
||||
; OP_SCTRL (for the no-op case).
|
||||
; 1999/08/04 MP
|
||||
; * updated with 4 new opcodes (SRANGE does nothing at the moment; 2dim.
|
||||
@ -107,6 +144,16 @@
|
||||
; to compute the destination address: It searches backwards now.
|
||||
; 1999/07/08 MP - initial revision
|
||||
|
||||
|
||||
;
|
||||
; Support for the BREAK opcode (callback to the debugger): 0 = no, all other
|
||||
; values = yes. Beware that the compiled code runs slower when this is enabled,
|
||||
; and that debug support is still fairly minimal.
|
||||
;
|
||||
; GWMV: to generate LINE opcode, %define DEBUGSUPPORT
|
||||
;
|
||||
%undef DEBUGSUPPORT
|
||||
|
||||
;
|
||||
; If this is set to 1 the JIT generates relocatable code for case tables, too.
|
||||
; If set to 0, a faster variant for switch (using absolute addresses) is
|
||||
@ -128,119 +175,17 @@
|
||||
;
|
||||
; This variable controls the generation of memory range checks at run-time.
|
||||
; You should set this to 0, only when you are sure that there are no range
|
||||
; violations in your Small programs and you really need those 5% speed gain.
|
||||
; violations in your Pawn programs and you really need those 5% speed gain.
|
||||
;
|
||||
; GWMV: To disable runtime checks, %undef it, instread of setting it to zero
|
||||
;
|
||||
%define DORUNTIMECHECKS
|
||||
|
||||
|
||||
struc amx_s
|
||||
_base: resd 1
|
||||
_dataseg: resd 1
|
||||
_callback: resd 1
|
||||
_debug: resd 1
|
||||
_cip: resd 1
|
||||
_frm: resd 1
|
||||
_hea: resd 1
|
||||
_hlw: resd 1
|
||||
_stk: resd 1
|
||||
_stp: resd 1
|
||||
_flags: resd 1
|
||||
_curline: resd 1
|
||||
_curfile: resd 1
|
||||
_dbgcode: resd 1
|
||||
_dbgaddr: resd 1
|
||||
_dbgparam: resd 1
|
||||
_dbgname: resd 1
|
||||
;usertags and userdata are 16 bytes on AMX Mod X
|
||||
_usertags1: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_usertags2: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_usertags3: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_usertags4: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata1: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata2: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata3: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata4: resd 1 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_error: resd 1
|
||||
_pri: resd 1
|
||||
_alt: resd 1
|
||||
_reset_stk: resd 1
|
||||
_reset_hea: resd 1
|
||||
_syscall_d: resd 1
|
||||
; the two fields below are for the JIT
|
||||
; they are included in the non-JIT version for AMX Mod X
|
||||
; this is to make sure that the structs match universally!
|
||||
_reloc_size: resd 1 ; memory block for relocations
|
||||
_code_size: resd 1 ; memory size of the native code
|
||||
endstruc
|
||||
|
||||
|
||||
struc amxhead_s
|
||||
_size: resd 1 ; size of the "file"
|
||||
_magic: resw 1 ; signature
|
||||
_file_version: resb 1 ;file format version
|
||||
_amx_version: resb 1 ; required version of the AMX
|
||||
_h_flags: resw 1
|
||||
_defsize: resw 1 ; size of one public/native function entry
|
||||
_cod: resd 1 ; initial value of COD - code block
|
||||
_dat: resd 1 ; initial value of DAT - data block
|
||||
_h_hea: resd 1 ; initial value of HEA - start of the heap
|
||||
_h_stp: resd 1 ; initial value of STP - stack top
|
||||
_h_cip: resd 1 ; initial value of CIP - the instruction pointer
|
||||
_publics: resd 1 ; offset to the "public functions" table
|
||||
_natives: resd 1 ; offset to the "native functions" table
|
||||
_libraries: resd 1 ; offset to the "library" table
|
||||
_pubvars: resd 1 ; offset to the "public variables" table
|
||||
_tags: resd 1 ; offset to the "public tagnames" table
|
||||
endstruc
|
||||
|
||||
|
||||
AMX_ERR_NONE equ 0
|
||||
AMX_ERR_EXIT equ 1
|
||||
AMX_ERR_ASSERT equ 2
|
||||
AMX_ERR_STACKERR equ 3
|
||||
AMX_ERR_BOUNDS equ 4
|
||||
AMX_ERR_MEMACCESS equ 5
|
||||
AMX_ERR_INVINSTR equ 6
|
||||
AMX_ERR_STACKLOW equ 7
|
||||
AMX_ERR_HEAPLOW equ 8
|
||||
AMX_ERR_CALLBACK equ 9
|
||||
AMX_ERR_NATIVE equ 10
|
||||
AMX_ERR_DIVIDE equ 11 ; MP: added for catching divide errors
|
||||
AMX_ERR_SLEEP equ 12 ; (TR) go into sleep mode
|
||||
|
||||
AMX_ERR_MEMORY equ 16
|
||||
AMX_ERR_FORMAT equ 17
|
||||
AMX_ERR_VERSION equ 18
|
||||
AMX_ERR_NOTFOUND equ 19
|
||||
AMX_ERR_INDEX equ 20
|
||||
AMX_ERR_DEBUG equ 21
|
||||
AMX_ERR_INIT equ 22
|
||||
AMX_ERR_USERDATA equ 23
|
||||
AMX_ERR_INIT_JIT equ 24
|
||||
AMX_ERR_PARAMS equ 25
|
||||
AMX_ERR_DOMAIN equ 26
|
||||
|
||||
DBG_INIT equ 0
|
||||
DBG_FILE equ 1
|
||||
DBG_LINE equ 2
|
||||
DBG_SYMBOL equ 3
|
||||
DBG_CLRSYM equ 4
|
||||
DBG_CALL equ 5
|
||||
DBG_RETURN equ 6
|
||||
DBG_TERMINATE equ 7
|
||||
DBG_SRANGE equ 8
|
||||
DBG_SYMTAG equ 9
|
||||
|
||||
AMX_FLAG_CHAR16 equ 0001h ; characters are 16-bit
|
||||
AMX_FLAG_DEBUG equ 0002h ; symbolic info. available
|
||||
AMX_FLAG_LINEOPS equ 0020h ; line ops should be parsed [load time only flag] - ~dvander
|
||||
AMX_FLAG_BROWSE equ 4000h
|
||||
AMX_FLAG_RELOC equ 8000h ; jump/call addresses relocated
|
||||
%define JIT 1
|
||||
%include "amxdefn.asm"
|
||||
|
||||
; GWMV:
|
||||
; Nasm can't do the next as equivalence statements, since the value of
|
||||
; Nasm can't do the next as equivalence statements, since the value of
|
||||
; esi is not determined at compile time
|
||||
%define stk [esi+32] ; define some aliases to registers that will
|
||||
%define alt [esi+28] ; be stored on the stack when the code is
|
||||
@ -269,7 +214,7 @@ AMX_FLAG_RELOC equ 8000h ; jump/call addresses relocated
|
||||
|
||||
|
||||
;
|
||||
; For determining the biggest native code section generated for ONE Small
|
||||
; For determining the biggest native code section generated for ONE Pawn
|
||||
; opcode. (See the following macro and the PUBLIC function getMaxCodeSize().)
|
||||
;
|
||||
; GWMV: Do NOT see the following macro. See CHECKCODESIZE instead.
|
||||
@ -278,20 +223,12 @@ AMX_FLAG_RELOC equ 8000h ; jump/call addresses relocated
|
||||
|
||||
;
|
||||
; This is the work horse of the whole JIT: It actually copies the code.
|
||||
; Notes from ~dvander (with help of dJeyL)
|
||||
; This takes a source and ending address pointer in the assembled JIT code.
|
||||
; Then it subtracts them and copies the code in between.
|
||||
; The last parameter is the number of bytes the opcode is so it can jump
|
||||
; to the next one.
|
||||
; Also note that the "in between" code is NEVER executed during the compile
|
||||
; phase of the JIT. It's only assembled in memory, and copied into the
|
||||
; final output bytecode by this function.
|
||||
%macro GO_ON 2-3 4
|
||||
mov esi, %1 ;get source address of JIT code
|
||||
mov ecx,%2-%1 ;get number of bytes to copy
|
||||
mov [ebx],edi ;store address for jump-correction
|
||||
add ebx,%3
|
||||
rep movsb
|
||||
add ebx,%3
|
||||
rep movsb
|
||||
cmp ebx,[end_code]
|
||||
jae code_gen_done
|
||||
jmp dword [ebx] ;go on with the next opcode
|
||||
@ -300,9 +237,7 @@ AMX_FLAG_RELOC equ 8000h ; jump/call addresses relocated
|
||||
; GWMV:
|
||||
; Nasm can't handle the determination of the maximum code size as was done
|
||||
; in the Masm implementation, since it only does two passes. This macro is
|
||||
; called *after* the code for each Small instruction.
|
||||
; Notes by ~dvander: This just substracts a label's ip from the current ip.
|
||||
; Therefore you get an instant size check - see RELOC
|
||||
; called *after* the code for each Pawn instruction.
|
||||
%macro CHECKCODESIZE 1
|
||||
%if MAXCODESIZE < $-%1
|
||||
%assign MAXCODESIZE $-%1
|
||||
@ -310,14 +245,9 @@ AMX_FLAG_RELOC equ 8000h ; jump/call addresses relocated
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Modify the argument of an x86 instruction with the Small opcode's parameter
|
||||
; Modify the argument of an x86 instruction with the Pawn opcode's parameter
|
||||
; before copying the code.
|
||||
;
|
||||
; Notes by ~dvander (thanks to dJeyL) - this will take an address and modify
|
||||
; the dword at it. Since the JIT copies already assembled code, you see
|
||||
; things like "call 12345678h". This is an arbitrary value as putval
|
||||
; will modify it in memory and then GO_ON will add it to the program.
|
||||
; It is important to get the putval address right - it's in bytes.
|
||||
%macro putval 1
|
||||
mov eax,[ebx+4]
|
||||
mov dword [%1],eax
|
||||
@ -326,17 +256,12 @@ AMX_FLAG_RELOC equ 8000h ; jump/call addresses relocated
|
||||
;
|
||||
; Add an entry to the table of addresses which have to be relocated after the
|
||||
; code compilation is done.
|
||||
; Notes by ~dvander: This is sort of what amx_BrowseRelocate() does, although
|
||||
; relocation is actually done after code generation (this just adds to a
|
||||
; table). Like putval, this takes in an address and marks it to be
|
||||
; rewritten. It is a good idea to just use labels to find relocation
|
||||
; offsets (see OP_CALL and OP_RETN). After code generation, this table
|
||||
; is browsed and the correct threaded jumps are placed.
|
||||
;
|
||||
%macro RELOC 1-2 ; adr, dest
|
||||
mov ebp,[reloc_num]
|
||||
%if %0 < 2
|
||||
mov eax,[ebx+4]
|
||||
%else
|
||||
%else
|
||||
lea eax,[%2]
|
||||
%endif
|
||||
mov [edx+ebp],eax ; write absolute destination
|
||||
@ -356,7 +281,7 @@ section .text
|
||||
|
||||
|
||||
global asm_runJIT, _asm_runJIT
|
||||
global amx_exec_asm, _amx_exec_asm
|
||||
global amx_exec_jit, _amx_exec_jit
|
||||
global getMaxCodeSize, _getMaxCodeSize
|
||||
|
||||
|
||||
@ -381,7 +306,7 @@ _asm_runJIT:
|
||||
mov eax,[esp+20] ; get amxh
|
||||
mov edx,[esp+24] ; get jumps array
|
||||
mov ebx,[esp+28] ; get destination
|
||||
|
||||
|
||||
mov [amxhead],eax ; save pointer to AMX_HEADER struct
|
||||
mov ecx,[eax+_cod] ; get offset of start of code
|
||||
mov eax,[eax+_dat] ; offset of start of data = end of code
|
||||
@ -481,9 +406,9 @@ reloc_done:
|
||||
ret
|
||||
|
||||
; GWMV:
|
||||
; The code below modifies itself to store the arguments to the Small opcodes
|
||||
; The code below modifies itself to store the arguments to the Pawn opcodes
|
||||
; in the compiled code. This is fine, but the .text section in an ELF executable
|
||||
; is usually marked read-only, that's why this code is in the .data section.
|
||||
; is usually marked read-only, that's why this code is in the .data section.
|
||||
|
||||
section .data exec
|
||||
|
||||
@ -817,7 +742,7 @@ OP_ALIGN_PRI:
|
||||
CHECKCODESIZE j_align_pri
|
||||
|
||||
OP_ALIGN_ALT:
|
||||
;nop
|
||||
;nop;
|
||||
mov eax,4
|
||||
sub eax,[ebx+4]
|
||||
mov dword [j_align_alt+1],eax
|
||||
@ -1045,7 +970,7 @@ OP_HEAP:
|
||||
call [chk_marginheap]
|
||||
%endif
|
||||
CHECKCODESIZE j_heap
|
||||
|
||||
|
||||
;good
|
||||
OP_PROC:
|
||||
;nop;
|
||||
@ -1073,119 +998,22 @@ OP_RET:
|
||||
;good
|
||||
OP_RETN:
|
||||
;nop;
|
||||
;save registers
|
||||
push eax
|
||||
push ebp
|
||||
;get .amx flags
|
||||
mov ebp,[amxhead]
|
||||
mov eax,[ebp+_h_flags]
|
||||
;check to see if the flag has line ops
|
||||
and eax,AMX_FLAG_DEBUG
|
||||
cmp eax,AMX_FLAG_DEBUG
|
||||
;restore registers
|
||||
pop ebp
|
||||
pop eax
|
||||
;if so, skip down to debug compiler
|
||||
jmp _go_jit_retn_debug
|
||||
GO_ON j_retn, OP_CALL
|
||||
|
||||
_go_jit_retn_nodebug:
|
||||
GO_ON j_retn_nodebug, _go_jit_retn_go
|
||||
j_retn_nodebug:
|
||||
j_retn:
|
||||
jmp [jit_retn]
|
||||
CHECKCODESIZE j_retn_nodebug
|
||||
_go_jit_retn_go:
|
||||
jmp _go_jit_retn_end
|
||||
|
||||
_go_jit_retn_debug:
|
||||
GO_ON j_retn, OP_CALL
|
||||
j_retn:
|
||||
push ebp
|
||||
push eax
|
||||
push edx
|
||||
;get AMX
|
||||
mov ebp,amx
|
||||
;get debug call ptr
|
||||
mov eax,[ebp+_userdata2]
|
||||
;check validity
|
||||
mov edx, dword 0
|
||||
cmp eax, edx
|
||||
je _go_jit_skip_debug
|
||||
xchg esp,esi ;switch stack
|
||||
push 1 ;param 2 mode 1 = pop
|
||||
push ebp ;param 1 - amx
|
||||
call eax ;indirect debug call
|
||||
add esp, 8 ;restore stack
|
||||
xchg esp,esi ;return to AMX stack
|
||||
mov ebp,amx ;restore AMX [necessary?]
|
||||
_go_jit_skip_debug:
|
||||
pop edx
|
||||
pop eax
|
||||
pop ebp
|
||||
jmp [jit_retn]
|
||||
CHECKCODESIZE j_retn
|
||||
_go_jit_retn_end:
|
||||
CHECKCODESIZE j_retn
|
||||
|
||||
;good
|
||||
OP_CALL:
|
||||
;nop;
|
||||
;save registers
|
||||
push eax
|
||||
push ebp
|
||||
;get .amx flags
|
||||
mov ebp,[amxhead]
|
||||
mov eax,[ebp+_h_flags]
|
||||
;check to see if the flag has line ops
|
||||
and eax,AMX_FLAG_DEBUG
|
||||
cmp eax,AMX_FLAG_DEBUG
|
||||
;restore registers
|
||||
pop ebp
|
||||
pop eax
|
||||
;if so, skip down to debug compiler
|
||||
jmp _go_jit_debug
|
||||
RELOC 1
|
||||
GO_ON j_call, OP_CALL_I, 8
|
||||
|
||||
_go_jit_nodebug:
|
||||
RELOC 1
|
||||
GO_ON j_call_nodebug, _j_call_go_on, 8
|
||||
j_call_nodebug:
|
||||
db 0e8h, 0, 0, 0, 0
|
||||
CHECKCODESIZE j_call_nodebug
|
||||
|
||||
_j_call_go_on:
|
||||
jmp _opcall_end
|
||||
|
||||
_go_jit_debug:
|
||||
;thanks to Julien "dJeyL" Laurent for code relocation explanation
|
||||
RELOC _go_jit_reloc-j_call+1
|
||||
GO_ON j_call, OP_CALL_I, 8
|
||||
j_call:
|
||||
; save some registers
|
||||
push ebp
|
||||
push eax
|
||||
push edx
|
||||
; get AMX
|
||||
mov ebp,amx
|
||||
; get debug call pointer
|
||||
mov eax,[ebp+_userdata2]
|
||||
; check to see if it's valid
|
||||
mov edx, dword 0
|
||||
cmp eax,edx
|
||||
je _go_jit_skip_call
|
||||
xchg esp,esi ;switch to caller stack
|
||||
push 2 ;param mode=2, push
|
||||
push ebp ;param amx
|
||||
call eax ;indirect call
|
||||
add esp, 8 ;restore stack
|
||||
xchg esp,esi ;return to AMX stack
|
||||
mov ebp,amx ;restore AMX [necessary?]
|
||||
_go_jit_skip_call:
|
||||
;restore original registers
|
||||
pop edx
|
||||
pop eax
|
||||
pop ebp
|
||||
_go_jit_reloc:
|
||||
db 0e8h, 0, 0, 0, 0
|
||||
CHECKCODESIZE j_call
|
||||
_opcall_end:
|
||||
j_call:
|
||||
;call 12345678h ; tasm chokes on this out of a sudden
|
||||
db 0e8h, 0, 0, 0, 0
|
||||
CHECKCODESIZE j_call
|
||||
|
||||
OP_CALL_I:
|
||||
;nop;
|
||||
@ -1857,39 +1685,12 @@ OP_FILE: ;opcode is simply ignored
|
||||
|
||||
OP_LINE:
|
||||
;nop;
|
||||
;~dvander - opline is now variable on compile time :]
|
||||
;save registers
|
||||
push eax
|
||||
push ebp
|
||||
;get .amx flags
|
||||
mov ebp,[amxhead]
|
||||
mov eax,[ebp+_h_flags]
|
||||
;check to see if the flag has line ops
|
||||
and eax,AMX_FLAG_LINEOPS
|
||||
cmp eax,AMX_FLAG_LINEOPS
|
||||
;restore registers
|
||||
pop ebp
|
||||
pop eax
|
||||
;if so, skip down to debug compiler
|
||||
je _go_debug
|
||||
|
||||
mov [ebx],edi ; no line number support: ignore opcode
|
||||
add ebx,12 ; move on to next opcode
|
||||
cmp ebx,[end_code]
|
||||
jae code_gen_done
|
||||
jmp dword [ebx] ; go on with the next opcode
|
||||
|
||||
_go_debug:
|
||||
putval j_line+6
|
||||
mov eax,[ebx+8]
|
||||
mov [j_line_sm],eax
|
||||
GO_ON j_line, OP_SYMBOL, 12
|
||||
j_line:
|
||||
call [jit_line]
|
||||
DD 0 ; space for curline
|
||||
j_line_sm DD 0 ; space for curfile
|
||||
CHECKCODESIZE j_line
|
||||
|
||||
OP_SYMBOL: ;ignored
|
||||
mov [ebx],edi
|
||||
mov eax,[ebx+4] ; get size
|
||||
@ -2019,6 +1820,23 @@ OP_SYMTAG: ;ignored (TR)
|
||||
jmp dword [ebx] ; go on with the next opcode
|
||||
|
||||
|
||||
OP_BREAK:
|
||||
%ifndef DEBUGSUPPORT
|
||||
mov [ebx],edi ; no line number support: ignore opcode
|
||||
add ebx,4 ; move on to next opcode
|
||||
cmp ebx,[end_code]
|
||||
jae code_gen_done
|
||||
jmp DWORD [ebx] ; go on with the next opcode
|
||||
%else
|
||||
GO_ON j_break, OP_INVALID
|
||||
j_break:
|
||||
mov ebp,amx
|
||||
cmp DWORD [ebp+_debug], 0
|
||||
je $+4 ; jump around the "call" statement
|
||||
call [jit_break]
|
||||
CHECKCODESIZE j_break
|
||||
%endif
|
||||
|
||||
OP_INVALID: ; break from the compiler with an error code
|
||||
mov eax,AMX_ERR_INVINSTR
|
||||
pop esi
|
||||
@ -2032,12 +1850,12 @@ section .text
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; ;
|
||||
;cell asm_exec( cell *regs, cell *retval, cell stp, cell hea );
|
||||
;cell amx_exec( cell *regs, cell *retval, cell stp, cell hea );
|
||||
; eax edx ebx ecx ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
amx_exec_asm:
|
||||
_amx_exec_asm:
|
||||
amx_exec_jit:
|
||||
_amx_exec_jit:
|
||||
push edi
|
||||
push esi
|
||||
push ebp
|
||||
@ -2338,20 +2156,39 @@ JIT_OP_SYSREQ_D: ; (TR)
|
||||
ret
|
||||
|
||||
|
||||
JIT_OP_LINE:
|
||||
pop ecx ; get return address
|
||||
mov ebp,amx
|
||||
push eax
|
||||
push edx
|
||||
mov eax,[ecx] ; get curline
|
||||
mov edx,[ecx+4] ; get curfile
|
||||
add ecx,8 ; skip curline & curfile
|
||||
mov [ebp+_curline],eax ; store curline
|
||||
mov [ebp+_curfile],edx ; store curfile
|
||||
JIT_OP_BREAK:
|
||||
%ifdef DEBUGSUPPORT
|
||||
mov ecx,esp ; get STK into ECX
|
||||
mov ebp,amx ; get amx into EBP
|
||||
|
||||
sub ecx,edi ; correct STK
|
||||
|
||||
mov [ebp+_pri],eax ; store values in AMX structure: PRI,
|
||||
mov [ebp+_alt],edx ; ALT,
|
||||
mov [ebp+_stk],ecx ; STK,
|
||||
mov ecx,hea ; HEA,
|
||||
mov ebx,frm ; and FRM
|
||||
mov [ebp+_hea],ecx
|
||||
mov [ebp+_frm],ebx ; EBX & ECX are invalid by now
|
||||
;??? storing CIP is not very useful, because the code changed (during JIT compile)
|
||||
|
||||
xchg esp,esi ; switch to caller stack
|
||||
push ebp ; 1st param: amx
|
||||
call [ebp+_debug]
|
||||
_DROPARGS 4 ; remove args from stack
|
||||
xchg esp,esi ; switch back to AMX stack
|
||||
cmp eax,AMX_ERR_NONE
|
||||
jne _return_popstack; return error code, if any
|
||||
|
||||
mov ebp,amx ; get amx into EBP
|
||||
mov eax,[ebp+_pri] ; restore values
|
||||
mov edx,[ebp+_alt] ; ALT,
|
||||
mov edx,alt ; restore ALT
|
||||
mov ebx,frm ; restore FRM
|
||||
add ebx,edi ; relocate frame
|
||||
%endif
|
||||
ret
|
||||
|
||||
pop edx
|
||||
pop eax
|
||||
jmp ecx ; jump back
|
||||
|
||||
JIT_OP_SWITCH:
|
||||
pop ebp ; pop return address = table address
|
||||
@ -2370,9 +2207,10 @@ JIT_OP_SWITCH:
|
||||
jmp ebp
|
||||
%endif
|
||||
|
||||
|
||||
; The caller of asm_runJIT() can determine the maximum size of the compiled
|
||||
; code by multiplying the result of this function by the number of opcodes in
|
||||
; Small module.
|
||||
; Pawn module.
|
||||
;
|
||||
; unsigned long getMaxCodeSize_();
|
||||
;
|
||||
@ -2414,17 +2252,17 @@ jit_fill DD JIT_OP_FILL
|
||||
jit_bounds DD JIT_OP_BOUNDS
|
||||
jit_sysreq DD JIT_OP_SYSREQ
|
||||
jit_sysreq_d DD JIT_OP_SYSREQ_D
|
||||
jit_line DD JIT_OP_LINE
|
||||
jit_break DD JIT_OP_BREAK
|
||||
jit_switch DD JIT_OP_SWITCH
|
||||
|
||||
;
|
||||
; The table for the browser/relocator function.
|
||||
;
|
||||
|
||||
global amx_opcodelist, _amx_opcodelist
|
||||
global amx_opcodelist_jit, _amx_opcodelist_jit
|
||||
|
||||
amx_opcodelist:
|
||||
_amx_opcodelist:
|
||||
amx_opcodelist_jit:
|
||||
_amx_opcodelist_jit:
|
||||
DD OP_INVALID
|
||||
DD OP_LOAD_PRI
|
||||
DD OP_LOAD_ALT
|
||||
@ -2562,3 +2400,6 @@ _amx_opcodelist:
|
||||
DD OP_NOP ; TR
|
||||
DD OP_SYSREQ_D ; TR
|
||||
DD OP_SYMTAG ; TR
|
||||
DD OP_BREAK ; TR
|
||||
|
||||
END
|
@ -353,7 +353,7 @@ static cell AMX_NATIVE_CALL is_linux_server(AMX *amx, cell *params)
|
||||
|
||||
static cell AMX_NATIVE_CALL is_amd64_server(AMX *amx, cell *params)
|
||||
{
|
||||
#if SMALL_CELL_SIZE==64
|
||||
#if PAWN_CELL_SIZE==64
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
@ -794,10 +794,11 @@ static cell AMX_NATIVE_CALL register_menucmd(AMX *amx, cell *params) /* 3 param
|
||||
int ilen, idx;
|
||||
char* sptemp = get_amxstring(amx,params[3],0,ilen);
|
||||
|
||||
if(amx_FindPublic(amx, sptemp ,&idx)!=AMX_ERR_NONE) {
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",sptemp,plugin->getName() );
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
return 0;
|
||||
idx = registerSPForwardByName(amx, sptemp, FP_CELL, FP_CELL, FP_DONE);
|
||||
if (idx == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", sptemp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_menucmds.registerMenuCmd( plugin , params[1] , params[2] , idx );
|
||||
@ -870,9 +871,10 @@ static cell AMX_NATIVE_CALL register_concmd(AMX *amx, cell *params) /* 4 param *
|
||||
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx );
|
||||
int i, idx = 0;
|
||||
char* temp = get_amxstring(amx,params[2],0, i );
|
||||
if(amx_FindPublic(amx, temp ,&idx)!=AMX_ERR_NONE) {
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",temp,plugin->getName() );
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
if (idx == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
||||
return 0;
|
||||
}
|
||||
temp = get_amxstring(amx,params[1],0, i );
|
||||
@ -897,9 +899,10 @@ static cell AMX_NATIVE_CALL register_clcmd(AMX *amx, cell *params) /* 4 param */
|
||||
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx );
|
||||
int i, idx = 0;
|
||||
char* temp = get_amxstring(amx,params[2],0, i );
|
||||
if(amx_FindPublic(amx, temp ,&idx)!=AMX_ERR_NONE) {
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",temp,plugin->getName() );
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
if(idx==-1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
||||
return 0;
|
||||
}
|
||||
temp = get_amxstring(amx,params[1],0, i );
|
||||
@ -922,9 +925,10 @@ static cell AMX_NATIVE_CALL register_srvcmd(AMX *amx, cell *params) /* 2 param *
|
||||
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx );
|
||||
int i, idx = 0;
|
||||
char* temp = get_amxstring(amx,params[2],0, i );
|
||||
if(amx_FindPublic(amx, temp ,&idx)!=AMX_ERR_NONE) {
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",temp,plugin->getName() );
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
if (idx==-1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
||||
return 0;
|
||||
}
|
||||
temp = get_amxstring(amx,params[1],0, i );
|
||||
@ -1023,10 +1027,10 @@ static cell AMX_NATIVE_CALL register_event(AMX *amx, cell *params) /* 2 param */
|
||||
}
|
||||
|
||||
sTemp = get_amxstring(amx,params[2],0,len);
|
||||
|
||||
if ( amx_FindPublic(amx, sTemp , &iFunction) != AMX_ERR_NONE){
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",sTemp,plugin->getName() );
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
iFunction = registerSPForwardByName(amx, sTemp, FP_CELL, FP_DONE);
|
||||
if (iFunction==-1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", sTemp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1874,20 +1878,9 @@ static cell AMX_NATIVE_CALL pause(AMX *amx, cell *params) /* 3 param */
|
||||
|
||||
CPluginMngr::CPlugin *plugin = 0;
|
||||
|
||||
if ( flags & 2 ) { // pause function
|
||||
if (flags&4){ //look out side the plugin
|
||||
temp = get_amxstring(amx,params[3],0,ilen);
|
||||
plugin = g_plugins.findPlugin(temp);
|
||||
}
|
||||
else plugin = g_plugins.findPluginFast(amx);
|
||||
if ( !plugin ) return 0; // plugin not found
|
||||
temp = get_amxstring(amx,params[2],0,ilen);
|
||||
int err, index;
|
||||
if ((err = amx_FindPublic( plugin->getAMX(), temp , &index) )!= AMX_ERR_NONE){
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")", temp,plugin->getName() );
|
||||
return 0;
|
||||
}
|
||||
plugin->pauseFunction( index );
|
||||
if ( flags & 2 )
|
||||
{ // pause function
|
||||
AMXXLOG_Log("[AMXX] This usage of the native pause() has been deprecated!");
|
||||
return 1;
|
||||
}
|
||||
else if (flags&4){
|
||||
@ -1915,24 +1908,11 @@ static cell AMX_NATIVE_CALL unpause(AMX *amx, cell *params) /* 3 param */
|
||||
char* sptemp = get_amxstring(amx,params[1],0,ilen);
|
||||
int flags = UTIL_ReadFlags(sptemp);
|
||||
CPluginMngr::CPlugin *plugin = 0;
|
||||
if (flags&2) {
|
||||
if (flags&4){
|
||||
sptemp = get_amxstring(amx,params[3],0,ilen);
|
||||
plugin = g_plugins.findPlugin(sptemp);
|
||||
}
|
||||
else
|
||||
plugin = g_plugins.findPluginFast(amx);
|
||||
if ( !plugin ) return 0;
|
||||
sptemp = get_amxstring(amx,params[2],0,ilen);
|
||||
int err, index;
|
||||
if ((err = amx_FindPublic(plugin->getAMX(), sptemp , &index) )!= AMX_ERR_NONE){
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")", sptemp,plugin->getName() );
|
||||
return 0;
|
||||
}
|
||||
plugin->unpauseFunction( index );
|
||||
if (flags&2)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] This usage of the native pause() has been deprecated!");
|
||||
return 1;
|
||||
}
|
||||
else if (flags&4){
|
||||
} else if (flags&4) {
|
||||
sptemp = get_amxstring(amx,params[2],0,ilen);
|
||||
plugin = g_plugins.findPlugin(sptemp);
|
||||
}
|
||||
@ -2298,10 +2278,10 @@ static cell AMX_NATIVE_CALL register_logevent(AMX *amx, cell *params)
|
||||
|
||||
char* temp = get_amxstring(amx,params[1],0, a );
|
||||
|
||||
if (amx_FindPublic(amx, temp , &iFunc) != AMX_ERR_NONE){
|
||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",
|
||||
temp,plugin->getName() );
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
iFunc = registerSPForwardByName(amx, temp, FP_DONE);
|
||||
if (iFunc == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2457,31 +2437,22 @@ static cell AMX_NATIVE_CALL get_module(AMX *amx, cell *params)
|
||||
set_amxstring(amx, params[2], info && info->name ? info->name : "unk", params[3]);
|
||||
set_amxstring(amx, params[4], info && info->author ? info->author : "unk", params[5]);
|
||||
set_amxstring(amx, params[6], info && info->version ? info->version : "unk", params[7]);
|
||||
}
|
||||
else
|
||||
{
|
||||
module_info_s *info = (*moduleIter).getInfo();
|
||||
set_amxstring(amx, params[2], info && info->name ? info->name : "unk", params[3]);
|
||||
set_amxstring(amx, params[4], info && info->author ? info->author : "unk", params[5]);
|
||||
set_amxstring(amx, params[6], info && info->version ? info->version : "unk", params[7]);
|
||||
}
|
||||
|
||||
// compatibility problem possible
|
||||
int numParams = params[0] / sizeof(cell);
|
||||
if (numParams < 8)
|
||||
{
|
||||
CPluginMngr::CPlugin *curPlugin = g_plugins.findPluginFast(amx);
|
||||
AMXXLOG_Log("[AMXX] get_module: call to a previous version (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "Call to incompatible version");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set status
|
||||
cell *addr;
|
||||
if (amx_GetAddr(amx, params[8], &addr) != AMX_ERR_NONE)
|
||||
{
|
||||
CPluginMngr::CPlugin *curPlugin = g_plugins.findPluginFast(amx);
|
||||
AMXXLOG_Log("[AMXX] get_module: invalid reference (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid reference plugin");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*addr = (cell)(*moduleIter).getStatusValue();
|
||||
@ -2526,8 +2497,7 @@ static cell AMX_NATIVE_CALL callfunc_begin(AMX *amx, cell *params)
|
||||
if (g_CallFunc_Plugin)
|
||||
{
|
||||
// scripter's fault
|
||||
AMXXLOG_Log("[AMXX] callfunc_begin called without callfunc_end (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "callfunc_begin called without callfunc_end");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2608,8 +2578,7 @@ static cell AMX_NATIVE_CALL callfunc_end(AMX *amx, cell *params)
|
||||
if (!g_CallFunc_Plugin)
|
||||
{
|
||||
// scripter's fault
|
||||
AMXXLOG_Log("[AMXX] callfunc_end called without callfunc_begin (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "callfunc_end called without callfunc_begin");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2633,9 +2602,13 @@ static cell AMX_NATIVE_CALL callfunc_end(AMX *amx, cell *params)
|
||||
g_CallFunc_CurParam = 0;
|
||||
|
||||
// actual call
|
||||
if ((err = amx_Execv(plugin->getAMX(), &retVal, func, curParam, gparams)) != AMX_ERR_NONE)
|
||||
// Pawn - push parameters in reverse order
|
||||
for (int i=curParam-1; i>=0; i--)
|
||||
{
|
||||
amx_Push(amx, gparams[i]);
|
||||
}
|
||||
if ((err = amx_Exec(plugin->getAMX(), &retVal, func) != AMX_ERR_NONE))
|
||||
{
|
||||
LogError(amx, err, "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2672,8 +2645,7 @@ static cell AMX_NATIVE_CALL callfunc_push_byval(AMX *amx, cell *params)
|
||||
if (!g_CallFunc_Plugin)
|
||||
{
|
||||
// scripter's fault
|
||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx called without callfunc_begin (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx called without callfunc_begin");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2698,15 +2670,13 @@ static cell AMX_NATIVE_CALL callfunc_push_byref(AMX *amx, cell *params)
|
||||
if (!g_CallFunc_Plugin)
|
||||
{
|
||||
// scripter's fault
|
||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx called without callfunc_begin (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx called without callfunc_begin");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (g_CallFunc_CurParam == CALLFUNC_MAXPARAMS)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2756,15 +2726,13 @@ static cell AMX_NATIVE_CALL callfunc_push_str(AMX *amx, cell *params)
|
||||
if (!g_CallFunc_Plugin)
|
||||
{
|
||||
// scripter's fault
|
||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx called without callfunc_begin (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx called without callfunc_begin");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (g_CallFunc_CurParam == CALLFUNC_MAXPARAMS)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2799,7 +2767,7 @@ static cell AMX_NATIVE_CALL callfunc_push_str(AMX *amx, cell *params)
|
||||
// copy it to the allocated memory
|
||||
// we assume it's unpacked
|
||||
// :NOTE: 4th parameter use_wchar since Small Abstract Machine 2.5.0
|
||||
amx_SetString(phys_addr, str, 0, 0);
|
||||
amx_SetString(phys_addr, str, 0, 0, 0);
|
||||
|
||||
// push the address and set the reference flag so that memory is released after function call.
|
||||
g_CallFunc_ParamInfo[g_CallFunc_CurParam].flags = CALLFUNC_FLAG_BYREF;
|
||||
|
@ -68,7 +68,7 @@
|
||||
#include "amxxlog.h"
|
||||
|
||||
#define AMXXLOG_Log g_log.Log
|
||||
#define AMX_VERSION "1.10-RC1"
|
||||
#define AMX_VERSION "1.50-RC1"
|
||||
|
||||
extern AMX_NATIVE_INFO core_Natives[];
|
||||
extern AMX_NATIVE_INFO time_Natives[];
|
||||
@ -244,7 +244,6 @@ enum CountModulesMode
|
||||
int countModules(CountModulesMode mode);
|
||||
void modules_callPluginsLoaded();
|
||||
|
||||
int add_amxnatives(module_info_s* info,AMX_NATIVE_INFO*natives);
|
||||
cell* get_amxaddr(AMX *amx,cell amx_addr);
|
||||
char* build_pathname(char *fmt, ... );
|
||||
char* build_pathname_r(char *buffer, size_t maxlen, char *fmt, ...);
|
||||
@ -280,6 +279,7 @@ extern ModuleCallReason g_ModuleCallReason; // modules.cpp
|
||||
extern CModule *g_CurrentlyCalledModule; // modules.cpp
|
||||
extern const char *g_LastRequestedFunc; // modules.cpp
|
||||
void Module_CacheFunctions();
|
||||
void Module_UncacheFunctions();
|
||||
|
||||
void *Module_ReqFnptr(const char *funcName); // modules.cpp
|
||||
|
||||
@ -297,6 +297,7 @@ extern int FF_PluginLog;
|
||||
extern int FF_PluginEnd;
|
||||
extern int FF_InconsistentFile;
|
||||
extern int FF_ClientAuthorized;
|
||||
extern bool g_coloredmenus;
|
||||
|
||||
#ifdef FAKEMETA
|
||||
extern CFakeMeta g_FakeMeta;
|
||||
|
@ -364,19 +364,6 @@ static cell AMX_NATIVE_CALL amx_fclose(AMX *amx, cell *params)
|
||||
}
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
FILE *fp = FileList.at(id);
|
||||
if (fp) {
|
||||
return fgetc(fp);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
@ -394,6 +381,20 @@ static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef UNUSED
|
||||
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
FILE *fp = FileList.at(id);
|
||||
if (fp) {
|
||||
return fgetc(fp);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fwrite(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
@ -506,6 +507,7 @@ static cell AMX_NATIVE_CALL amx_ftell(AMX *amx, cell *params)
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif //UNUSED
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
|
||||
{
|
||||
@ -521,6 +523,7 @@ static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef UNUSED
|
||||
static cell AMX_NATIVE_CALL amx_fgetl(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
@ -636,6 +639,7 @@ static cell AMX_NATIVE_CALL amx_fputf(AMX *amx, cell *params)
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif //UNUSED
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_build_pathname(AMX *amx, cell *params)
|
||||
{
|
||||
@ -723,8 +727,10 @@ AMX_NATIVE_INFO file_Natives[] = {
|
||||
//Sanji's File Natives
|
||||
{ "fopen", amx_fopen },
|
||||
{ "fclose", amx_fclose },
|
||||
{ "fgetc", amx_fgetc },
|
||||
{ "fread", amx_fread },
|
||||
{ "filesize", amx_filesize },
|
||||
#ifdef UNUSED
|
||||
{ "fgetc", amx_fgetc },
|
||||
{ "fwrite", amx_fwrite },
|
||||
{ "feof", amx_feof },
|
||||
{ "fseek", amx_fseek },
|
||||
@ -733,16 +739,16 @@ AMX_NATIVE_INFO file_Natives[] = {
|
||||
{ "fflush", amx_fflush },
|
||||
{ "fscanf", amx_fscanf },
|
||||
{ "ftell", amx_ftell },
|
||||
{ "filesize", amx_filesize },
|
||||
{ "fgetl", amx_fgetl },
|
||||
{ "fgeti", amx_fgeti },
|
||||
{ "fgets", amx_fgets },
|
||||
{ "fputs", amx_fputs },
|
||||
{ "fputl", amx_fputl },
|
||||
{ "fputi", amx_fputi },
|
||||
{ "unlink", delete_file },
|
||||
{ "fgetf", amx_fgetf },
|
||||
{ "fputf", amx_fputf },
|
||||
#endif
|
||||
{ "unlink", delete_file },
|
||||
{ "build_pathname", amx_build_pathname},
|
||||
{ "dir_exists", dir_exists },
|
||||
{ "open_dir", amx_open_dir },
|
||||
|
@ -96,7 +96,7 @@ static cell AMX_NATIVE_CALL n_floatstr(AMX *amx,cell *params)
|
||||
return 0;
|
||||
|
||||
/* Now convert the Small String into a C type null terminated string */
|
||||
amx_GetString(szSource, pString, 0);
|
||||
amx_GetStringOld(szSource, pString, 0);
|
||||
|
||||
/* Now convert this to a float. */
|
||||
fNum = (REAL)atof(szSource);
|
||||
|
@ -90,6 +90,7 @@ float g_auth_time;
|
||||
bool g_initialized = false;
|
||||
bool g_IsNewMM = false;
|
||||
bool g_NeedsP = false;
|
||||
bool g_coloredmenus;
|
||||
|
||||
#ifdef MEMORY_TEST
|
||||
float g_next_memreport_time;
|
||||
@ -605,7 +606,6 @@ void C_ClientCommand( edict_t *pEntity ) {
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
|
||||
META_RES result = MRES_IGNORED;
|
||||
cell ret = 0;
|
||||
int err;
|
||||
const char* cmd = CMD_ARGV(0);
|
||||
const char* arg = CMD_ARGV(1);
|
||||
|
||||
@ -665,10 +665,7 @@ void C_ClientCommand( edict_t *pEntity ) {
|
||||
if ( (*aa).matchCommandLine( cmd , arg ) &&
|
||||
(*aa).getPlugin()->isExecutable( (*aa).getFunction() ) )
|
||||
{
|
||||
|
||||
if ((err =amx_Exec((*aa).getPlugin()->getAMX(), &ret , (*aa).getFunction() , 3, pPlayer->index, (*aa).getFlags(),(*aa).getId() )) != AMX_ERR_NONE)
|
||||
LogError((*aa).getPlugin()->getAMX(), err, "");
|
||||
|
||||
ret = executeForwards((*aa).getFunction(), pPlayer->index, (*aa).getFlags(), (*aa).getId());
|
||||
if ( ret & 2 ) result = MRES_SUPERCEDE;
|
||||
if ( ret & 1 ) RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
@ -695,33 +692,19 @@ void C_ClientCommand( edict_t *pEntity ) {
|
||||
int menuid = pPlayer->menu;
|
||||
pPlayer->menu = 0;
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
try{
|
||||
#endif
|
||||
MenuMngr::iterator a = g_menucmds.begin();
|
||||
|
||||
while( a )
|
||||
{
|
||||
if ( (*a).matchCommand( menuid , bit_key ) && (*a).getPlugin()->isExecutable( (*a).getFunction() ) )
|
||||
{
|
||||
|
||||
if ( ( err = amx_Exec((*a).getPlugin()->getAMX(), &ret ,(*a).getFunction() , 2, pPlayer->index,pressed_key)) != AMX_ERR_NONE)
|
||||
LogError((*a).getPlugin()->getAMX(), err, "");
|
||||
|
||||
ret = executeForwards((*a).getFunction(), pPlayer->index, pressed_key);
|
||||
if ( ret & 2 ) result = MRES_SUPERCEDE;
|
||||
if ( ret & 1 ) RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
++a;
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
AMXXLOG_Log( "[AMXX] Fatal error at menu commmand execution");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/* check for PLUGIN_HANDLED_MAIN and block hl call if needed */
|
||||
@ -898,35 +881,6 @@ void C_WriteEntity_Post(int iValue) {
|
||||
}
|
||||
void C_MessageEnd_Post(void) {
|
||||
g_events.executeEvents();
|
||||
|
||||
#if 0 // ######### this is done by call above
|
||||
EventsMngr::iterator a = g_events.begin();
|
||||
int err;
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
|
||||
while ( a )
|
||||
{
|
||||
|
||||
if ((err = amx_Exec((*a).getPlugin()->getAMX(), NULL , (*a).getFunction() , 1, mPlayerIndex /*g_events.getArgInteger(0)*/ )) != AMX_ERR_NONE)
|
||||
LogError((*a).getPlugin()->getAMX(), err, "");
|
||||
|
||||
|
||||
++a;
|
||||
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
AMXXLOG_Log( "[AMXX] Fatal error at event execution");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (endfunction) (*endfunction)(NULL);
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
@ -1134,6 +1088,13 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
|
||||
a = &gameDir[i];
|
||||
g_mod_name.assign(a);
|
||||
|
||||
if (g_mod_name.compare("cstrike")==0 ||
|
||||
g_mod_name.compare("czero")==0 ||
|
||||
g_mod_name.compare("dod")==0)
|
||||
g_coloredmenus = true;
|
||||
else
|
||||
g_coloredmenus = false;
|
||||
|
||||
// ###### Print short GPL
|
||||
print_srvconsole( "\n AMX Mod X version %s Copyright (c) 2004-2005 AMX Mod X Development Team \n"
|
||||
" AMX Mod X comes with ABSOLUTELY NO WARRANTY; for details type `amxx gpl'.\n", AMX_VERSION);
|
||||
@ -1194,6 +1155,8 @@ C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) {
|
||||
|
||||
g_log.CloseFile();
|
||||
|
||||
Module_UncacheFunctions();
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ void free_amxmemory(void **ptr)
|
||||
int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug)
|
||||
{
|
||||
*error = 0;
|
||||
CAmxxReader reader(filename, SMALL_CELL_SIZE / 8);
|
||||
CAmxxReader reader(filename, PAWN_CELL_SIZE / 8);
|
||||
if (reader.GetStatus() == CAmxxReader::Err_None)
|
||||
{
|
||||
size_t bufSize = reader.GetBufferSize();
|
||||
@ -153,59 +153,72 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
||||
return (amx->error = AMX_ERR_FORMAT);
|
||||
}
|
||||
|
||||
if ( (int)CVAR_GET_FLOAT("amx_debug") >= 2 || debug)
|
||||
{
|
||||
//automatic debug mode
|
||||
hdr->flags |= AMX_FLAG_LINEOPS;
|
||||
hdr->flags |= AMX_FLAG_DEBUG;
|
||||
}
|
||||
|
||||
int err;
|
||||
memset(amx, 0, sizeof(*amx));
|
||||
|
||||
if ((int)CVAR_GET_FLOAT("amx_debug") >= 2 || debug)
|
||||
{
|
||||
if ((amx->flags & AMX_FLAG_DEBUG) != 0)
|
||||
{
|
||||
//:TODO: debug support
|
||||
}
|
||||
} else {
|
||||
#ifdef JIT
|
||||
//if (hdr->file_version == CUR_FILE_VERSION)
|
||||
amx->flags |= AMX_FLAG_JITC;
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((err = amx_Init( amx, *program )) != AMX_ERR_NONE)
|
||||
{
|
||||
sprintf(error,"Load error %d (invalid file format or version)", err);
|
||||
return (amx->error = AMX_ERR_INIT);
|
||||
}
|
||||
|
||||
#ifdef JIT
|
||||
void *np = new char[ amx->code_size ];
|
||||
void *rt = new char[ amx->reloc_size ];
|
||||
if ( !np || (!rt && amx->reloc_size > 0) )
|
||||
{
|
||||
delete[] np;
|
||||
delete[] rt;
|
||||
strcpy(error,"Failed to initialize plugin");
|
||||
return (amx->error = AMX_ERR_INIT);
|
||||
}
|
||||
LOG_MESSAGE(PLID, "AMX: %p FLAGS: %d\n", amx, amx->flags);
|
||||
|
||||
if ( (err = amx_InitJIT(amx, rt, np)) == AMX_ERR_NONE )
|
||||
#ifdef JIT
|
||||
if (amx->flags & AMX_FLAG_JITC)
|
||||
{
|
||||
//amx->base = (unsigned char FAR *)realloc( np, amx->code_size );
|
||||
#ifndef __linux__
|
||||
amx->base = new unsigned char[ amx->code_size ];
|
||||
#else
|
||||
//posix_memalign((void **)&(amx->base), sysconf(_SC_PAGESIZE), amx->code_size);
|
||||
amx->base = (unsigned char *)memalign(sysconf(_SC_PAGESIZE), amx->code_size);
|
||||
mprotect((void *)amx->base, amx->code_size, PROT_READ|PROT_WRITE|PROT_EXEC);
|
||||
#endif
|
||||
if ( amx->base )
|
||||
memcpy( amx->base , np , amx->code_size );
|
||||
delete[] np;
|
||||
delete[] rt;
|
||||
delete[] *program;
|
||||
(*program) = amx->base;
|
||||
if ( *program == 0 ){
|
||||
strcpy(error,"Failed to allocate memory");
|
||||
return (amx->error = AMX_ERR_MEMORY);
|
||||
char *np = new char[ amx->code_size ];
|
||||
char *rt = new char[ amx->reloc_size ];
|
||||
if ( !np || (!rt && amx->reloc_size > 0) )
|
||||
{
|
||||
delete[] np;
|
||||
delete[] rt;
|
||||
strcpy(error,"Failed to initialize plugin");
|
||||
return (amx->error = AMX_ERR_INIT);
|
||||
}
|
||||
|
||||
if ( (err = amx_InitJIT(amx, (void *)rt, (void *)np)) == AMX_ERR_NONE )
|
||||
{
|
||||
//amx->base = (unsigned char FAR *)realloc( np, amx->code_size );
|
||||
#ifndef __linux__
|
||||
amx->base = new unsigned char[ amx->code_size ];
|
||||
#else
|
||||
//posix_memalign((void **)&(amx->base), sysconf(_SC_PAGESIZE), amx->code_size);
|
||||
amx->base = (unsigned char *)memalign(sysconf(_SC_PAGESIZE), amx->code_size);
|
||||
mprotect((void *)amx->base, amx->code_size, PROT_READ|PROT_WRITE|PROT_EXEC);
|
||||
#endif
|
||||
if ( amx->base )
|
||||
memcpy( amx->base , np , amx->code_size );
|
||||
delete[] np;
|
||||
delete[] rt;
|
||||
char *prg = (char *)(*program);
|
||||
delete[] *prg;
|
||||
(*program) = amx->base;
|
||||
if ( *program == 0 ){
|
||||
strcpy(error,"Failed to allocate memory");
|
||||
return (amx->error = AMX_ERR_MEMORY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
delete[] np;
|
||||
delete[] rt;
|
||||
sprintf(error, "Failed to initialize plugin (%d)", err);
|
||||
return (amx->error = AMX_ERR_INIT_JIT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
delete[] np;
|
||||
delete[] rt;
|
||||
sprintf(error, "Failed to initialize plugin (%d)", err);
|
||||
return (amx->error = AMX_ERR_INIT_JIT);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -219,7 +232,6 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
||||
}
|
||||
|
||||
g_loadedscripts.put( aa );
|
||||
amx->sysreq_d = 0;
|
||||
return set_amxnatives(amx,error);
|
||||
}
|
||||
|
||||
@ -345,7 +357,8 @@ int unload_amxscript(AMX* amx, void** program)
|
||||
{
|
||||
CList<CScript,AMX*>::iterator a = g_loadedscripts.find( amx );
|
||||
if ( a ) a.remove();
|
||||
delete[] *program;
|
||||
char *prg = (char *)*program;
|
||||
delete[] *prg;
|
||||
*program = 0;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
@ -469,27 +482,6 @@ char* build_pathname_addons(char *fmt, ... )
|
||||
return string;
|
||||
}
|
||||
|
||||
int add_amxnatives(module_info_s* info,AMX_NATIVE_INFO*natives)
|
||||
{
|
||||
CList<CModule,const char *>::iterator a = g_modules.begin();
|
||||
|
||||
while ( a )
|
||||
{
|
||||
if ( (*a).getInfo() == info )
|
||||
{
|
||||
AMX_NATIVE_INFO** aa = new AMX_NATIVE_INFO*(natives);
|
||||
if ( aa == 0 ) return AMX_ERR_NATIVE;
|
||||
(*a).m_Natives.put( aa );
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
++a;
|
||||
}
|
||||
|
||||
return AMX_ERR_NATIVE;
|
||||
}
|
||||
|
||||
|
||||
bool validFile(const char* file)
|
||||
{
|
||||
const char* a = 0;
|
||||
@ -505,7 +497,7 @@ bool validFile(const char* file)
|
||||
|
||||
void ConvertModuleName(const char *pathString, String &path)
|
||||
{
|
||||
#if SMALL_CELL_SIZE==64
|
||||
#if PAWN_CELL_SIZE==64
|
||||
char *ptr = strstr(pathString, "i386");
|
||||
if (ptr)
|
||||
{
|
||||
@ -600,7 +592,7 @@ void ConvertModuleName(const char *pathString, String &path)
|
||||
}
|
||||
}
|
||||
#endif //__linux__
|
||||
#endif //SMALL_CELL_SIZE==64
|
||||
#endif //PAWN_CELL_SIZE==64
|
||||
}
|
||||
|
||||
int loadModules(const char* filename, PLUG_LOADTIME now)
|
||||
@ -930,10 +922,14 @@ int MNF_AddNatives(AMX_NATIVE_INFO* natives)
|
||||
|
||||
const char *MNF_GetModname(void)
|
||||
{
|
||||
// :TODO: Do we have to do this??
|
||||
// :TODO: Do we have to do this??
|
||||
// I dunno who wrote the above comment but no
|
||||
#if 0
|
||||
static char buffer[64];
|
||||
strcpy(buffer, g_mod_name.c_str());
|
||||
return buffer;
|
||||
#endif
|
||||
return g_mod_name.c_str();
|
||||
}
|
||||
|
||||
AMX *MNF_GetAmxScript(int id)
|
||||
@ -1169,13 +1165,17 @@ REAL MNF_CellToReal(cell x)
|
||||
return *(REAL*)&x;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
#define _vsnprintf vsnprintf
|
||||
#endif
|
||||
|
||||
void MNF_Log(const char *fmt, ...)
|
||||
{
|
||||
// :TODO: Overflow possible here
|
||||
char msg[3072];
|
||||
va_list arglst;
|
||||
va_start(arglst, fmt);
|
||||
vsprintf(msg, fmt, arglst);
|
||||
_vsnprintf(msg, sizeof(msg)-1, fmt, arglst);
|
||||
//vsprintf(msg, fmt, arglst);
|
||||
va_end(arglst);
|
||||
AMXXLOG_Log("%s", msg);
|
||||
}
|
||||
@ -1220,7 +1220,7 @@ void GenericError(AMX *amx, int err, int line, char buf[], const char *file)
|
||||
geterr = NULL;
|
||||
else
|
||||
geterr = amx_errs[err];
|
||||
if (!(amx->flags & AMX_FLAG_LINEOPS))
|
||||
if (!(amx->flags & AMX_FLAG_DEBUG))
|
||||
{
|
||||
if (geterr == NULL)
|
||||
{
|
||||
@ -1250,7 +1250,7 @@ void LogError(AMX *amx, int err, const char *fmt, ...)
|
||||
{
|
||||
//does this plugin have debug info?
|
||||
va_list arg;
|
||||
AMX_DBG *dbg = (AMX_DBG *)(amx->userdata[0]);
|
||||
//AMX_DBG *dbg = (AMX_DBG *)(amx->userdata[0]);
|
||||
static char buf[1024];
|
||||
static char vbuf[1024];
|
||||
*buf = 0;
|
||||
@ -1259,7 +1259,7 @@ void LogError(AMX *amx, int err, const char *fmt, ...)
|
||||
va_start(arg, fmt);
|
||||
vsprintf(vbuf, fmt, arg);
|
||||
va_end(arg);
|
||||
|
||||
#if 0
|
||||
if (!dbg || !(dbg->tail))
|
||||
{
|
||||
if (dbg && amx->curfile < dbg->numFiles && amx->curfile >= 0)
|
||||
@ -1313,6 +1313,8 @@ void LogError(AMX *amx, int err, const char *fmt, ...)
|
||||
t = dbg->tail;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
amx_RaiseError(amx, err);
|
||||
}
|
||||
|
||||
void MNF_MergeDefinitionFile(const char *file)
|
||||
@ -1386,7 +1388,7 @@ const char *g_LastRequestedFunc = NULL;
|
||||
#define REGISTER_FUNC(name, func) \
|
||||
{ \
|
||||
pFunc = new func_s; \
|
||||
pFunc->pfn = func; \
|
||||
pFunc->pfn = (void *)func; \
|
||||
pFunc->desc = name; \
|
||||
g_functions.put(pFunc); \
|
||||
}
|
||||
@ -1398,6 +1400,16 @@ void MNF_RegisterFunction(void *pfn, const char *description)
|
||||
REGISTER_FUNC(description, pfn);
|
||||
}
|
||||
|
||||
void Module_UncacheFunctions()
|
||||
{
|
||||
g_functions.clear();
|
||||
}
|
||||
|
||||
int amx_Execv()
|
||||
{
|
||||
return AMX_ERR_NOTFOUND;
|
||||
}
|
||||
|
||||
void Module_CacheFunctions()
|
||||
{
|
||||
func_s *pFunc;
|
||||
@ -1430,7 +1442,7 @@ void Module_CacheFunctions()
|
||||
|
||||
// other amx stuff
|
||||
REGISTER_FUNC("amx_Exec", amx_Exec)
|
||||
REGISTER_FUNC("amx_Execv", amx_Execv)
|
||||
REGISTER_FUNC("amx_Execv", amx_Execv) //I HOPE NO ONE USES THIS!!!!
|
||||
REGISTER_FUNC("amx_Allot", amx_Allot)
|
||||
REGISTER_FUNC("amx_FindPublic", amx_FindPublic)
|
||||
REGISTER_FUNC("amx_FindNative", amx_FindNative)
|
||||
|
@ -45,135 +45,8 @@
|
||||
#undef C_DLLEXPORT
|
||||
#define C_DLLEXPORT extern "C" DLLEXPORT
|
||||
|
||||
#define AMX_INTERFACE_VERSION 6
|
||||
|
||||
#define RELOAD_MODULE 0
|
||||
#define STATIC_MODULE 1
|
||||
|
||||
struct module_info_s {
|
||||
const char* name;
|
||||
const char* author;
|
||||
const char* version;
|
||||
int ivers;
|
||||
int type;
|
||||
long int serial;
|
||||
};
|
||||
|
||||
// Small scripting language
|
||||
struct pfnamx_engine_g {
|
||||
uint16_t* (*pfnamx_Align16)(uint16_t *); // value
|
||||
uint32_t* (*pfnamx_Align32)(uint32_t *); // value
|
||||
int (*pfnamx_Allot)(AMX*, int, cell*, cell**); // amx, length, amx_addr, phys_addr
|
||||
int (*pfnamx_Callback)(AMX*, cell , cell*, cell*); // amx, index,result,params
|
||||
int (*pfnamx_Clone)(AMX*, AMX*, void*); // amxClone, amxSrc, data
|
||||
int (*pfnamx_Debug)(AMX*); // default debug procedure, does nothing // amx
|
||||
int (*pfnamx_Exec)(AMX*, cell*, int , int , ...); // amx, return val, index, num_params, ...
|
||||
int (*pfnamx_Execv)(AMX*, cell*, int , int, cell[]); // amx, return val, index, num_params, param[]
|
||||
int (*pfnamx_FindPublic)(AMX*, char*, int*); // amx, func name, index
|
||||
int (*pfnamx_FindPubVar)(AMX*, char*, cell*); // anx, var name, amx_addr
|
||||
int (*pfnamx_FindTagId)(AMX*, cell , char*); // amx. tag_id, tagname
|
||||
int (*pfnamx_Flags)(AMX*,uint16_t *); // amx, flags
|
||||
int (*pfnamx_GetAddr)(AMX*,cell ,cell**); // amx, amx_addr, phys_addr
|
||||
int (*pfnamx_GetPublic)(AMX*, int , char*); // amx, index, funcname
|
||||
int (*pfnamx_GetPubVar)(AMX*, int , char*, cell*); // amx, index, varname, amx_addr
|
||||
int (*pfnamx_GetString)(char*dest,cell*); // dest, source
|
||||
int (*pfnamx_GetTag)(AMX*, int , char*, cell*); // amx, index, tagname, tag_id
|
||||
int (*pfnamx_GetUserData)(AMX*, long , void **); // amx, tag, ptr
|
||||
int (*pfnamx_Init)(AMX*, void *); // amx, program
|
||||
int (*pfnamx_InitJIT)(AMX*, void *, void *); // amx, reloc_table, native_code
|
||||
int (*pfnamx_MemInfo)(AMX*, long*, long*, long*); // amx, codesize, datasize, stackheap
|
||||
int (*pfnamx_NameLength)(AMX*, int*); // amx, length
|
||||
AMX_NATIVE_INFO * (*pfnamx_NativeInfo)(char*,AMX_NATIVE ); // name, func
|
||||
int (*pfnamx_NumPublics)(AMX*, int*); // amx, number
|
||||
int (*pfnamx_NumPubVars)(AMX*, int*); // amx, number
|
||||
int (*pfnamx_NumTags)(AMX*, int*); // amx, number
|
||||
int (*pfnamx_RaiseError)(AMX*, int ); // amx, error
|
||||
int (*pfnamx_Register)(AMX*, AMX_NATIVE_INFO*, int ); // amx, nativelist, number
|
||||
int (*pfnamx_Release)(AMX*, cell ); // amx, amx_addr
|
||||
int (*pfnamx_SetCallback)(AMX*, AMX_CALLBACK ); // amx, callback
|
||||
int (*pfnamx_SetDebugHook)(AMX*, AMX_DEBUG ); // amx, debug
|
||||
int (*pfnamx_SetString)(cell*, char*, int ); // dest, source, pack
|
||||
int (*pfnamx_SetUserData)(AMX*, long , void*); // amx, tag, prt
|
||||
int (*pfnamx_StrLen)(cell*, int*); // amx, cstring, length
|
||||
};
|
||||
extern pfnamx_engine_g* g_engAmxFunc;
|
||||
|
||||
#define AMX_ALIGN16 (*g_engAmxFunc->pfnamx_Align16)
|
||||
#define AMX_ALIGN32 (*g_engAmxFunc->pfnamx_Align32)
|
||||
#define AMX_ALLOT (*g_engAmxFunc->pfnamx_Allot)
|
||||
#define AMX_CALLBACK (*g_engAmxFunc->pfnamx_Callback)
|
||||
#define AMX_CLONE (*g_engAmxFunc->pfnamx_Clone)
|
||||
#define AMX_DEBUG (*g_engAmxFunc->pfnamx_Debug)
|
||||
#define AMX_EXEC (*g_engAmxFunc->pfnamx_Exec)
|
||||
#define AMX_EXECV (*g_engAmxFunc->pfnamx_Execv)
|
||||
#define AMX_FINDPUBLIC (*g_engAmxFunc->pfnamx_FindPublic)
|
||||
#define AMX_FINDPUBVAR (*g_engAmxFunc->pfnamx_FindPubVar)
|
||||
#define AMX_FINDTAGID (*g_engAmxFunc->pfnamx_FindTagId)
|
||||
#define AMX_FLAGS (*g_engAmxFunc->pfnamx_Flags)
|
||||
#define AMX_GETADDR (*g_engAmxFunc->pfnamx_GetAddr)
|
||||
#define AMX_GETPUBLIC (*g_engAmxFunc->pfnamx_GetPublic)
|
||||
#define AMX_GETPUBVAR (*g_engAmxFunc->pfnamx_GetPubVar)
|
||||
#define AMX_GETSTRING (*g_engAmxFunc->pfnamx_GetString)
|
||||
#define AMX_GETTAG (*g_engAmxFunc->pfnamx_GetTag)
|
||||
#define AMX_GETUSERDATA (*g_engAmxFunc->pfnamx_GetUserData)
|
||||
#define AMX_INIT (*g_engAmxFunc->pfnamx_Init)
|
||||
#define AMX_INITJIT (*g_engAmxFunc->pfnamx_InitJIT)
|
||||
#define AMX_MEMINFO (*g_engAmxFunc->pfnamx_MemInfo)
|
||||
#define AMX_NAMELENGTH (*g_engAmxFunc->pfnamx_NameLength)
|
||||
#define AMX_NATIVEINFO (*g_engAmxFunc->pfnamx_NativeInfo)
|
||||
#define AMX_NUMPUBLICS (*g_engAmxFunc->pfnamx_NumPublics)
|
||||
#define AMX_NUMPUBVARS (*g_engAmxFunc->pfnamx_NumPubVars)
|
||||
#define AMX_NUMTAGS (*g_engAmxFunc->pfnamx_NumTags)
|
||||
#define AMX_RAISEERROR (*g_engAmxFunc->pfnamx_RaiseError)
|
||||
#define AMX_REGISTER (*g_engAmxFunc->pfnamx_Register)
|
||||
#define AMX_RELEASE (*g_engAmxFunc->pfnamx_Release)
|
||||
#define AMX_SETCALLBACK (*g_engAmxFunc->pfnamx_SetCallback)
|
||||
#define AMX_SETDEBUGHOOK (*g_engAmxFunc->pfnamx_SetDebugHook)
|
||||
#define AMX_SETSTRING (*g_engAmxFunc->pfnamx_SetString)
|
||||
#define AMX_SETUSERDATA (*g_engAmxFunc->pfnamx_SetUserData)
|
||||
#define AMX_STRLEN (*g_engAmxFunc->pfnamx_StrLen)
|
||||
|
||||
// Modules API
|
||||
struct pfnmodule_engine_g {
|
||||
int (*pfnadd_amxnatives)(module_info_s*,AMX_NATIVE_INFO*); // list
|
||||
char* (*pfnbuild_pathname)(char*, ...); // format, ....
|
||||
void (*pfncopy_amxmemory)(cell*,cell*,int); // dest, src, len
|
||||
char* (*pfnformat_amxstring)(AMX*, cell*, int ,int& ); // amx, format, start pos, len
|
||||
cell* (*pfnget_amxaddr)(AMX*,cell ); // amx, cell
|
||||
AMX* (*pfnget_amxscript)(int, void**,const char**); // id, code, name
|
||||
const char* (*pfnget_amxscriptname)(AMX* amx); // amx
|
||||
char* (*pfnget_amxstring)(AMX*,cell,int, int&); // amx, src, buffer (0-3), len
|
||||
void (*pfnget_modname)(char*); // modname
|
||||
int (*pfnload_amxscript)(AMX*, void**, const char*, char[64], int); // amx, code, path, error info
|
||||
void (*pfnprint_console)(char*, ...); // format, ....
|
||||
void (*pfnreport_error)(int code, char*, ... );
|
||||
int (*pfnset_amxnatives)(AMX*,char[64]); // amx, error info
|
||||
int (*pfnset_amxstring)(AMX*,cell ,const char*,int); // amx, dest, string, maxlen
|
||||
int (*pfnamxstring_length)(cell*); // src
|
||||
int (*pfnunload_amxscript)(AMX* amx,void**); // amx, code
|
||||
void* (*pfnalloc_amxmemory)(void**,int size);
|
||||
void (*pfnfree_amxmemory)(void**);
|
||||
};
|
||||
extern pfnmodule_engine_g* g_engModuleFunc;
|
||||
|
||||
#define ADD_AMXNATIVES (*g_engModuleFunc->pfnadd_amxnatives)
|
||||
#define AMXSTRING_LENGTH (*g_engModuleFunc->pfnamxstring_length)
|
||||
#define BUILD_PATHNAME (*g_engModuleFunc->pfnbuild_pathname)
|
||||
#define COPY_AMXMEMORY (*g_engModuleFunc->pfncopy_amxmemory)
|
||||
#define FORMAT_AMXSTRING (*g_engModuleFunc->pfnformat_amxstring)
|
||||
#define GET_AMXADDR (*g_engModuleFunc->pfnget_amxaddr)
|
||||
#define GET_AMXSCRIPT (*g_engModuleFunc->pfnget_amxscript)
|
||||
#define GET_AMXSCRIPTNAME (*g_engModuleFunc->pfnget_amxscriptname)
|
||||
#define GET_AMXSTRING (*g_engModuleFunc->pfnget_amxstring)
|
||||
#define GET_MODNAME (*g_engModuleFunc->pfnget_modname)
|
||||
#define LOAD_AMXSCRIPT (*g_engModuleFunc->pfnload_amxscript)
|
||||
#define PRINT_CONSOLE (*g_engModuleFunc->pfnprint_console)
|
||||
#define REPORT_ERROR (*g_engModuleFunc->pfnreport_error)
|
||||
#define SET_AMXNATIVES (*g_engModuleFunc->pfnset_amxnatives)
|
||||
#define SET_AMXSTRING (*g_engModuleFunc->pfnset_amxstring)
|
||||
#define UNLOAD_AMXSCRIPT (*g_engModuleFunc->pfnunload_amxscript)
|
||||
#define ALLOC_AMXMEMORY (*g_engModuleFunc->pfnalloc_amxmemory)
|
||||
#define FREE_AMXMEMORY (*g_engModuleFunc->pfnfree_amxmemory)
|
||||
|
||||
|
||||
#endif // __MODULES_H__
|
||||
|
@ -300,7 +300,7 @@
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared";"C:\Hry\Half-Life\SDK\Multiplayer Source\dlls";"C:\Hry\Half-Life\SDK\Multiplayer Source\engine";"C:\Hry\Half-Life\SDK\Multiplayer Source\common";C:\Files\Programming\metamod\metamod"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
StructMemberAlignment="3"
|
||||
@ -319,7 +319,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="..\jit\jits.obj ..\zlib\zlib.lib"
|
||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj"
|
||||
OutputFile="jitdebug/amxmodx_mm.dll"
|
||||
Version="0.1"
|
||||
LinkIncremental="1"
|
||||
@ -371,7 +371,8 @@
|
||||
InlineFunctionExpansion="1"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32"
|
||||
IgnoreStandardIncludePath="FALSE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
@ -389,7 +390,7 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="..\jit\jits.obj ..\zlib\zlib.lib"
|
||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj"
|
||||
OutputFile="jitrelease/amxmodx_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
@ -649,6 +650,9 @@
|
||||
<File
|
||||
RelativePath="..\md5.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\menus.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\meta_api.cpp">
|
||||
</File>
|
||||
@ -780,6 +784,9 @@
|
||||
<File
|
||||
RelativePath="..\md5.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\menus.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\modules.h">
|
||||
</File>
|
||||
|
@ -150,14 +150,14 @@ void amx_command(){
|
||||
print_srvconsole( "%s %s\n", Plugin_info.name, Plugin_info.version);
|
||||
print_srvconsole( "Authors: %s (%s)\n", "Felix \"SniperBeamer\" Geyer, David \"BAILOPAN\" Anderson, Pavol \"PM OnoTo\" Marko, Jonny \"Got His Gun\" Bergstrom, and Lukasz \"SidLuke\" Wlasinski.", Plugin_info.url);
|
||||
print_srvconsole( "Compiled: %s\n", __DATE__ ", " __TIME__);
|
||||
#ifdef JIT
|
||||
print_srvconsole( "Core mode: JIT\n");
|
||||
#if defined JIT && !defined ASM32
|
||||
print_srvconsole( "Core mode: JIT Only\n");
|
||||
#elif !defined JIT && defined ASM32
|
||||
print_srvconsole( "Core mode: ASM32 Only\n");
|
||||
#elif defined JIT && defined ASM32
|
||||
print_srvconsole( "Core mode: JIT+ASM32\n");
|
||||
#else
|
||||
#ifdef ASM32
|
||||
print_srvconsole( "Core mode: ASM\n");
|
||||
#else
|
||||
print_srvconsole( "Core mode: Normal\n");
|
||||
#endif
|
||||
print_srvconsole( "Core mode: Normal\n");
|
||||
#endif
|
||||
}
|
||||
else if (!strcmp(cmd,"modules"))
|
||||
@ -264,39 +264,19 @@ void amx_command(){
|
||||
|
||||
void plugin_srvcmd()
|
||||
{
|
||||
|
||||
cell ret = 0;
|
||||
int err;
|
||||
const char* cmd = CMD_ARGV(0);
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
try{
|
||||
#endif
|
||||
cell ret = 0;
|
||||
const char* cmd = CMD_ARGV(0);
|
||||
|
||||
CmdMngr::iterator a = g_commands.srvcmdbegin();
|
||||
|
||||
while ( a )
|
||||
{
|
||||
if ( (*a).matchCommand( cmd ) &&
|
||||
(*a).getPlugin()->isExecutable( (*a).getFunction() ) )
|
||||
{
|
||||
|
||||
if ((err = amx_Exec( (*a).getPlugin()->getAMX(), &ret , (*a).getFunction()
|
||||
, 3 , g_srvindex , (*a).getFlags() , (*a).getId() )) != AMX_ERR_NONE)
|
||||
{
|
||||
LogError((*a).getPlugin()->getAMX(), err, "");
|
||||
}
|
||||
if ( ret ) break;
|
||||
}
|
||||
|
||||
++a;
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
}catch( ... )
|
||||
CmdMngr::iterator a = g_commands.srvcmdbegin();
|
||||
|
||||
while ( a )
|
||||
{
|
||||
if ( (*a).matchCommand( cmd ) &&
|
||||
(*a).getPlugin()->isExecutable( (*a).getFunction() ) )
|
||||
{
|
||||
AMXXLOG_Log( "[AMXX] fatal error at forward function execution");
|
||||
cell ret = executeForwards((*a).getFunction(), g_srvindex, (*a).getFlags(), (*a).getId());
|
||||
if ( ret ) break;
|
||||
}
|
||||
#endif
|
||||
|
||||
++a;
|
||||
}
|
||||
}
|
||||
|
@ -471,7 +471,7 @@ static cell AMX_NATIVE_CALL amx_strtok(AMX *amx, cell *params)
|
||||
char token = params[6];
|
||||
//trim
|
||||
int trim = params[7];
|
||||
for (i=0; i<len; i++)
|
||||
for (i=0; i<(unsigned int)len; i++)
|
||||
{
|
||||
if (trim && !done_flag)
|
||||
{
|
||||
@ -521,7 +521,7 @@ static cell AMX_NATIVE_CALL strbreak(AMX *amx, cell *params) /* 5 param */
|
||||
int LeftMax = params[3];
|
||||
int RightMax = params[5];
|
||||
|
||||
for (i=0; i<l; i++) {
|
||||
for (i=0; i<(unsigned int)l; i++) {
|
||||
if (string[i] == '"' && !quote_flag) {
|
||||
quote_flag = true;
|
||||
} else if (string[i] == '"' && quote_flag) {
|
||||
@ -603,6 +603,14 @@ static cell AMX_NATIVE_CALL amx_ucfirst(AMX *amx, cell *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_strlen(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *str = get_amxstring(amx, params[1], 0, len);
|
||||
|
||||
return strlen(str);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_trim(AMX *amx, cell *params)
|
||||
{
|
||||
cell *asdf = get_amxaddr(amx, params[1]);
|
||||
@ -668,5 +676,6 @@ AMX_NATIVE_INFO string_Natives[] = {
|
||||
{ "trim", amx_trim },
|
||||
{ "ucfirst", amx_ucfirst },
|
||||
{ "strtok", amx_strtok },
|
||||
{ "strlen", amx_strlen },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,1,0,0
|
||||
PRODUCTVERSION 1,1,0,0
|
||||
FILEVERSION 1,5,0,1
|
||||
PRODUCTVERSION 1,5,0,1
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -45,12 +45,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "Comments", "AMX Mod X"
|
||||
VALUE "FileDescription", "AMX Mod X"
|
||||
VALUE "FileVersion", "1.10-RC1"
|
||||
VALUE "FileVersion", "1.50"
|
||||
VALUE "InternalName", "amxmodx"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2004-2005, AMX Mod X Dev Team"
|
||||
VALUE "OriginalFilename", "amxmodx_mm.dll"
|
||||
VALUE "ProductName", "AMX Mod X"
|
||||
VALUE "ProductVersion", "1.10-RC1"
|
||||
VALUE "ProductVersion", "1.50-RC1"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
Loading…
Reference in New Issue
Block a user