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()
|
void EventsMngr::executeEvents()
|
||||||
{
|
{
|
||||||
int err;
|
|
||||||
|
|
||||||
if (!m_ParseFun)
|
if (!m_ParseFun)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLEEXEPTIONS
|
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
#endif // #ifdef ENABLEEXEPTIONS
|
if ( (*iter).m_Done )
|
||||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
|
||||||
{
|
{
|
||||||
if ( (*iter).m_Done )
|
(*iter).m_Done = false;
|
||||||
{
|
continue;
|
||||||
(*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_Stamp = (float)*m_Timer;
|
||||||
#ifdef ENABLEEXEPTIONS
|
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_CurrentMsgType = -1;
|
||||||
m_ParseFun = NULL;
|
m_ParseFun = NULL;
|
||||||
|
|
|
@ -71,7 +71,7 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
if (iter->pPlugin->isExecutable(iter->func))
|
if (iter->pPlugin->isExecutable(iter->func))
|
||||||
{
|
{
|
||||||
// handle strings & arrays
|
// handle strings & arrays
|
||||||
int i;
|
int i, ax=0;
|
||||||
for (i = 0; i < m_NumParams; ++i)
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
{
|
{
|
||||||
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
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(),
|
amx_Allot(iter->pPlugin->getAMX(),
|
||||||
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH,
|
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH,
|
||||||
&realParams[i], &tmp);
|
&realParams[i], &tmp);
|
||||||
amx_SetString(tmp, (const char *)(params[i]), 0, 0);
|
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
|
||||||
physAddrs[i] = tmp;
|
physAddrs[i] = tmp;
|
||||||
}
|
}
|
||||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||||
|
@ -105,9 +105,14 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
realParams[i] = params[i];
|
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
|
// exec
|
||||||
cell retVal;
|
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
|
// log runtime error, if any
|
||||||
if (err != AMX_ERR_NONE)
|
if (err != AMX_ERR_NONE)
|
||||||
LogError(iter->pPlugin->getAMX(), err, "");
|
LogError(iter->pPlugin->getAMX(), err, "");
|
||||||
|
@ -122,7 +127,7 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
else if (m_ParamTypes[i] == FP_STRINGEX)
|
else if (m_ParamTypes[i] == FP_STRINGEX)
|
||||||
{
|
{
|
||||||
// copy back
|
// 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]);
|
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
||||||
}
|
}
|
||||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||||
|
@ -216,7 +221,7 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
amx_Allot(m_Amx,
|
amx_Allot(m_Amx,
|
||||||
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH,
|
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH,
|
||||||
&realParams[i], &tmp);
|
&realParams[i], &tmp);
|
||||||
amx_SetString(tmp, (const char *)(params[i]), 0, 0);
|
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
|
||||||
physAddrs[i] = tmp;
|
physAddrs[i] = tmp;
|
||||||
}
|
}
|
||||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||||
|
@ -241,10 +246,11 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
realParams[i] = params[i];
|
realParams[i] = params[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (i=m_NumParams-1; i>=0; i--)
|
||||||
|
amx_Push(m_Amx, realParams[i]);
|
||||||
// exec
|
// exec
|
||||||
cell retVal;
|
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
|
// log runtime error, if any
|
||||||
if (err != AMX_ERR_NONE)
|
if (err != AMX_ERR_NONE)
|
||||||
|
@ -260,7 +266,7 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
else if (m_ParamTypes[i] == FP_STRINGEX)
|
else if (m_ParamTypes[i] == FP_STRINGEX)
|
||||||
{
|
{
|
||||||
// copy back
|
// 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]);
|
amx_Release(m_Amx, realParams[i]);
|
||||||
}
|
}
|
||||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||||
|
|
|
@ -151,7 +151,6 @@ LogEventsMngr::CLogEvent* LogEventsMngr::registerLogEvent( CPluginMngr::CPlugin*
|
||||||
|
|
||||||
void LogEventsMngr::executeLogEvents()
|
void LogEventsMngr::executeLogEvents()
|
||||||
{
|
{
|
||||||
int err;
|
|
||||||
bool valid;
|
bool valid;
|
||||||
for(CLogEvent* a = logevents[ logArgc ]; a ; a = a->next)
|
for(CLogEvent* a = logevents[ logArgc ]; a ; a = a->next)
|
||||||
{
|
{
|
||||||
|
@ -171,8 +170,7 @@ void LogEventsMngr::executeLogEvents()
|
||||||
|
|
||||||
if (valid)
|
if (valid)
|
||||||
{
|
{
|
||||||
if ((err = amx_Exec(a->plugin->getAMX(), NULL , a->func , 0)) != AMX_ERR_NONE)
|
executeForwards(a->func);
|
||||||
LogError(a->plugin->getAMX(), err, "");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ MenuMngr::~MenuMngr()
|
||||||
int MenuMngr::findMenuId(const char* name, AMX* amx)
|
int MenuMngr::findMenuId(const char* name, AMX* amx)
|
||||||
{
|
{
|
||||||
for( MenuIdEle* b = headid; b ; b = b->next) {
|
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 b->id;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -35,11 +35,6 @@
|
||||||
#define FAR
|
#define FAR
|
||||||
#endif
|
#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
|
// New
|
||||||
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
||||||
typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo*/);
|
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 int (FAR *DETACHMOD_NEW)(void);
|
||||||
typedef void (FAR *PLUGINSLOADED_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
|
// class CModule
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
@ -150,8 +70,6 @@ void CModule::clear(bool clearFilename)
|
||||||
if (clearFilename)
|
if (clearFilename)
|
||||||
m_Filename.assign("unknown");
|
m_Filename.assign("unknown");
|
||||||
|
|
||||||
// old
|
|
||||||
m_InfoOld = NULL;
|
|
||||||
// new
|
// new
|
||||||
m_Amxx = false;
|
m_Amxx = false;
|
||||||
m_InfoNew.author = "unknown";
|
m_InfoNew.author = "unknown";
|
||||||
|
@ -220,17 +138,11 @@ bool CModule::attachModule()
|
||||||
m_Status = MODULE_BADLOAD;
|
m_Status = MODULE_BADLOAD;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
m_Status = MODULE_BADLOAD;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// old
|
|
||||||
ATTACHMOD AttachFunc = (ATTACHMOD)DLPROC(m_Handle, "AMX_Attach");
|
|
||||||
|
|
||||||
if (AttachFunc)
|
return false;
|
||||||
(*AttachFunc)(&engAmxFunc,&engModuleFunc);
|
|
||||||
m_Status = MODULE_LOADED;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CModule::queryModule()
|
bool CModule::queryModule()
|
||||||
|
@ -292,44 +204,9 @@ bool CModule::queryModule()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// old interface not 64 bit compatible
|
m_Status = MODULE_NOQUERY;
|
||||||
#if SMALL_CELL_SIZE == 64
|
m_Amxx = false;
|
||||||
m_Status = MODULE_NOT64BIT;
|
|
||||||
return 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;
|
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
DETACHMOD detachFunc_Old = (DETACHMOD)DLPROC(m_Handle, "AMX_Detach");
|
|
||||||
if (detachFunc_Old)
|
|
||||||
(*detachFunc_Old)();
|
|
||||||
}
|
|
||||||
#ifndef FAKEMETA
|
#ifndef FAKEMETA
|
||||||
if (IsMetamod())
|
if (IsMetamod())
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,14 +66,13 @@ struct amxx_module_info_s
|
||||||
#define AMXX_PARAM 2 /* Invalid parameter */
|
#define AMXX_PARAM 2 /* Invalid parameter */
|
||||||
#define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */
|
#define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */
|
||||||
|
|
||||||
#define AMXX_INTERFACE_VERSION 2
|
#define AMXX_INTERFACE_VERSION 3
|
||||||
|
|
||||||
class CModule
|
class CModule
|
||||||
{
|
{
|
||||||
String m_Filename; // Filename
|
String m_Filename; // Filename
|
||||||
bool m_Metamod; // Using metamod?
|
bool m_Metamod; // Using metamod?
|
||||||
bool m_Amxx; // Using new module interface?
|
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)
|
amxx_module_info_s m_InfoNew; // module info (new module interface)
|
||||||
DLHANDLE m_Handle; // handle
|
DLHANDLE m_Handle; // handle
|
||||||
MODULE_STATUS m_Status; // status
|
MODULE_STATUS m_Status; // status
|
||||||
|
@ -93,14 +92,13 @@ public:
|
||||||
#endif
|
#endif
|
||||||
const char* getStatus() const;
|
const char* getStatus() const;
|
||||||
inline const char* getType() const { return m_Amxx ? "amxx" : (m_Metamod ? "amx&mm" : "amx"); }
|
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* getAuthor() const { return m_InfoNew.author; }
|
||||||
inline const char* getVersion() const { return m_Amxx ? (m_InfoNew.version) : (m_InfoOld ? m_InfoOld->version : "unknown"); }
|
inline const char* getVersion() const { return m_InfoNew.version; }
|
||||||
inline const char* getName() const { return m_Amxx ? (m_InfoNew.name) : (m_InfoOld ? m_InfoOld->name : "unknown"); }
|
inline const char* getName() const { return m_InfoNew.name; }
|
||||||
inline module_info_s* getInfo() const { return m_InfoOld; } // old
|
|
||||||
inline const amxx_module_info_s* getInfoNew() const { return &m_InfoNew; } // new
|
inline const amxx_module_info_s* getInfoNew() const { return &m_InfoNew; } // new
|
||||||
inline int getStatusValue() { return m_Status; }
|
inline int getStatusValue() { return m_Status; }
|
||||||
inline bool operator==( const char* fname ) { return !strcmp( m_Filename.c_str() , fname ); }
|
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 bool isAmxx() const { return m_Amxx; }
|
||||||
inline const char *getMissingFunc() const { return m_MissingFunc; }
|
inline const char *getMissingFunc() const { return m_MissingFunc; }
|
||||||
inline const char *getFilename() { return m_Filename.c_str(); }
|
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;
|
paused_fun = 0;
|
||||||
next = 0;
|
next = 0;
|
||||||
id = i;
|
id = i;
|
||||||
|
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause");
|
||||||
|
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause");
|
||||||
}
|
}
|
||||||
|
|
||||||
CPluginMngr::CPlugin::~CPlugin( )
|
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 );
|
unload_amxscript( &amx, &code );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,16 +206,8 @@ void CPluginMngr::CPlugin::pausePlugin()
|
||||||
if (isValid())
|
if (isValid())
|
||||||
{
|
{
|
||||||
// call plugin_pause if provided
|
// call plugin_pause if provided
|
||||||
int func;
|
if (m_PauseFwd != -1)
|
||||||
cell retval;
|
executeForwards(m_PauseFwd);
|
||||||
if (amx_FindPublic(&amx, "plugin_pause", &func) == AMX_ERR_NONE)
|
|
||||||
{
|
|
||||||
if (isExecutable(func))
|
|
||||||
{
|
|
||||||
|
|
||||||
amx_Exec(&amx, &retval, func, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setStatus(ps_paused);
|
setStatus(ps_paused);
|
||||||
}
|
}
|
||||||
|
@ -256,14 +222,7 @@ void CPluginMngr::CPlugin::unpausePlugin()
|
||||||
|
|
||||||
setStatus(ps_running);
|
setStatus(ps_running);
|
||||||
// call plugin_unpause if provided
|
// call plugin_unpause if provided
|
||||||
int func;
|
if (m_UnpauseFwd != -1)
|
||||||
cell retval;
|
executeForwards(m_UnpauseFwd);
|
||||||
if (amx_FindPublic(&amx, "plugin_unpause", &func) == AMX_ERR_NONE)
|
|
||||||
{
|
|
||||||
if (isExecutable(func))
|
|
||||||
{
|
|
||||||
amx_Exec(&amx, &retval, func, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,8 @@ public:
|
||||||
String title;
|
String title;
|
||||||
String author;
|
String author;
|
||||||
String errorMsg;
|
String errorMsg;
|
||||||
|
int m_PauseFwd;
|
||||||
|
int m_UnpauseFwd;
|
||||||
int paused_fun;
|
int paused_fun;
|
||||||
int status;
|
int status;
|
||||||
CPlugin* next;
|
CPlugin* next;
|
||||||
|
@ -88,8 +90,8 @@ public:
|
||||||
inline void setError( const char* n ) { errorMsg.assign(n); }
|
inline void setError( const char* n ) { errorMsg.assign(n); }
|
||||||
inline bool isValid() const { return ((status != ps_bad_load) && (status != ps_locked)); }
|
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 isPaused() const { return ( (status == ps_paused) || (status == ps_stopped)); }
|
||||||
inline bool isFunctionPaused( int id ) const { return (paused_fun & (1<<id)) ? true : false; }
|
//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 isExecutable(int id) const { return (isValid() && !isPaused()); }
|
||||||
void pausePlugin();
|
void pausePlugin();
|
||||||
void unpausePlugin();
|
void unpausePlugin();
|
||||||
void pauseFunction( int id );
|
void pauseFunction( int id );
|
||||||
|
|
|
@ -48,7 +48,8 @@ template <class T> class CVector
|
||||||
return false;
|
return false;
|
||||||
if (m_Data)
|
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;
|
delete [] m_Data;
|
||||||
}
|
}
|
||||||
m_Data = newData;
|
m_Data = newData;
|
||||||
|
@ -74,7 +75,9 @@ template <class T> class CVector
|
||||||
return false;
|
return false;
|
||||||
if (m_Data)
|
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;
|
delete [] m_Data;
|
||||||
}
|
}
|
||||||
if (m_Size < size)
|
if (m_Size < size)
|
||||||
|
@ -251,10 +254,11 @@ public:
|
||||||
CVector<T>(const CVector<T> & other)
|
CVector<T>(const CVector<T> & other)
|
||||||
{
|
{
|
||||||
// copy data
|
// copy data
|
||||||
m_Data = new T [other.m_Size];
|
m_Data = new T [other.m_CurrentUsedSize];
|
||||||
m_Size = other.m_Size;
|
m_Size = other.m_CurrentUsedSize;
|
||||||
m_CurrentUsedSize = 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>()
|
~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.
|
* 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
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
@ -21,54 +21,98 @@
|
||||||
* Version: $Id$
|
* Version: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined __linux__
|
#if defined FREEBSD && !defined __FreeBSD__
|
||||||
|
#define __FreeBSD__
|
||||||
|
#endif
|
||||||
|
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||||
#include <sclinux.h>
|
#include <sclinux.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef AMX_H_INCLUDED
|
#ifndef AMX_H_INCLUDED
|
||||||
#define AMX_H_INCLUDED
|
#define AMX_H_INCLUDED
|
||||||
|
|
||||||
#if defined __LCC__ || defined __DMC__ || defined __linux__
|
#if defined HAVE_STDINT_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
#else
|
||||||
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
#if defined __LCC__ || defined __DMC__ || defined LINUX
|
||||||
* here, these types are probably undefined.
|
#if defined HAVE_INTTYPES_H
|
||||||
*/
|
#include <inttypes.h>
|
||||||
#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
|
#else
|
||||||
typedef long int int32_t;
|
#include <stdint.h>
|
||||||
typedef unsigned long int uint32_t;
|
|
||||||
#endif
|
#endif
|
||||||
// evilspy's fix for mingw
|
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||||
#if defined __GNUC__
|
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
||||||
typedef long long int64_t;
|
* here, these types are probably undefined.
|
||||||
typedef unsigned long long uint64_t;
|
*/
|
||||||
#define HAVE_I64
|
#if defined __MACH__
|
||||||
#elif defined __WIN32__ || defined _WIN32 || defined WIN32
|
#include <ppc/types.h>
|
||||||
typedef __int64 int64_t;
|
typedef unsigned short int uint16_t;
|
||||||
typedef unsigned __int64 uint64_t;
|
typedef unsigned long int uint32_t;
|
||||||
#define HAVE_I64
|
#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
|
||||||
#endif
|
#endif
|
||||||
|
#define HAVE_STDINT_H
|
||||||
|
#endif
|
||||||
|
#if defined _LP64 || defined WIN64 || defined _WIN64
|
||||||
|
#if !defined __64BIT__
|
||||||
|
#define __64BIT__
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_ALLOCA_H
|
||||||
|
#include <alloca.h>
|
||||||
|
#endif
|
||||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
|
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
|
||||||
#if !defined alloca
|
#if !defined alloca
|
||||||
#define alloca(n) _alloca(n)
|
#define alloca(n) _alloca(n)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined arraysize
|
||||||
|
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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 */
|
/* calling convention for native functions */
|
||||||
#if !defined AMX_NATIVE_CALL
|
#if !defined AMX_NATIVE_CALL
|
||||||
#define AMX_NATIVE_CALL
|
#define AMX_NATIVE_CALL
|
||||||
|
@ -79,6 +123,8 @@ extern "C" {
|
||||||
#define AMXAPI __stdcall
|
#define AMXAPI __stdcall
|
||||||
#elif defined CDECL
|
#elif defined CDECL
|
||||||
#define AMXAPI __cdecl
|
#define AMXAPI __cdecl
|
||||||
|
#elif defined GCC_HASCLASSVISIBILITY
|
||||||
|
#define AMXAPI __attribute__ ((visibility("default")))
|
||||||
#else
|
#else
|
||||||
#define AMXAPI
|
#define AMXAPI
|
||||||
#endif
|
#endif
|
||||||
|
@ -96,46 +142,36 @@ extern "C" {
|
||||||
* 5 (tagnames table) 4
|
* 5 (tagnames table) 4
|
||||||
* 6 (reformatted header) 6
|
* 6 (reformatted header) 6
|
||||||
* 7 (name table, opcodes SYMTAG & SYSREQ.D) 7
|
* 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_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
|
#if !defined PAWN_CELL_SIZE
|
||||||
#define SMALL_CELL_SIZE 16 /* for backward compatibility */
|
#define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
|
||||||
#endif
|
#endif
|
||||||
#if !defined SMALL_CELL_SIZE
|
#if PAWN_CELL_SIZE==16
|
||||||
#define SMALL_CELL_SIZE 32 /* by default, use 32-bit cells */
|
|
||||||
#endif
|
|
||||||
#if SMALL_CELL_SIZE==16
|
|
||||||
typedef uint16_t ucell;
|
typedef uint16_t ucell;
|
||||||
typedef int16_t cell;
|
typedef int16_t cell;
|
||||||
#elif SMALL_CELL_SIZE==32
|
#elif PAWN_CELL_SIZE==32
|
||||||
typedef uint32_t ucell;
|
typedef uint32_t ucell;
|
||||||
typedef int32_t cell;
|
typedef int32_t cell;
|
||||||
#elif SMALL_CELL_SIZE==64
|
#elif PAWN_CELL_SIZE==64
|
||||||
typedef uint64_t ucell;
|
typedef uint64_t ucell;
|
||||||
typedef int64_t cell;
|
typedef int64_t cell;
|
||||||
#else
|
#else
|
||||||
#error Unsupported cell size (SMALL_CELL_SIZE)
|
#error Unsupported cell size (PAWN_CELL_SIZE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SMALL_CELL_SIZE==32
|
#define UNPACKEDMAX ((1L << (sizeof(cell)-1)*8) - 1)
|
||||||
#define REAL float
|
#define UNLIMITED (~1u >> 1)
|
||||||
#elif SMALL_CELL_SIZE==64
|
|
||||||
#define REAL double
|
|
||||||
#else
|
|
||||||
#error Unsupported cell size
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define UNPACKEDMAX ((1 << (sizeof(cell)-1)*8) - 1)
|
|
||||||
|
|
||||||
struct tagAMX;
|
struct tagAMX;
|
||||||
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
|
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
|
||||||
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
|
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
|
||||||
cell *result, cell *params);
|
cell *result, cell *params);
|
||||||
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
||||||
typedef int (AMXAPI *AMX_DEBUGCALL)(struct tagAMX *amx, int mode);
|
|
||||||
#if !defined _FAR
|
#if !defined _FAR
|
||||||
#define _FAR
|
#define _FAR
|
||||||
#endif
|
#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
|
/* 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...
|
* 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
|
#define AMX_NO_ALIGN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -160,8 +196,10 @@ typedef int (AMXAPI *AMX_DEBUGCALL)(struct tagAMX *amx, int mode);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined AMX_NO_ALIGN
|
#if !defined AMX_NO_ALIGN
|
||||||
#if defined __linux__
|
#if defined LINUX || defined __FreeBSD__
|
||||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||||
|
#elif defined MACOS && defined __MWERKS__
|
||||||
|
#pragma options align=mac68k
|
||||||
#else
|
#else
|
||||||
#pragma pack(push)
|
#pragma pack(push)
|
||||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
#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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct tagAMX_NATIVE_INFO {
|
||||||
const char _FAR *name PACKED;
|
const char _FAR *name PACKED;
|
||||||
AMX_NATIVE func PACKED;
|
AMX_NATIVE func PACKED;
|
||||||
} AMX_NATIVE_INFO;
|
} PACKED AMX_NATIVE_INFO;
|
||||||
|
|
||||||
#define AMX_USERNUM 4
|
#define AMX_USERNUM 4
|
||||||
#define sEXPMAX 19 /* maximum name length for file version <= 6 */
|
#define sEXPMAX 19 /* maximum name length for file version <= 6 */
|
||||||
#define sNAMEMAX 31 /* maximum name length of symbol name */
|
#define sNAMEMAX 31 /* maximum name length of symbol name */
|
||||||
|
|
||||||
typedef struct tagAMX_FUNCSTUB {
|
typedef struct tagAMX_FUNCSTUB {
|
||||||
ucell address PACKED;
|
ucell address PACKED;
|
||||||
const char name[sEXPMAX+1] PACKED;
|
char name[sEXPMAX+1] PACKED;
|
||||||
} AMX_FUNCSTUB;
|
} 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
|
/* 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.
|
* fields are valid at all times; many fields are cached in local variables.
|
||||||
*/
|
*/
|
||||||
typedef struct tagAMX {
|
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 */
|
unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
|
||||||
AMX_CALLBACK callback PACKED;
|
AMX_CALLBACK callback PACKED;
|
||||||
AMX_DEBUG debug PACKED; /* debug callback */
|
AMX_DEBUG debug PACKED; /* debug callback */
|
||||||
|
@ -201,28 +244,23 @@ typedef struct tagAMX {
|
||||||
cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
|
cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
|
||||||
cell stp PACKED; /* top of the stack: 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() */
|
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 */
|
/* user data */
|
||||||
long usertags[AMX_USERNUM] PACKED;
|
long usertags[AMX_USERNUM] PACKED;
|
||||||
void _FAR *userdata[AMX_USERNUM] PACKED;
|
void _FAR *userdata[AMX_USERNUM] PACKED;
|
||||||
/* native functions can raise an error */
|
/* native functions can raise an error */
|
||||||
int error PACKED;
|
int error PACKED;
|
||||||
|
/* passing parameters requires a "count" field */
|
||||||
|
int paramcount;
|
||||||
/* the sleep opcode needs to store the full AMX status */
|
/* the sleep opcode needs to store the full AMX status */
|
||||||
cell pri PACKED;
|
cell pri PACKED;
|
||||||
cell alt PACKED;
|
cell alt PACKED;
|
||||||
cell reset_stk PACKED;
|
cell reset_stk PACKED;
|
||||||
cell reset_hea PACKED;
|
cell reset_hea PACKED;
|
||||||
cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */
|
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 */
|
int reloc_size PACKED; /* required temporary buffer for relocations */
|
||||||
long code_size PACKED; /* estimated memory footprint of the native code */
|
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
|
/* The AMX_HEADER structure is both the memory format as the file format. The
|
||||||
* structure is used internaly.
|
* structure is used internaly.
|
||||||
|
@ -244,26 +282,11 @@ typedef struct tagAMX_HEADER {
|
||||||
int32_t libraries PACKED; /* offset to the table of libraries */
|
int32_t libraries PACKED; /* offset to the table of libraries */
|
||||||
int32_t pubvars PACKED; /* the "public variables" table */
|
int32_t pubvars PACKED; /* the "public variables" table */
|
||||||
int32_t tags PACKED; /* the "public tagnames" table */
|
int32_t tags PACKED; /* the "public tagnames" table */
|
||||||
int32_t nametable PACKED; /* name table, file version 7 only */
|
int32_t nametable PACKED; /* name table */
|
||||||
} AMX_HEADER PACKED;
|
} PACKED AMX_HEADER;
|
||||||
#define AMX_MAGIC 0xf1e0
|
|
||||||
|
|
||||||
//double linked list for stack
|
//This is always the same for us
|
||||||
typedef struct tagAMX_TRACE
|
#define AMX_MAGIC 0xf1e0
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
AMX_ERR_NONE,
|
AMX_ERR_NONE,
|
||||||
|
@ -280,6 +303,7 @@ enum {
|
||||||
AMX_ERR_NATIVE, /* native function failed */
|
AMX_ERR_NATIVE, /* native function failed */
|
||||||
AMX_ERR_DIVIDE, /* divide by zero */
|
AMX_ERR_DIVIDE, /* divide by zero */
|
||||||
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
|
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_MEMORY = 16, /* out of memory */
|
||||||
AMX_ERR_FORMAT, /* invalid file format */
|
AMX_ERR_FORMAT, /* invalid file format */
|
||||||
|
@ -292,29 +316,17 @@ enum {
|
||||||
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
|
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
|
||||||
AMX_ERR_PARAMS, /* parameter error */
|
AMX_ERR_PARAMS, /* parameter error */
|
||||||
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
|
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
|
||||||
};
|
AMX_ERR_GENERAL, /* general error (unknown or unspecific error) */
|
||||||
|
|
||||||
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_FLAG_CHAR16 0x01 no longer used */
|
/* AMX_FLAG_CHAR16 0x01 no longer used */
|
||||||
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
|
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
|
||||||
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */
|
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */
|
||||||
#define AMX_FLAG_BIGENDIAN 0x08 /* big endian encoding */
|
#define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */
|
||||||
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking */
|
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */
|
||||||
#define AMX_FLAG_LINEOPS 0x20 /* line ops are parsed by the JIT [loadtime only flag] */
|
#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
|
||||||
#define AMX_FLAG_TRACED 0x40 /* the file has already been traced */
|
#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
|
||||||
#define AMX_FLAG_BROWSE 0x4000 /* browsing/relocating or executing */
|
#define AMX_FLAG_BROWSE 0x4000 /* busy browsing */
|
||||||
#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
|
#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
|
||||||
|
|
||||||
#define AMX_EXEC_MAIN -1 /* start at program entry point */
|
#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_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
|
/* for native functions that use floating point parameters, the following
|
||||||
* two macros are convenient for casting a "cell" into a "float" type _without_
|
* two macros are convenient for casting a "cell" into a "float" type _without_
|
||||||
* changing the bit pattern
|
* 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_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||||
#define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
|
#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_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||||
#define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
|
#define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
|
||||||
#else
|
#else
|
||||||
|
@ -345,7 +359,7 @@ enum {
|
||||||
amx_StrLen(amx_cstr_, &amx_length_); \
|
amx_StrLen(amx_cstr_, &amx_length_); \
|
||||||
if (amx_length_ > 0 && \
|
if (amx_length_ > 0 && \
|
||||||
((result) = (void*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \
|
((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; \
|
else (result) = NULL; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -354,23 +368,11 @@ uint32_t * AMXAPI amx_Align32(uint32_t *v);
|
||||||
#if defined _I64_MAX || defined HAVE_I64
|
#if defined _I64_MAX || defined HAVE_I64
|
||||||
uint64_t * AMXAPI amx_Align64(uint64_t *v);
|
uint64_t * AMXAPI amx_Align64(uint64_t *v);
|
||||||
#endif
|
#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_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_Callback(AMX *amx, cell index, cell *result, cell *params);
|
||||||
int AMXAPI amx_Cleanup(AMX *amx);
|
int AMXAPI amx_Cleanup(AMX *amx);
|
||||||
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
|
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
|
||||||
int AMXAPI amx_Debug(AMX *amx); /* default debug procedure, does nothing */
|
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
|
||||||
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_FindNative(AMX *amx, const char *name, 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_FindPublic(AMX *amx, const char *funcname, int *index);
|
||||||
int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr);
|
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_GetNative(AMX *amx, int index, char *funcname);
|
||||||
int AMXAPI amx_GetPublic(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_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_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
|
||||||
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
|
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
|
||||||
int AMXAPI amx_Init(AMX *amx, void *program);
|
int AMXAPI amx_Init(AMX *amx, void *program);
|
||||||
int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
|
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_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
|
||||||
int AMXAPI amx_NameLength(AMX *amx, int *length);
|
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_NumNatives(AMX *amx, int *number);
|
||||||
int AMXAPI amx_NumPublics(AMX *amx, int *number);
|
int AMXAPI amx_NumPublics(AMX *amx, int *number);
|
||||||
int AMXAPI amx_NumPubVars(AMX *amx, int *number);
|
int AMXAPI amx_NumPubVars(AMX *amx, int *number);
|
||||||
int AMXAPI amx_NumTags(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_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_Release(AMX *amx, cell amx_addr);
|
||||||
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
|
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
|
||||||
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
|
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_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_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_UTF8Put(char *string, char **endptr, int maxchars, cell value);
|
||||||
int AMXAPI amx_UTF8Check(const char *string);
|
|
||||||
int AMXAPI amx_GetLibraries(AMX *amx);
|
int AMXAPI amx_GetLibraries(AMX *amx);
|
||||||
const char *AMXAPI amx_GetLibrary(AMX *amx, int index, char *buffer, int len);
|
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 AMX_NO_ALIGN
|
||||||
#if defined __linux__
|
#if defined LINUX || defined __FreeBSD__
|
||||||
#pragma pack() /* reset default packing */
|
#pragma pack() /* reset default packing */
|
||||||
|
#elif defined MACOS && defined __MWERKS__
|
||||||
|
#pragma options align=reset
|
||||||
#else
|
#else
|
||||||
#pragma pack(pop) /* reset previous packing */
|
#pragma pack(pop) /* reset previous packing */
|
||||||
#endif
|
#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.
|
* 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
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
@ -34,14 +34,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <assert.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"
|
#include "amx.h"
|
||||||
|
|
||||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined _Windows
|
#if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined _Windows
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -60,14 +53,13 @@
|
||||||
# define _tcscpy strcpy
|
# define _tcscpy strcpy
|
||||||
# define _tcsdup strdup
|
# define _tcsdup strdup
|
||||||
# define _tcslen strlen
|
# define _tcslen strlen
|
||||||
# define _stprintf sprintf
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define CHARBITS (8*sizeof(char))
|
#define CHARBITS (8*sizeof(char))
|
||||||
typedef unsigned char uchar;
|
typedef unsigned char uchar;
|
||||||
|
|
||||||
#if !defined NOPROPLIST
|
#if !defined AMX_NOPROPLIST
|
||||||
typedef struct _property_list {
|
typedef struct _property_list {
|
||||||
struct _property_list *next;
|
struct _property_list *next;
|
||||||
cell id;
|
cell id;
|
||||||
|
@ -76,7 +68,7 @@ typedef struct _property_list {
|
||||||
//??? safe AMX (owner of the property)
|
//??? safe AMX (owner of the property)
|
||||||
} proplist;
|
} proplist;
|
||||||
|
|
||||||
static proplist proproot = { NULL };
|
static proplist proproot = { NULL, 0, NULL, 0 };
|
||||||
|
|
||||||
static proplist *list_additem(proplist *root)
|
static proplist *list_additem(proplist *root)
|
||||||
{
|
{
|
||||||
|
@ -142,15 +134,13 @@ static proplist *list_finditem(proplist *root,cell id,char *name,cell value,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
|
||||||
#pragma argsused
|
|
||||||
#endif
|
|
||||||
static cell AMX_NATIVE_CALL numargs(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL numargs(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
AMX_HEADER *hdr;
|
AMX_HEADER *hdr;
|
||||||
uchar *data;
|
uchar *data;
|
||||||
cell bytes;
|
cell bytes;
|
||||||
|
|
||||||
|
(void)params;
|
||||||
hdr=(AMX_HEADER *)amx->base;
|
hdr=(AMX_HEADER *)amx->base;
|
||||||
data=amx->data ? amx->data : amx->base+(int)hdr->dat;
|
data=amx->data ? amx->data : amx->base+(int)hdr->dat;
|
||||||
/* the number of bytes is on the stack, at "frm + 2*cell" */
|
/* 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 */
|
/* adjust the address in "value" in case of an array access */
|
||||||
value+=params[2]*sizeof(cell);
|
value+=params[2]*sizeof(cell);
|
||||||
/* verify the address */
|
/* verify the address */
|
||||||
if (value<0 || (value>=amx->hea && value<amx->stk))
|
if (value<0 || value>=amx->hea && value<amx->stk)
|
||||||
return 0;
|
return 0;
|
||||||
/* set the value indirectly */
|
/* set the value indirectly */
|
||||||
* (cell *)(data+(int)value) = params[3];
|
* (cell *)(data+(int)value) = params[3];
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
|
||||||
#pragma argsused
|
|
||||||
#endif
|
|
||||||
static cell AMX_NATIVE_CALL heapspace(AMX *amx,cell *params)
|
static cell AMX_NATIVE_CALL heapspace(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
|
(void)params;
|
||||||
return amx->stk - amx->hea;
|
return amx->stk - amx->hea;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,142 +208,22 @@ static cell AMX_NATIVE_CALL funcidx(AMX *amx,cell *params)
|
||||||
return 0;
|
return 0;
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
amx_GetString(name,cstr,0);
|
amx_GetString(name,cstr,0,UNLIMITED);
|
||||||
err=amx_FindPublic(amx,name,&index);
|
err=amx_FindPublic(amx,name,&index);
|
||||||
if (err!=AMX_ERR_NONE)
|
if (err!=AMX_ERR_NONE)
|
||||||
index=-1; /* this is not considered a fatal error */
|
index=-1; /* this is not considered a fatal error */
|
||||||
return index;
|
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)
|
static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
cell c;
|
cell c;
|
||||||
#if SMALL_CELL_SIZE==16
|
#if PAWN_CELL_SIZE==16
|
||||||
uchar b[2];
|
uchar b[2];
|
||||||
#elif SMALL_CELL_SIZE==32
|
#elif PAWN_CELL_SIZE==32
|
||||||
uchar b[4];
|
uchar b[4];
|
||||||
#elif SMALL_CELL_SIZE==64
|
#elif PAWN_CELL_SIZE==64
|
||||||
uchar b[8];
|
uchar b[8];
|
||||||
#else
|
#else
|
||||||
#error Unsupported cell size
|
#error Unsupported cell size
|
||||||
|
@ -363,20 +231,21 @@ static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
|
||||||
} value;
|
} value;
|
||||||
uchar t;
|
uchar t;
|
||||||
|
|
||||||
|
(void)amx;
|
||||||
assert((size_t)params[0]==sizeof(cell));
|
assert((size_t)params[0]==sizeof(cell));
|
||||||
value.c = params[1];
|
value.c = params[1];
|
||||||
#if SMALL_CELL_SIZE==16
|
#if PAWN_CELL_SIZE==16
|
||||||
t = value.b[0];
|
t = value.b[0];
|
||||||
value.b[0] = value.b[1];
|
value.b[0] = value.b[1];
|
||||||
value.b[1] = t;
|
value.b[1] = t;
|
||||||
#elif SMALL_CELL_SIZE==32
|
#elif PAWN_CELL_SIZE==32
|
||||||
t = value.b[0];
|
t = value.b[0];
|
||||||
value.b[0] = value.b[3];
|
value.b[0] = value.b[3];
|
||||||
value.b[3] = t;
|
value.b[3] = t;
|
||||||
t = value.b[1];
|
t = value.b[1];
|
||||||
value.b[1] = value.b[2];
|
value.b[1] = value.b[2];
|
||||||
value.b[2] = t;
|
value.b[2] = t;
|
||||||
#elif SMALL_CELL_SIZE==64
|
#elif PAWN_CELL_SIZE==64
|
||||||
t = value.b[0];
|
t = value.b[0];
|
||||||
value.b[0] = value.b[7];
|
value.b[0] = value.b[7];
|
||||||
value.b[7] = t;
|
value.b[7] = t;
|
||||||
|
@ -395,11 +264,9 @@ static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
|
||||||
return value.c;
|
return value.c;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
|
||||||
#pragma argsused
|
|
||||||
#endif
|
|
||||||
static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params)
|
static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
|
(void)amx;
|
||||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||||
return (cell)CharLower((LPTSTR)params[1]);
|
return (cell)CharLower((LPTSTR)params[1]);
|
||||||
#elif defined _Windows
|
#elif defined _Windows
|
||||||
|
@ -409,11 +276,9 @@ static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
|
||||||
#pragma argsused
|
|
||||||
#endif
|
|
||||||
static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params)
|
static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
|
(void)amx;
|
||||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||||
return (cell)CharUpper((LPTSTR)params[1]);
|
return (cell)CharUpper((LPTSTR)params[1]);
|
||||||
#elif defined _Windows
|
#elif defined _Windows
|
||||||
|
@ -423,19 +288,15 @@ static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
|
||||||
#pragma argsused
|
|
||||||
#endif
|
|
||||||
static cell AMX_NATIVE_CALL core_min(AMX *amx,cell *params)
|
static cell AMX_NATIVE_CALL core_min(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
|
(void)amx;
|
||||||
return params[1] <= params[2] ? params[1] : params[2];
|
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)
|
static cell AMX_NATIVE_CALL core_max(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
|
(void)amx;
|
||||||
return params[1] >= params[2] ? params[1] : params[2];
|
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;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined NOPROPLIST
|
#if !defined AMX_NOPROPLIST
|
||||||
static char *MakePackedString(cell *cptr)
|
static char *MakePackedString(cell *cptr)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
@ -459,10 +320,21 @@ static char *MakePackedString(cell *cptr)
|
||||||
|
|
||||||
amx_StrLen(cptr,&len);
|
amx_StrLen(cptr,&len);
|
||||||
dest=(char *)malloc(len+sizeof(cell));
|
dest=(char *)malloc(len+sizeof(cell));
|
||||||
amx_GetString(dest,cptr,0);
|
amx_GetString(dest,cptr,0,UNLIMITED);
|
||||||
return dest;
|
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)
|
static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
cell *cstr;
|
cell *cstr;
|
||||||
|
@ -480,7 +352,7 @@ static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params)
|
||||||
return 0;
|
return 0;
|
||||||
} /* if */
|
} /* if */
|
||||||
amx_GetAddr(amx,params[4],&cstr);
|
amx_GetAddr(amx,params[4],&cstr);
|
||||||
amx_SetString(cstr,item->name,1,0);
|
amx_SetString(cstr,item->name,1,0,UNLIMITED);
|
||||||
} /* if */
|
} /* if */
|
||||||
free(name);
|
free(name);
|
||||||
return (item!=NULL) ? item->value : 0;
|
return (item!=NULL) ? item->value : 0;
|
||||||
|
@ -545,12 +417,14 @@ static cell AMX_NATIVE_CALL existproperty(AMX *amx,cell *params)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined AMX_NORANDOM
|
||||||
/* This routine comes from the book "Inner Loops" by Rick Booth, Addison-Wesley
|
/* 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
|
* (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
|
* generator" that has been extended to 31-bits (the standard C version returns
|
||||||
* only 15-bits).
|
* 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
|
#define IL_RMULT 1103515245L
|
||||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||||
#pragma argsused
|
#pragma argsused
|
||||||
|
@ -562,7 +436,7 @@ static cell AMX_NATIVE_CALL core_random(AMX *amx,cell *params)
|
||||||
|
|
||||||
/* one-time initialization (or, mostly one-time) */
|
/* one-time initialization (or, mostly one-time) */
|
||||||
#if !defined SN_TARGET_PS2 && !defined _WIN32_WCE
|
#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);
|
IL_StandardRandom_seed=(unsigned long)time(NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -579,6 +453,7 @@ static cell AMX_NATIVE_CALL core_random(AMX *amx,cell *params)
|
||||||
result %= params[1];
|
result %= params[1];
|
||||||
return (cell)result;
|
return (cell)result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO core_Natives[] = {
|
AMX_NATIVE_INFO core_Natives[] = {
|
||||||
|
@ -587,22 +462,13 @@ AMX_NATIVE_INFO core_Natives[] = {
|
||||||
{ "setarg", setarg },
|
{ "setarg", setarg },
|
||||||
{ "heapspace", heapspace },
|
{ "heapspace", heapspace },
|
||||||
{ "funcidx", funcidx },
|
{ "funcidx", funcidx },
|
||||||
{ "strlen", core_strlen },
|
|
||||||
{ "strpack", strpack },
|
|
||||||
{ "strunpack", strunpack },
|
|
||||||
{ "swapchars", swapchars },
|
{ "swapchars", swapchars },
|
||||||
{ "tolower", core_tolower },
|
{ "tolower", core_tolower },
|
||||||
{ "toupper", core_toupper },
|
{ "toupper", core_toupper },
|
||||||
{ "random", core_random },
|
|
||||||
{ "min", core_min },
|
{ "min", core_min },
|
||||||
{ "max", core_max },
|
{ "max", core_max },
|
||||||
{ "clamp", core_clamp },
|
{ "clamp", core_clamp },
|
||||||
#if !defined NOPROPLIST
|
{ "random", core_random },
|
||||||
{ "getproperty", getproperty },
|
|
||||||
{ "setproperty", setproperty },
|
|
||||||
{ "deleteproperty",delproperty },
|
|
||||||
{ "existproperty", existproperty },
|
|
||||||
#endif
|
|
||||||
{ NULL, NULL } /* terminator */
|
{ NULL, NULL } /* terminator */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -611,12 +477,10 @@ int AMXEXPORT amx_CoreInit(AMX *amx)
|
||||||
return amx_Register(amx, core_Natives, -1);
|
return amx_Register(amx, core_Natives, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
|
||||||
#pragma argsused
|
|
||||||
#endif
|
|
||||||
int AMXEXPORT amx_CoreCleanup(AMX *amx)
|
int AMXEXPORT amx_CoreCleanup(AMX *amx)
|
||||||
{
|
{
|
||||||
#if !defined NOPROPLIST
|
(void)amx;
|
||||||
|
#if !defined AMX_NOPROPLIST
|
||||||
//??? delete only the properties owned by the AMX
|
//??? delete only the properties owned by the AMX
|
||||||
while (proproot.next!=NULL)
|
while (proproot.next!=NULL)
|
||||||
list_delete(&proproot,proproot.next);
|
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:
|
;Some notes:
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
;
|
;
|
||||||
;Copyright and license of use, please read
|
;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.
|
;specifically the file AMXEXEC.ASM, is copyright (c) 1998-2000 by Marc Peter.
|
||||||
;
|
;
|
||||||
;Permission is hereby granted, without written agreement and without paid
|
;Permission is hereby granted, without written agreement and without paid
|
||||||
|
@ -56,6 +56,8 @@
|
||||||
;
|
;
|
||||||
;History (list of changes)
|
;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
|
; 6 march 2004 by Thiadmer Riemersma
|
||||||
; Corrected a bug in OP_FILL, where a cell preceding the array would
|
; 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
|
; be overwritten (zero'ed out). This bug was brought to my attention
|
||||||
|
@ -95,92 +97,7 @@
|
||||||
%endif
|
%endif
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
%include "amxdefn.asm"
|
||||||
; 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
|
|
||||||
|
|
||||||
;#define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
|
;#define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
|
||||||
%macro _PUSH 1
|
%macro _PUSH 1
|
||||||
|
@ -659,29 +576,6 @@ OP_POP_ALT:
|
||||||
|
|
||||||
;good
|
;good
|
||||||
OP_STACK:
|
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
|
mov edx,ecx
|
||||||
add ecx,[esi+4]
|
add ecx,[esi+4]
|
||||||
_CHKMARGIN
|
_CHKMARGIN
|
||||||
|
@ -711,35 +605,6 @@ OP_PROC:
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
OP_RET:
|
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 ebx
|
||||||
_POP esi
|
_POP esi
|
||||||
cmp esi,code ; verify ESI>=code
|
cmp esi,code ; verify ESI>=code
|
||||||
|
@ -760,107 +625,17 @@ OP_RETN:
|
||||||
jae err_memaccess
|
jae err_memaccess
|
||||||
mov frm,ebx
|
mov frm,ebx
|
||||||
add ebx,edi
|
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]
|
mov ebp,[edi+ecx]
|
||||||
lea ecx,[ecx+ebp+4]
|
lea ecx,[ecx+ebp+4]
|
||||||
GO_ON
|
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:
|
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]
|
lea ebp,[esi+8]
|
||||||
mov esi,[esi+4]
|
mov esi,[esi+4]
|
||||||
_PUSH ebp
|
_PUSH ebp
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
OP_CALL_PRI:
|
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]
|
lea ebp,[esi+4]
|
||||||
mov esi,eax
|
mov esi,eax
|
||||||
add esi,code ; cip = PRI + code
|
add esi,code ; cip = PRI + code
|
||||||
|
@ -928,7 +703,7 @@ OP_JGRTR:
|
||||||
|
|
||||||
OP_JGEQ:
|
OP_JGEQ:
|
||||||
cmp eax,edx
|
cmp eax,edx
|
||||||
jae short jump_taken ; unsigned comparison
|
jae short jump_taken ; unsigned comparison
|
||||||
add esi,8
|
add esi,8
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
|
@ -941,19 +716,19 @@ OP_JSLESS:
|
||||||
;good
|
;good
|
||||||
OP_JSLEQ:
|
OP_JSLEQ:
|
||||||
cmp eax,edx
|
cmp eax,edx
|
||||||
jle short jump_taken
|
jle near jump_taken
|
||||||
add esi,8
|
add esi,8
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
OP_JSGRTR:
|
OP_JSGRTR:
|
||||||
cmp eax,edx
|
cmp eax,edx
|
||||||
jg short jump_taken
|
jg near jump_taken
|
||||||
add esi,8
|
add esi,8
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
OP_JSGEQ:
|
OP_JSGEQ:
|
||||||
cmp eax,edx
|
cmp eax,edx
|
||||||
jge near jump_taken ; signed comparison
|
jge near jump_taken ; signed comparison
|
||||||
add esi,8
|
add esi,8
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
|
@ -1350,12 +1125,11 @@ OP_CMPS:
|
||||||
_VERIFYADDRESS eax ; PRI
|
_VERIFYADDRESS eax ; PRI
|
||||||
_VERIFYADDRESS edx ; ALT
|
_VERIFYADDRESS edx ; ALT
|
||||||
mov ebp,eax
|
mov ebp,eax
|
||||||
add ebp,[esi+4]
|
add ebp,[esi+4] ; size in bytes
|
||||||
dec ebp
|
dec ebp ; EBP = PRI + size - 1
|
||||||
_VERIFYADDRESS ebp ; PRI + size - 1
|
_VERIFYADDRESS ebp ; PRI + size - 1
|
||||||
mov ebp,edx
|
sub ebp,eax ; EBP = size - 1
|
||||||
add ebp,[esi+4]
|
add ebp,edx ; EBP = ALT + size - 1
|
||||||
dec ebp
|
|
||||||
_VERIFYADDRESS ebp ; ALT + size - 1
|
_VERIFYADDRESS ebp ; ALT + size - 1
|
||||||
|
|
||||||
push ecx
|
push ecx
|
||||||
|
@ -1422,19 +1196,6 @@ OP_HALT:
|
||||||
mov eax,esi ; EAX=CIP
|
mov eax,esi ; EAX=CIP
|
||||||
sub eax,code
|
sub eax,code
|
||||||
mov [ebp+_cip],eax
|
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
|
mov eax,ebx ; return the parameter of the HALT opcode
|
||||||
jmp _return
|
jmp _return
|
||||||
|
|
||||||
|
@ -1549,159 +1310,21 @@ OP_FILE:
|
||||||
|
|
||||||
OP_LINE:
|
OP_LINE:
|
||||||
add esi,12
|
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
|
GO_ON
|
||||||
|
|
||||||
|
|
||||||
OP_SYMBOL:
|
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,[esi+4]
|
||||||
add esi,8 ; skip "fixed" part
|
add esi,8 ; skip "fixed" part
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
|
|
||||||
OP_SRANGE:
|
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
|
add esi,12
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
|
|
||||||
OP_SYMTAG:
|
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
|
add esi,8
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
|
@ -1759,6 +1382,45 @@ OP_PUSHADDR:
|
||||||
|
|
||||||
|
|
||||||
OP_NOP:
|
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
|
GO_ON
|
||||||
|
|
||||||
|
|
||||||
|
@ -1796,7 +1458,7 @@ err_divide:
|
||||||
|
|
||||||
|
|
||||||
_return:
|
_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,amx ; get amx into ebp
|
||||||
mov [ebp+_pri],eax ; store values in AMX structure (PRI, ALT)
|
mov [ebp+_pri],eax ; store values in AMX structure (PRI, ALT)
|
||||||
mov [ebp+_alt],edx ; 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_NOP
|
||||||
DD OP_SYSREQ_D
|
DD OP_SYSREQ_D
|
||||||
DD OP_SYMTAG
|
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
|
; (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"
|
; I reached >155 million instr./sec on my AMD K6-2/366 with the Hanoi "bench"
|
||||||
|
@ -20,42 +21,78 @@
|
||||||
; step.
|
; step.
|
||||||
|
|
||||||
; NOTE 3:
|
; 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
|
; 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
|
; that there should always be enough memory left between HEA and STK to provide
|
||||||
; stack space for occurring interrupts! (see the STACKRESERVE variable)
|
; stack space for occurring interrupts! (see the STACKRESERVE variable)
|
||||||
|
|
||||||
; NOTE 4:
|
; 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
|
; 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
|
; 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.
|
; 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
|
; This version is the JIT that uses the "stack calling convention". In the
|
||||||
; original implementation, this meant __cdecl; both for the calling convention
|
; original implementation, this meant __cdecl; both for the calling convention
|
||||||
; for the _asm_runJIT routine itself as for the callback functions.
|
; for the _asm_runJIT routine itself as for the callback functions.
|
||||||
; The current release supports __stdcall for the callback functions; to
|
; 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
|
; a reserved word on the assembler, I had to choose a different name for the
|
||||||
; macro, hence STDECL.)
|
; macro, hence STDECL.)
|
||||||
|
|
||||||
; Revision History
|
; Revision History
|
||||||
;------------------
|
; ----------------
|
||||||
; 16 September 2004 by David "BAILOPAN" Anderson
|
; 17 february 2005 by Thiadmer Riemersms
|
||||||
; Implemented a compile time toggleable debug hook on OP_CALL and OP_RET.
|
; Addition of the BREAK opcode, removal of the older debugging opcode
|
||||||
; NOTE: JIT has not had debug hooks since 1999.
|
; table. There should now be some debug support (if enabled during the
|
||||||
; 8 September 2004 by David "BAILOPAN" Anderson
|
; build of the JIT compiler), but not enough to run a debugger: the JIT
|
||||||
; Changed OP_LINE call to be compile-time toggle-able between compiling
|
; compiler does not keep a list that relates the code addresses of the
|
||||||
; line ops or not.
|
; P-code versus the native code.
|
||||||
; 29 June 2004 by G.W.M. Vissers
|
; 29 June 2004 by G.W.M. Vissers
|
||||||
; Translated the thing into NASM. The actual generation of the code is
|
; Translated the thing into NASM. The actual generation of the code is
|
||||||
; put into the data section because the code modifies itself whereas the
|
; put into the data section because the code modifies itself whereas the
|
||||||
; text section is usually read-only in the Unix ELF format.
|
; text section is usually read-only in the Unix ELF format.
|
||||||
; 6 march 2004 by Thiadmer Riemersma
|
; 6 march 2004 by Thiadmer Riemersma
|
||||||
; Corrected a bug in OP_FILL, where a cell preceding the array would
|
; 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
|
; 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)
|
; 22 december 2003 by Thiadmer Riemersma (TR)
|
||||||
; Added the SYMTAG and SYSCALL.D opcodes (these are not really supported;
|
; Added the SYMTAG and SYSCALL.D opcodes (these are not really supported;
|
||||||
; SYMTAG is a no-op).
|
; SYMTAG is a no-op).
|
||||||
|
@ -94,8 +131,8 @@
|
||||||
; hanoi bench.
|
; hanoi bench.
|
||||||
; 1999/08/05 MP
|
; 1999/08/05 MP
|
||||||
; * fixed OP_LINE in the case of NODBGCALLS==1, where no compiled address
|
; * 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
|
; 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
|
; wrong addresses). The same fix was applied to OP_FILL, OP_FILE and
|
||||||
; OP_SCTRL (for the no-op case).
|
; OP_SCTRL (for the no-op case).
|
||||||
; 1999/08/04 MP
|
; 1999/08/04 MP
|
||||||
; * updated with 4 new opcodes (SRANGE does nothing at the moment; 2dim.
|
; * 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.
|
; to compute the destination address: It searches backwards now.
|
||||||
; 1999/07/08 MP - initial revision
|
; 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 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
|
; 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.
|
; 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
|
; 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
|
; GWMV: To disable runtime checks, %undef it, instread of setting it to zero
|
||||||
;
|
;
|
||||||
%define DORUNTIMECHECKS
|
%define DORUNTIMECHECKS
|
||||||
|
|
||||||
|
%define JIT 1
|
||||||
struc amx_s
|
%include "amxdefn.asm"
|
||||||
_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
|
|
||||||
|
|
||||||
; GWMV:
|
; 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
|
; esi is not determined at compile time
|
||||||
%define stk [esi+32] ; define some aliases to registers that will
|
%define stk [esi+32] ; define some aliases to registers that will
|
||||||
%define alt [esi+28] ; be stored on the stack when the code is
|
%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().)
|
; opcode. (See the following macro and the PUBLIC function getMaxCodeSize().)
|
||||||
;
|
;
|
||||||
; GWMV: Do NOT see the following macro. See CHECKCODESIZE instead.
|
; 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.
|
; 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
|
%macro GO_ON 2-3 4
|
||||||
mov esi, %1 ;get source address of JIT code
|
mov esi, %1 ;get source address of JIT code
|
||||||
mov ecx,%2-%1 ;get number of bytes to copy
|
mov ecx,%2-%1 ;get number of bytes to copy
|
||||||
mov [ebx],edi ;store address for jump-correction
|
mov [ebx],edi ;store address for jump-correction
|
||||||
add ebx,%3
|
add ebx,%3
|
||||||
rep movsb
|
rep movsb
|
||||||
cmp ebx,[end_code]
|
cmp ebx,[end_code]
|
||||||
jae code_gen_done
|
jae code_gen_done
|
||||||
jmp dword [ebx] ;go on with the next opcode
|
jmp dword [ebx] ;go on with the next opcode
|
||||||
|
@ -300,9 +237,7 @@ AMX_FLAG_RELOC equ 8000h ; jump/call addresses relocated
|
||||||
; GWMV:
|
; GWMV:
|
||||||
; Nasm can't handle the determination of the maximum code size as was done
|
; 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
|
; in the Masm implementation, since it only does two passes. This macro is
|
||||||
; called *after* the code for each Small instruction.
|
; called *after* the code for each Pawn instruction.
|
||||||
; Notes by ~dvander: This just substracts a label's ip from the current ip.
|
|
||||||
; Therefore you get an instant size check - see RELOC
|
|
||||||
%macro CHECKCODESIZE 1
|
%macro CHECKCODESIZE 1
|
||||||
%if MAXCODESIZE < $-%1
|
%if MAXCODESIZE < $-%1
|
||||||
%assign MAXCODESIZE $-%1
|
%assign MAXCODESIZE $-%1
|
||||||
|
@ -310,14 +245,9 @@ AMX_FLAG_RELOC equ 8000h ; jump/call addresses relocated
|
||||||
%endmacro
|
%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.
|
; 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
|
%macro putval 1
|
||||||
mov eax,[ebx+4]
|
mov eax,[ebx+4]
|
||||||
mov dword [%1],eax
|
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
|
; Add an entry to the table of addresses which have to be relocated after the
|
||||||
; code compilation is done.
|
; 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
|
%macro RELOC 1-2 ; adr, dest
|
||||||
mov ebp,[reloc_num]
|
mov ebp,[reloc_num]
|
||||||
%if %0 < 2
|
%if %0 < 2
|
||||||
mov eax,[ebx+4]
|
mov eax,[ebx+4]
|
||||||
%else
|
%else
|
||||||
lea eax,[%2]
|
lea eax,[%2]
|
||||||
%endif
|
%endif
|
||||||
mov [edx+ebp],eax ; write absolute destination
|
mov [edx+ebp],eax ; write absolute destination
|
||||||
|
@ -356,7 +281,7 @@ section .text
|
||||||
|
|
||||||
|
|
||||||
global asm_runJIT, _asm_runJIT
|
global asm_runJIT, _asm_runJIT
|
||||||
global amx_exec_asm, _amx_exec_asm
|
global amx_exec_jit, _amx_exec_jit
|
||||||
global getMaxCodeSize, _getMaxCodeSize
|
global getMaxCodeSize, _getMaxCodeSize
|
||||||
|
|
||||||
|
|
||||||
|
@ -381,7 +306,7 @@ _asm_runJIT:
|
||||||
mov eax,[esp+20] ; get amxh
|
mov eax,[esp+20] ; get amxh
|
||||||
mov edx,[esp+24] ; get jumps array
|
mov edx,[esp+24] ; get jumps array
|
||||||
mov ebx,[esp+28] ; get destination
|
mov ebx,[esp+28] ; get destination
|
||||||
|
|
||||||
mov [amxhead],eax ; save pointer to AMX_HEADER struct
|
mov [amxhead],eax ; save pointer to AMX_HEADER struct
|
||||||
mov ecx,[eax+_cod] ; get offset of start of code
|
mov ecx,[eax+_cod] ; get offset of start of code
|
||||||
mov eax,[eax+_dat] ; offset of start of data = end of code
|
mov eax,[eax+_dat] ; offset of start of data = end of code
|
||||||
|
@ -481,9 +406,9 @@ reloc_done:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; GWMV:
|
; 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
|
; 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
|
section .data exec
|
||||||
|
|
||||||
|
@ -817,7 +742,7 @@ OP_ALIGN_PRI:
|
||||||
CHECKCODESIZE j_align_pri
|
CHECKCODESIZE j_align_pri
|
||||||
|
|
||||||
OP_ALIGN_ALT:
|
OP_ALIGN_ALT:
|
||||||
;nop
|
;nop;
|
||||||
mov eax,4
|
mov eax,4
|
||||||
sub eax,[ebx+4]
|
sub eax,[ebx+4]
|
||||||
mov dword [j_align_alt+1],eax
|
mov dword [j_align_alt+1],eax
|
||||||
|
@ -1045,7 +970,7 @@ OP_HEAP:
|
||||||
call [chk_marginheap]
|
call [chk_marginheap]
|
||||||
%endif
|
%endif
|
||||||
CHECKCODESIZE j_heap
|
CHECKCODESIZE j_heap
|
||||||
|
|
||||||
;good
|
;good
|
||||||
OP_PROC:
|
OP_PROC:
|
||||||
;nop;
|
;nop;
|
||||||
|
@ -1073,119 +998,22 @@ OP_RET:
|
||||||
;good
|
;good
|
||||||
OP_RETN:
|
OP_RETN:
|
||||||
;nop;
|
;nop;
|
||||||
;save registers
|
GO_ON j_retn, OP_CALL
|
||||||
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_jit_retn_nodebug:
|
j_retn:
|
||||||
GO_ON j_retn_nodebug, _go_jit_retn_go
|
|
||||||
j_retn_nodebug:
|
|
||||||
jmp [jit_retn]
|
jmp [jit_retn]
|
||||||
CHECKCODESIZE j_retn_nodebug
|
CHECKCODESIZE j_retn
|
||||||
_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:
|
|
||||||
|
|
||||||
;good
|
;good
|
||||||
OP_CALL:
|
OP_CALL:
|
||||||
;nop;
|
;nop;
|
||||||
;save registers
|
RELOC 1
|
||||||
push eax
|
GO_ON j_call, OP_CALL_I, 8
|
||||||
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
|
|
||||||
|
|
||||||
_go_jit_nodebug:
|
j_call:
|
||||||
RELOC 1
|
;call 12345678h ; tasm chokes on this out of a sudden
|
||||||
GO_ON j_call_nodebug, _j_call_go_on, 8
|
db 0e8h, 0, 0, 0, 0
|
||||||
j_call_nodebug:
|
CHECKCODESIZE j_call
|
||||||
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:
|
|
||||||
|
|
||||||
OP_CALL_I:
|
OP_CALL_I:
|
||||||
;nop;
|
;nop;
|
||||||
|
@ -1857,39 +1685,12 @@ OP_FILE: ;opcode is simply ignored
|
||||||
|
|
||||||
OP_LINE:
|
OP_LINE:
|
||||||
;nop;
|
;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
|
mov [ebx],edi ; no line number support: ignore opcode
|
||||||
add ebx,12 ; move on to next opcode
|
add ebx,12 ; move on to next opcode
|
||||||
cmp ebx,[end_code]
|
cmp ebx,[end_code]
|
||||||
jae code_gen_done
|
jae code_gen_done
|
||||||
jmp dword [ebx] ; go on with the next opcode
|
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
|
OP_SYMBOL: ;ignored
|
||||||
mov [ebx],edi
|
mov [ebx],edi
|
||||||
mov eax,[ebx+4] ; get size
|
mov eax,[ebx+4] ; get size
|
||||||
|
@ -2019,6 +1820,23 @@ OP_SYMTAG: ;ignored (TR)
|
||||||
jmp dword [ebx] ; go on with the next opcode
|
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
|
OP_INVALID: ; break from the compiler with an error code
|
||||||
mov eax,AMX_ERR_INVINSTR
|
mov eax,AMX_ERR_INVINSTR
|
||||||
pop esi
|
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 ;
|
; eax edx ebx ecx ;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
amx_exec_asm:
|
amx_exec_jit:
|
||||||
_amx_exec_asm:
|
_amx_exec_jit:
|
||||||
push edi
|
push edi
|
||||||
push esi
|
push esi
|
||||||
push ebp
|
push ebp
|
||||||
|
@ -2338,20 +2156,39 @@ JIT_OP_SYSREQ_D: ; (TR)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
JIT_OP_LINE:
|
JIT_OP_BREAK:
|
||||||
pop ecx ; get return address
|
%ifdef DEBUGSUPPORT
|
||||||
mov ebp,amx
|
mov ecx,esp ; get STK into ECX
|
||||||
push eax
|
mov ebp,amx ; get amx into EBP
|
||||||
push edx
|
|
||||||
mov eax,[ecx] ; get curline
|
sub ecx,edi ; correct STK
|
||||||
mov edx,[ecx+4] ; get curfile
|
|
||||||
add ecx,8 ; skip curline & curfile
|
mov [ebp+_pri],eax ; store values in AMX structure: PRI,
|
||||||
mov [ebp+_curline],eax ; store curline
|
mov [ebp+_alt],edx ; ALT,
|
||||||
mov [ebp+_curfile],edx ; store curfile
|
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:
|
JIT_OP_SWITCH:
|
||||||
pop ebp ; pop return address = table address
|
pop ebp ; pop return address = table address
|
||||||
|
@ -2370,9 +2207,10 @@ JIT_OP_SWITCH:
|
||||||
jmp ebp
|
jmp ebp
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
|
||||||
; The caller of asm_runJIT() can determine the maximum size of the compiled
|
; 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
|
; code by multiplying the result of this function by the number of opcodes in
|
||||||
; Small module.
|
; Pawn module.
|
||||||
;
|
;
|
||||||
; unsigned long getMaxCodeSize_();
|
; unsigned long getMaxCodeSize_();
|
||||||
;
|
;
|
||||||
|
@ -2414,17 +2252,17 @@ jit_fill DD JIT_OP_FILL
|
||||||
jit_bounds DD JIT_OP_BOUNDS
|
jit_bounds DD JIT_OP_BOUNDS
|
||||||
jit_sysreq DD JIT_OP_SYSREQ
|
jit_sysreq DD JIT_OP_SYSREQ
|
||||||
jit_sysreq_d DD JIT_OP_SYSREQ_D
|
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
|
jit_switch DD JIT_OP_SWITCH
|
||||||
|
|
||||||
;
|
;
|
||||||
; The table for the browser/relocator function.
|
; The table for the browser/relocator function.
|
||||||
;
|
;
|
||||||
|
|
||||||
global amx_opcodelist, _amx_opcodelist
|
global amx_opcodelist_jit, _amx_opcodelist_jit
|
||||||
|
|
||||||
amx_opcodelist:
|
amx_opcodelist_jit:
|
||||||
_amx_opcodelist:
|
_amx_opcodelist_jit:
|
||||||
DD OP_INVALID
|
DD OP_INVALID
|
||||||
DD OP_LOAD_PRI
|
DD OP_LOAD_PRI
|
||||||
DD OP_LOAD_ALT
|
DD OP_LOAD_ALT
|
||||||
|
@ -2562,3 +2400,6 @@ _amx_opcodelist:
|
||||||
DD OP_NOP ; TR
|
DD OP_NOP ; TR
|
||||||
DD OP_SYSREQ_D ; TR
|
DD OP_SYSREQ_D ; TR
|
||||||
DD OP_SYMTAG ; 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)
|
static cell AMX_NATIVE_CALL is_amd64_server(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
#if SMALL_CELL_SIZE==64
|
#if PAWN_CELL_SIZE==64
|
||||||
return 1;
|
return 1;
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -794,10 +794,11 @@ static cell AMX_NATIVE_CALL register_menucmd(AMX *amx, cell *params) /* 3 param
|
||||||
int ilen, idx;
|
int ilen, idx;
|
||||||
char* sptemp = get_amxstring(amx,params[3],0,ilen);
|
char* sptemp = get_amxstring(amx,params[3],0,ilen);
|
||||||
|
|
||||||
if(amx_FindPublic(amx, sptemp ,&idx)!=AMX_ERR_NONE) {
|
idx = registerSPForwardByName(amx, sptemp, FP_CELL, FP_CELL, FP_DONE);
|
||||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",sptemp,plugin->getName() );
|
if (idx == -1)
|
||||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
{
|
||||||
return 0;
|
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", sptemp);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_menucmds.registerMenuCmd( plugin , params[1] , params[2] , idx );
|
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 );
|
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx );
|
||||||
int i, idx = 0;
|
int i, idx = 0;
|
||||||
char* temp = get_amxstring(amx,params[2],0, i );
|
char* temp = get_amxstring(amx,params[2],0, i );
|
||||||
if(amx_FindPublic(amx, temp ,&idx)!=AMX_ERR_NONE) {
|
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",temp,plugin->getName() );
|
if (idx == -1)
|
||||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
{
|
||||||
|
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
temp = get_amxstring(amx,params[1],0, i );
|
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 );
|
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx );
|
||||||
int i, idx = 0;
|
int i, idx = 0;
|
||||||
char* temp = get_amxstring(amx,params[2],0, i );
|
char* temp = get_amxstring(amx,params[2],0, i );
|
||||||
if(amx_FindPublic(amx, temp ,&idx)!=AMX_ERR_NONE) {
|
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",temp,plugin->getName() );
|
if(idx==-1)
|
||||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
{
|
||||||
|
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
temp = get_amxstring(amx,params[1],0, i );
|
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 );
|
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast( amx );
|
||||||
int i, idx = 0;
|
int i, idx = 0;
|
||||||
char* temp = get_amxstring(amx,params[2],0, i );
|
char* temp = get_amxstring(amx,params[2],0, i );
|
||||||
if(amx_FindPublic(amx, temp ,&idx)!=AMX_ERR_NONE) {
|
idx = registerSPForwardByName(amx, temp, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",temp,plugin->getName() );
|
if (idx==-1)
|
||||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
{
|
||||||
|
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
temp = get_amxstring(amx,params[1],0, i );
|
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);
|
sTemp = get_amxstring(amx,params[2],0,len);
|
||||||
|
iFunction = registerSPForwardByName(amx, sTemp, FP_CELL, FP_DONE);
|
||||||
if ( amx_FindPublic(amx, sTemp , &iFunction) != AMX_ERR_NONE){
|
if (iFunction==-1)
|
||||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",sTemp,plugin->getName() );
|
{
|
||||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", sTemp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1874,20 +1878,9 @@ static cell AMX_NATIVE_CALL pause(AMX *amx, cell *params) /* 3 param */
|
||||||
|
|
||||||
CPluginMngr::CPlugin *plugin = 0;
|
CPluginMngr::CPlugin *plugin = 0;
|
||||||
|
|
||||||
if ( flags & 2 ) { // pause function
|
if ( flags & 2 )
|
||||||
if (flags&4){ //look out side the plugin
|
{ // pause function
|
||||||
temp = get_amxstring(amx,params[3],0,ilen);
|
AMXXLOG_Log("[AMXX] This usage of the native pause() has been deprecated!");
|
||||||
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 );
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (flags&4){
|
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);
|
char* sptemp = get_amxstring(amx,params[1],0,ilen);
|
||||||
int flags = UTIL_ReadFlags(sptemp);
|
int flags = UTIL_ReadFlags(sptemp);
|
||||||
CPluginMngr::CPlugin *plugin = 0;
|
CPluginMngr::CPlugin *plugin = 0;
|
||||||
if (flags&2) {
|
if (flags&2)
|
||||||
if (flags&4){
|
{
|
||||||
sptemp = get_amxstring(amx,params[3],0,ilen);
|
AMXXLOG_Log("[AMXX] This usage of the native pause() has been deprecated!");
|
||||||
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 );
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else if (flags&4) {
|
||||||
else if (flags&4){
|
|
||||||
sptemp = get_amxstring(amx,params[2],0,ilen);
|
sptemp = get_amxstring(amx,params[2],0,ilen);
|
||||||
plugin = g_plugins.findPlugin(sptemp);
|
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 );
|
char* temp = get_amxstring(amx,params[1],0, a );
|
||||||
|
|
||||||
if (amx_FindPublic(amx, temp , &iFunc) != AMX_ERR_NONE){
|
iFunc = registerSPForwardByName(amx, temp, FP_DONE);
|
||||||
AMXXLOG_Log("[AMXX] Function is not present (function \"%s\") (plugin \"%s\")",
|
if (iFunc == -1)
|
||||||
temp,plugin->getName() );
|
{
|
||||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", temp);
|
||||||
return 0;
|
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[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[4], info && info->author ? info->author : "unk", params[5]);
|
||||||
set_amxstring(amx, params[6], info && info->version ? info->version : "unk", params[7]);
|
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
|
// compatibility problem possible
|
||||||
int numParams = params[0] / sizeof(cell);
|
int numParams = params[0] / sizeof(cell);
|
||||||
if (numParams < 8)
|
if (numParams < 8)
|
||||||
{
|
{
|
||||||
CPluginMngr::CPlugin *curPlugin = g_plugins.findPluginFast(amx);
|
LogError(amx, AMX_ERR_NATIVE, "Call to incompatible version");
|
||||||
AMXXLOG_Log("[AMXX] get_module: call to a previous version (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
return 0;
|
||||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set status
|
// set status
|
||||||
cell *addr;
|
cell *addr;
|
||||||
if (amx_GetAddr(amx, params[8], &addr) != AMX_ERR_NONE)
|
if (amx_GetAddr(amx, params[8], &addr) != AMX_ERR_NONE)
|
||||||
{
|
{
|
||||||
CPluginMngr::CPlugin *curPlugin = g_plugins.findPluginFast(amx);
|
LogError(amx, AMX_ERR_NATIVE, "Invalid reference plugin");
|
||||||
AMXXLOG_Log("[AMXX] get_module: invalid reference (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
return 0;
|
||||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*addr = (cell)(*moduleIter).getStatusValue();
|
*addr = (cell)(*moduleIter).getStatusValue();
|
||||||
|
@ -2526,8 +2497,7 @@ static cell AMX_NATIVE_CALL callfunc_begin(AMX *amx, cell *params)
|
||||||
if (g_CallFunc_Plugin)
|
if (g_CallFunc_Plugin)
|
||||||
{
|
{
|
||||||
// scripter's fault
|
// scripter's fault
|
||||||
AMXXLOG_Log("[AMXX] callfunc_begin called without callfunc_end (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_begin called without callfunc_end");
|
||||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2608,8 +2578,7 @@ static cell AMX_NATIVE_CALL callfunc_end(AMX *amx, cell *params)
|
||||||
if (!g_CallFunc_Plugin)
|
if (!g_CallFunc_Plugin)
|
||||||
{
|
{
|
||||||
// scripter's fault
|
// scripter's fault
|
||||||
AMXXLOG_Log("[AMXX] callfunc_end called without callfunc_begin (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_end called without callfunc_begin");
|
||||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2633,9 +2602,13 @@ static cell AMX_NATIVE_CALL callfunc_end(AMX *amx, cell *params)
|
||||||
g_CallFunc_CurParam = 0;
|
g_CallFunc_CurParam = 0;
|
||||||
|
|
||||||
// actual call
|
// 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2672,8 +2645,7 @@ static cell AMX_NATIVE_CALL callfunc_push_byval(AMX *amx, cell *params)
|
||||||
if (!g_CallFunc_Plugin)
|
if (!g_CallFunc_Plugin)
|
||||||
{
|
{
|
||||||
// scripter's fault
|
// scripter's fault
|
||||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx called without callfunc_begin (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx called without callfunc_begin");
|
||||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2698,15 +2670,13 @@ static cell AMX_NATIVE_CALL callfunc_push_byref(AMX *amx, cell *params)
|
||||||
if (!g_CallFunc_Plugin)
|
if (!g_CallFunc_Plugin)
|
||||||
{
|
{
|
||||||
// scripter's fault
|
// scripter's fault
|
||||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx called without callfunc_begin (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx called without callfunc_begin");
|
||||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_CallFunc_CurParam == CALLFUNC_MAXPARAMS)
|
if (g_CallFunc_CurParam == CALLFUNC_MAXPARAMS)
|
||||||
{
|
{
|
||||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
||||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2756,15 +2726,13 @@ static cell AMX_NATIVE_CALL callfunc_push_str(AMX *amx, cell *params)
|
||||||
if (!g_CallFunc_Plugin)
|
if (!g_CallFunc_Plugin)
|
||||||
{
|
{
|
||||||
// scripter's fault
|
// scripter's fault
|
||||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx called without callfunc_begin (plugin \"%s\", line %d)", curPlugin->getName(), amx->curline);
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx called without callfunc_begin");
|
||||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_CallFunc_CurParam == CALLFUNC_MAXPARAMS)
|
if (g_CallFunc_CurParam == CALLFUNC_MAXPARAMS)
|
||||||
{
|
{
|
||||||
AMXXLOG_Log("[AMXX] callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
LogError(amx, AMX_ERR_NATIVE, "callfunc_push_xxx: maximal parameters num: %d", CALLFUNC_MAXPARAMS);
|
||||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2799,7 +2767,7 @@ static cell AMX_NATIVE_CALL callfunc_push_str(AMX *amx, cell *params)
|
||||||
// copy it to the allocated memory
|
// copy it to the allocated memory
|
||||||
// we assume it's unpacked
|
// we assume it's unpacked
|
||||||
// :NOTE: 4th parameter use_wchar since Small Abstract Machine 2.5.0
|
// :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.
|
// 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;
|
g_CallFunc_ParamInfo[g_CallFunc_CurParam].flags = CALLFUNC_FLAG_BYREF;
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
#include "amxxlog.h"
|
#include "amxxlog.h"
|
||||||
|
|
||||||
#define AMXXLOG_Log g_log.Log
|
#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 core_Natives[];
|
||||||
extern AMX_NATIVE_INFO time_Natives[];
|
extern AMX_NATIVE_INFO time_Natives[];
|
||||||
|
@ -244,7 +244,6 @@ enum CountModulesMode
|
||||||
int countModules(CountModulesMode mode);
|
int countModules(CountModulesMode mode);
|
||||||
void modules_callPluginsLoaded();
|
void modules_callPluginsLoaded();
|
||||||
|
|
||||||
int add_amxnatives(module_info_s* info,AMX_NATIVE_INFO*natives);
|
|
||||||
cell* get_amxaddr(AMX *amx,cell amx_addr);
|
cell* get_amxaddr(AMX *amx,cell amx_addr);
|
||||||
char* build_pathname(char *fmt, ... );
|
char* build_pathname(char *fmt, ... );
|
||||||
char* build_pathname_r(char *buffer, size_t maxlen, 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 CModule *g_CurrentlyCalledModule; // modules.cpp
|
||||||
extern const char *g_LastRequestedFunc; // modules.cpp
|
extern const char *g_LastRequestedFunc; // modules.cpp
|
||||||
void Module_CacheFunctions();
|
void Module_CacheFunctions();
|
||||||
|
void Module_UncacheFunctions();
|
||||||
|
|
||||||
void *Module_ReqFnptr(const char *funcName); // modules.cpp
|
void *Module_ReqFnptr(const char *funcName); // modules.cpp
|
||||||
|
|
||||||
|
@ -297,6 +297,7 @@ extern int FF_PluginLog;
|
||||||
extern int FF_PluginEnd;
|
extern int FF_PluginEnd;
|
||||||
extern int FF_InconsistentFile;
|
extern int FF_InconsistentFile;
|
||||||
extern int FF_ClientAuthorized;
|
extern int FF_ClientAuthorized;
|
||||||
|
extern bool g_coloredmenus;
|
||||||
|
|
||||||
#ifdef FAKEMETA
|
#ifdef FAKEMETA
|
||||||
extern CFakeMeta g_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)
|
static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
@ -394,6 +381,20 @@ static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
|
||||||
return -1;
|
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)
|
static cell AMX_NATIVE_CALL amx_fwrite(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
@ -506,6 +507,7 @@ static cell AMX_NATIVE_CALL amx_ftell(AMX *amx, cell *params)
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif //UNUSED
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef UNUSED
|
||||||
static cell AMX_NATIVE_CALL amx_fgetl(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fgetl(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
@ -636,6 +639,7 @@ static cell AMX_NATIVE_CALL amx_fputf(AMX *amx, cell *params)
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif //UNUSED
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_build_pathname(AMX *amx, cell *params)
|
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
|
//Sanji's File Natives
|
||||||
{ "fopen", amx_fopen },
|
{ "fopen", amx_fopen },
|
||||||
{ "fclose", amx_fclose },
|
{ "fclose", amx_fclose },
|
||||||
{ "fgetc", amx_fgetc },
|
|
||||||
{ "fread", amx_fread },
|
{ "fread", amx_fread },
|
||||||
|
{ "filesize", amx_filesize },
|
||||||
|
#ifdef UNUSED
|
||||||
|
{ "fgetc", amx_fgetc },
|
||||||
{ "fwrite", amx_fwrite },
|
{ "fwrite", amx_fwrite },
|
||||||
{ "feof", amx_feof },
|
{ "feof", amx_feof },
|
||||||
{ "fseek", amx_fseek },
|
{ "fseek", amx_fseek },
|
||||||
|
@ -733,16 +739,16 @@ AMX_NATIVE_INFO file_Natives[] = {
|
||||||
{ "fflush", amx_fflush },
|
{ "fflush", amx_fflush },
|
||||||
{ "fscanf", amx_fscanf },
|
{ "fscanf", amx_fscanf },
|
||||||
{ "ftell", amx_ftell },
|
{ "ftell", amx_ftell },
|
||||||
{ "filesize", amx_filesize },
|
|
||||||
{ "fgetl", amx_fgetl },
|
{ "fgetl", amx_fgetl },
|
||||||
{ "fgeti", amx_fgeti },
|
{ "fgeti", amx_fgeti },
|
||||||
{ "fgets", amx_fgets },
|
{ "fgets", amx_fgets },
|
||||||
{ "fputs", amx_fputs },
|
{ "fputs", amx_fputs },
|
||||||
{ "fputl", amx_fputl },
|
{ "fputl", amx_fputl },
|
||||||
{ "fputi", amx_fputi },
|
{ "fputi", amx_fputi },
|
||||||
{ "unlink", delete_file },
|
|
||||||
{ "fgetf", amx_fgetf },
|
{ "fgetf", amx_fgetf },
|
||||||
{ "fputf", amx_fputf },
|
{ "fputf", amx_fputf },
|
||||||
|
#endif
|
||||||
|
{ "unlink", delete_file },
|
||||||
{ "build_pathname", amx_build_pathname},
|
{ "build_pathname", amx_build_pathname},
|
||||||
{ "dir_exists", dir_exists },
|
{ "dir_exists", dir_exists },
|
||||||
{ "open_dir", amx_open_dir },
|
{ "open_dir", amx_open_dir },
|
||||||
|
|
|
@ -96,7 +96,7 @@ static cell AMX_NATIVE_CALL n_floatstr(AMX *amx,cell *params)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Now convert the Small String into a C type null terminated string */
|
/* 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. */
|
/* Now convert this to a float. */
|
||||||
fNum = (REAL)atof(szSource);
|
fNum = (REAL)atof(szSource);
|
||||||
|
|
|
@ -90,6 +90,7 @@ float g_auth_time;
|
||||||
bool g_initialized = false;
|
bool g_initialized = false;
|
||||||
bool g_IsNewMM = false;
|
bool g_IsNewMM = false;
|
||||||
bool g_NeedsP = false;
|
bool g_NeedsP = false;
|
||||||
|
bool g_coloredmenus;
|
||||||
|
|
||||||
#ifdef MEMORY_TEST
|
#ifdef MEMORY_TEST
|
||||||
float g_next_memreport_time;
|
float g_next_memreport_time;
|
||||||
|
@ -605,7 +606,6 @@ void C_ClientCommand( edict_t *pEntity ) {
|
||||||
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
|
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
|
||||||
META_RES result = MRES_IGNORED;
|
META_RES result = MRES_IGNORED;
|
||||||
cell ret = 0;
|
cell ret = 0;
|
||||||
int err;
|
|
||||||
const char* cmd = CMD_ARGV(0);
|
const char* cmd = CMD_ARGV(0);
|
||||||
const char* arg = CMD_ARGV(1);
|
const char* arg = CMD_ARGV(1);
|
||||||
|
|
||||||
|
@ -665,10 +665,7 @@ void C_ClientCommand( edict_t *pEntity ) {
|
||||||
if ( (*aa).matchCommandLine( cmd , arg ) &&
|
if ( (*aa).matchCommandLine( cmd , arg ) &&
|
||||||
(*aa).getPlugin()->isExecutable( (*aa).getFunction() ) )
|
(*aa).getPlugin()->isExecutable( (*aa).getFunction() ) )
|
||||||
{
|
{
|
||||||
|
ret = executeForwards((*aa).getFunction(), pPlayer->index, (*aa).getFlags(), (*aa).getId());
|
||||||
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, "");
|
|
||||||
|
|
||||||
if ( ret & 2 ) result = MRES_SUPERCEDE;
|
if ( ret & 2 ) result = MRES_SUPERCEDE;
|
||||||
if ( ret & 1 ) RETURN_META(MRES_SUPERCEDE);
|
if ( ret & 1 ) RETURN_META(MRES_SUPERCEDE);
|
||||||
}
|
}
|
||||||
|
@ -695,33 +692,19 @@ void C_ClientCommand( edict_t *pEntity ) {
|
||||||
int menuid = pPlayer->menu;
|
int menuid = pPlayer->menu;
|
||||||
pPlayer->menu = 0;
|
pPlayer->menu = 0;
|
||||||
|
|
||||||
#ifdef ENABLEEXEPTIONS
|
|
||||||
try{
|
|
||||||
#endif
|
|
||||||
MenuMngr::iterator a = g_menucmds.begin();
|
MenuMngr::iterator a = g_menucmds.begin();
|
||||||
|
|
||||||
while( a )
|
while( a )
|
||||||
{
|
{
|
||||||
if ( (*a).matchCommand( menuid , bit_key ) && (*a).getPlugin()->isExecutable( (*a).getFunction() ) )
|
if ( (*a).matchCommand( menuid , bit_key ) && (*a).getPlugin()->isExecutable( (*a).getFunction() ) )
|
||||||
{
|
{
|
||||||
|
ret = executeForwards((*a).getFunction(), pPlayer->index, pressed_key);
|
||||||
if ( ( err = amx_Exec((*a).getPlugin()->getAMX(), &ret ,(*a).getFunction() , 2, pPlayer->index,pressed_key)) != AMX_ERR_NONE)
|
|
||||||
LogError((*a).getPlugin()->getAMX(), err, "");
|
|
||||||
|
|
||||||
if ( ret & 2 ) result = MRES_SUPERCEDE;
|
if ( ret & 2 ) result = MRES_SUPERCEDE;
|
||||||
if ( ret & 1 ) RETURN_META(MRES_SUPERCEDE);
|
if ( ret & 1 ) RETURN_META(MRES_SUPERCEDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
++a;
|
++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 */
|
/* 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) {
|
void C_MessageEnd_Post(void) {
|
||||||
g_events.executeEvents();
|
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);
|
if (endfunction) (*endfunction)(NULL);
|
||||||
RETURN_META(MRES_IGNORED);
|
RETURN_META(MRES_IGNORED);
|
||||||
}
|
}
|
||||||
|
@ -1134,6 +1088,13 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
|
||||||
a = &gameDir[i];
|
a = &gameDir[i];
|
||||||
g_mod_name.assign(a);
|
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 short GPL
|
||||||
print_srvconsole( "\n AMX Mod X version %s Copyright (c) 2004-2005 AMX Mod X Development Team \n"
|
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);
|
" 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();
|
g_log.CloseFile();
|
||||||
|
|
||||||
|
Module_UncacheFunctions();
|
||||||
|
|
||||||
return(TRUE);
|
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)
|
int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug)
|
||||||
{
|
{
|
||||||
*error = 0;
|
*error = 0;
|
||||||
CAmxxReader reader(filename, SMALL_CELL_SIZE / 8);
|
CAmxxReader reader(filename, PAWN_CELL_SIZE / 8);
|
||||||
if (reader.GetStatus() == CAmxxReader::Err_None)
|
if (reader.GetStatus() == CAmxxReader::Err_None)
|
||||||
{
|
{
|
||||||
size_t bufSize = reader.GetBufferSize();
|
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);
|
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;
|
int err;
|
||||||
memset(amx, 0, sizeof(*amx));
|
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)
|
if ((err = amx_Init( amx, *program )) != AMX_ERR_NONE)
|
||||||
{
|
{
|
||||||
sprintf(error,"Load error %d (invalid file format or version)", err);
|
sprintf(error,"Load error %d (invalid file format or version)", err);
|
||||||
return (amx->error = AMX_ERR_INIT);
|
return (amx->error = AMX_ERR_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JIT
|
LOG_MESSAGE(PLID, "AMX: %p FLAGS: %d\n", amx, amx->flags);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 );
|
char *np = new char[ amx->code_size ];
|
||||||
#ifndef __linux__
|
char *rt = new char[ amx->reloc_size ];
|
||||||
amx->base = new unsigned char[ amx->code_size ];
|
if ( !np || (!rt && amx->reloc_size > 0) )
|
||||||
#else
|
{
|
||||||
//posix_memalign((void **)&(amx->base), sysconf(_SC_PAGESIZE), amx->code_size);
|
delete[] np;
|
||||||
amx->base = (unsigned char *)memalign(sysconf(_SC_PAGESIZE), amx->code_size);
|
delete[] rt;
|
||||||
mprotect((void *)amx->base, amx->code_size, PROT_READ|PROT_WRITE|PROT_EXEC);
|
strcpy(error,"Failed to initialize plugin");
|
||||||
#endif
|
return (amx->error = AMX_ERR_INIT);
|
||||||
if ( amx->base )
|
}
|
||||||
memcpy( amx->base , np , amx->code_size );
|
|
||||||
delete[] np;
|
if ( (err = amx_InitJIT(amx, (void *)rt, (void *)np)) == AMX_ERR_NONE )
|
||||||
delete[] rt;
|
{
|
||||||
delete[] *program;
|
//amx->base = (unsigned char FAR *)realloc( np, amx->code_size );
|
||||||
(*program) = amx->base;
|
#ifndef __linux__
|
||||||
if ( *program == 0 ){
|
amx->base = new unsigned char[ amx->code_size ];
|
||||||
strcpy(error,"Failed to allocate memory");
|
#else
|
||||||
return (amx->error = AMX_ERR_MEMORY);
|
//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
|
#endif
|
||||||
|
@ -219,7 +232,6 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
||||||
}
|
}
|
||||||
|
|
||||||
g_loadedscripts.put( aa );
|
g_loadedscripts.put( aa );
|
||||||
amx->sysreq_d = 0;
|
|
||||||
return set_amxnatives(amx,error);
|
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 );
|
CList<CScript,AMX*>::iterator a = g_loadedscripts.find( amx );
|
||||||
if ( a ) a.remove();
|
if ( a ) a.remove();
|
||||||
delete[] *program;
|
char *prg = (char *)*program;
|
||||||
|
delete[] *prg;
|
||||||
*program = 0;
|
*program = 0;
|
||||||
return AMX_ERR_NONE;
|
return AMX_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -469,27 +482,6 @@ char* build_pathname_addons(char *fmt, ... )
|
||||||
return string;
|
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)
|
bool validFile(const char* file)
|
||||||
{
|
{
|
||||||
const char* a = 0;
|
const char* a = 0;
|
||||||
|
@ -505,7 +497,7 @@ bool validFile(const char* file)
|
||||||
|
|
||||||
void ConvertModuleName(const char *pathString, String &path)
|
void ConvertModuleName(const char *pathString, String &path)
|
||||||
{
|
{
|
||||||
#if SMALL_CELL_SIZE==64
|
#if PAWN_CELL_SIZE==64
|
||||||
char *ptr = strstr(pathString, "i386");
|
char *ptr = strstr(pathString, "i386");
|
||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
|
@ -600,7 +592,7 @@ void ConvertModuleName(const char *pathString, String &path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif //__linux__
|
#endif //__linux__
|
||||||
#endif //SMALL_CELL_SIZE==64
|
#endif //PAWN_CELL_SIZE==64
|
||||||
}
|
}
|
||||||
|
|
||||||
int loadModules(const char* filename, PLUG_LOADTIME now)
|
int loadModules(const char* filename, PLUG_LOADTIME now)
|
||||||
|
@ -930,10 +922,14 @@ int MNF_AddNatives(AMX_NATIVE_INFO* natives)
|
||||||
|
|
||||||
const char *MNF_GetModname(void)
|
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];
|
static char buffer[64];
|
||||||
strcpy(buffer, g_mod_name.c_str());
|
strcpy(buffer, g_mod_name.c_str());
|
||||||
return buffer;
|
return buffer;
|
||||||
|
#endif
|
||||||
|
return g_mod_name.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
AMX *MNF_GetAmxScript(int id)
|
AMX *MNF_GetAmxScript(int id)
|
||||||
|
@ -1169,13 +1165,17 @@ REAL MNF_CellToReal(cell x)
|
||||||
return *(REAL*)&x;
|
return *(REAL*)&x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#define _vsnprintf vsnprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
void MNF_Log(const char *fmt, ...)
|
void MNF_Log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
// :TODO: Overflow possible here
|
|
||||||
char msg[3072];
|
char msg[3072];
|
||||||
va_list arglst;
|
va_list arglst;
|
||||||
va_start(arglst, fmt);
|
va_start(arglst, fmt);
|
||||||
vsprintf(msg, fmt, arglst);
|
_vsnprintf(msg, sizeof(msg)-1, fmt, arglst);
|
||||||
|
//vsprintf(msg, fmt, arglst);
|
||||||
va_end(arglst);
|
va_end(arglst);
|
||||||
AMXXLOG_Log("%s", msg);
|
AMXXLOG_Log("%s", msg);
|
||||||
}
|
}
|
||||||
|
@ -1220,7 +1220,7 @@ void GenericError(AMX *amx, int err, int line, char buf[], const char *file)
|
||||||
geterr = NULL;
|
geterr = NULL;
|
||||||
else
|
else
|
||||||
geterr = amx_errs[err];
|
geterr = amx_errs[err];
|
||||||
if (!(amx->flags & AMX_FLAG_LINEOPS))
|
if (!(amx->flags & AMX_FLAG_DEBUG))
|
||||||
{
|
{
|
||||||
if (geterr == NULL)
|
if (geterr == NULL)
|
||||||
{
|
{
|
||||||
|
@ -1250,7 +1250,7 @@ void LogError(AMX *amx, int err, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
//does this plugin have debug info?
|
//does this plugin have debug info?
|
||||||
va_list arg;
|
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 buf[1024];
|
||||||
static char vbuf[1024];
|
static char vbuf[1024];
|
||||||
*buf = 0;
|
*buf = 0;
|
||||||
|
@ -1259,7 +1259,7 @@ void LogError(AMX *amx, int err, const char *fmt, ...)
|
||||||
va_start(arg, fmt);
|
va_start(arg, fmt);
|
||||||
vsprintf(vbuf, fmt, arg);
|
vsprintf(vbuf, fmt, arg);
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
|
#if 0
|
||||||
if (!dbg || !(dbg->tail))
|
if (!dbg || !(dbg->tail))
|
||||||
{
|
{
|
||||||
if (dbg && amx->curfile < dbg->numFiles && amx->curfile >= 0)
|
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;
|
t = dbg->tail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
amx_RaiseError(amx, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MNF_MergeDefinitionFile(const char *file)
|
void MNF_MergeDefinitionFile(const char *file)
|
||||||
|
@ -1386,7 +1388,7 @@ const char *g_LastRequestedFunc = NULL;
|
||||||
#define REGISTER_FUNC(name, func) \
|
#define REGISTER_FUNC(name, func) \
|
||||||
{ \
|
{ \
|
||||||
pFunc = new func_s; \
|
pFunc = new func_s; \
|
||||||
pFunc->pfn = func; \
|
pFunc->pfn = (void *)func; \
|
||||||
pFunc->desc = name; \
|
pFunc->desc = name; \
|
||||||
g_functions.put(pFunc); \
|
g_functions.put(pFunc); \
|
||||||
}
|
}
|
||||||
|
@ -1398,6 +1400,16 @@ void MNF_RegisterFunction(void *pfn, const char *description)
|
||||||
REGISTER_FUNC(description, pfn);
|
REGISTER_FUNC(description, pfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Module_UncacheFunctions()
|
||||||
|
{
|
||||||
|
g_functions.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
int amx_Execv()
|
||||||
|
{
|
||||||
|
return AMX_ERR_NOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
void Module_CacheFunctions()
|
void Module_CacheFunctions()
|
||||||
{
|
{
|
||||||
func_s *pFunc;
|
func_s *pFunc;
|
||||||
|
@ -1430,7 +1442,7 @@ void Module_CacheFunctions()
|
||||||
|
|
||||||
// other amx stuff
|
// other amx stuff
|
||||||
REGISTER_FUNC("amx_Exec", amx_Exec)
|
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_Allot", amx_Allot)
|
||||||
REGISTER_FUNC("amx_FindPublic", amx_FindPublic)
|
REGISTER_FUNC("amx_FindPublic", amx_FindPublic)
|
||||||
REGISTER_FUNC("amx_FindNative", amx_FindNative)
|
REGISTER_FUNC("amx_FindNative", amx_FindNative)
|
||||||
|
|
|
@ -45,135 +45,8 @@
|
||||||
#undef C_DLLEXPORT
|
#undef C_DLLEXPORT
|
||||||
#define C_DLLEXPORT extern "C" DLLEXPORT
|
#define C_DLLEXPORT extern "C" DLLEXPORT
|
||||||
|
|
||||||
#define AMX_INTERFACE_VERSION 6
|
|
||||||
|
|
||||||
#define RELOAD_MODULE 0
|
#define RELOAD_MODULE 0
|
||||||
#define STATIC_MODULE 1
|
#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__
|
#endif // __MODULES_H__
|
||||||
|
|
|
@ -300,7 +300,7 @@
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
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"
|
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"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="5"
|
RuntimeLibrary="5"
|
||||||
StructMemberAlignment="3"
|
StructMemberAlignment="3"
|
||||||
|
@ -319,7 +319,7 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386"
|
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"
|
OutputFile="jitdebug/amxmodx_mm.dll"
|
||||||
Version="0.1"
|
Version="0.1"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
|
@ -371,7 +371,8 @@
|
||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
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"
|
StringPooling="TRUE"
|
||||||
RuntimeLibrary="4"
|
RuntimeLibrary="4"
|
||||||
EnableFunctionLevelLinking="TRUE"
|
EnableFunctionLevelLinking="TRUE"
|
||||||
|
@ -389,7 +390,7 @@
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386"
|
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"
|
OutputFile="jitrelease/amxmodx_mm.dll"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
|
@ -649,6 +650,9 @@
|
||||||
<File
|
<File
|
||||||
RelativePath="..\md5.cpp">
|
RelativePath="..\md5.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\menus.cpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\meta_api.cpp">
|
RelativePath="..\meta_api.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
@ -780,6 +784,9 @@
|
||||||
<File
|
<File
|
||||||
RelativePath="..\md5.h">
|
RelativePath="..\md5.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\menus.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\modules.h">
|
RelativePath="..\modules.h">
|
||||||
</File>
|
</File>
|
||||||
|
|
|
@ -150,14 +150,14 @@ void amx_command(){
|
||||||
print_srvconsole( "%s %s\n", Plugin_info.name, Plugin_info.version);
|
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( "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__);
|
print_srvconsole( "Compiled: %s\n", __DATE__ ", " __TIME__);
|
||||||
#ifdef JIT
|
#if defined JIT && !defined ASM32
|
||||||
print_srvconsole( "Core mode: JIT\n");
|
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
|
#else
|
||||||
#ifdef ASM32
|
print_srvconsole( "Core mode: Normal\n");
|
||||||
print_srvconsole( "Core mode: ASM\n");
|
|
||||||
#else
|
|
||||||
print_srvconsole( "Core mode: Normal\n");
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (!strcmp(cmd,"modules"))
|
else if (!strcmp(cmd,"modules"))
|
||||||
|
@ -264,39 +264,19 @@ void amx_command(){
|
||||||
|
|
||||||
void plugin_srvcmd()
|
void plugin_srvcmd()
|
||||||
{
|
{
|
||||||
|
cell ret = 0;
|
||||||
cell ret = 0;
|
const char* cmd = CMD_ARGV(0);
|
||||||
int err;
|
|
||||||
const char* cmd = CMD_ARGV(0);
|
|
||||||
|
|
||||||
#ifdef ENABLEEXEPTIONS
|
|
||||||
try{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CmdMngr::iterator a = g_commands.srvcmdbegin();
|
CmdMngr::iterator a = g_commands.srvcmdbegin();
|
||||||
|
|
||||||
while ( a )
|
while ( a )
|
||||||
{
|
{
|
||||||
if ( (*a).matchCommand( cmd ) &&
|
if ( (*a).matchCommand( cmd ) &&
|
||||||
(*a).getPlugin()->isExecutable( (*a).getFunction() ) )
|
(*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( ... )
|
|
||||||
{
|
{
|
||||||
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];
|
char token = params[6];
|
||||||
//trim
|
//trim
|
||||||
int trim = params[7];
|
int trim = params[7];
|
||||||
for (i=0; i<len; i++)
|
for (i=0; i<(unsigned int)len; i++)
|
||||||
{
|
{
|
||||||
if (trim && !done_flag)
|
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 LeftMax = params[3];
|
||||||
int RightMax = params[5];
|
int RightMax = params[5];
|
||||||
|
|
||||||
for (i=0; i<l; i++) {
|
for (i=0; i<(unsigned int)l; i++) {
|
||||||
if (string[i] == '"' && !quote_flag) {
|
if (string[i] == '"' && !quote_flag) {
|
||||||
quote_flag = true;
|
quote_flag = true;
|
||||||
} else if (string[i] == '"' && quote_flag) {
|
} else if (string[i] == '"' && quote_flag) {
|
||||||
|
@ -603,6 +603,14 @@ static cell AMX_NATIVE_CALL amx_ucfirst(AMX *amx, cell *params)
|
||||||
return 1;
|
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)
|
static cell AMX_NATIVE_CALL amx_trim(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
cell *asdf = get_amxaddr(amx, params[1]);
|
cell *asdf = get_amxaddr(amx, params[1]);
|
||||||
|
@ -668,5 +676,6 @@ AMX_NATIVE_INFO string_Natives[] = {
|
||||||
{ "trim", amx_trim },
|
{ "trim", amx_trim },
|
||||||
{ "ucfirst", amx_ucfirst },
|
{ "ucfirst", amx_ucfirst },
|
||||||
{ "strtok", amx_strtok },
|
{ "strtok", amx_strtok },
|
||||||
|
{ "strlen", amx_strlen },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,1,0,0
|
FILEVERSION 1,5,0,1
|
||||||
PRODUCTVERSION 1,1,0,0
|
PRODUCTVERSION 1,5,0,1
|
||||||
FILEFLAGSMASK 0x17L
|
FILEFLAGSMASK 0x17L
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -45,12 +45,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "Comments", "AMX Mod X"
|
VALUE "Comments", "AMX Mod X"
|
||||||
VALUE "FileDescription", "AMX Mod X"
|
VALUE "FileDescription", "AMX Mod X"
|
||||||
VALUE "FileVersion", "1.10-RC1"
|
VALUE "FileVersion", "1.50"
|
||||||
VALUE "InternalName", "amxmodx"
|
VALUE "InternalName", "amxmodx"
|
||||||
VALUE "LegalCopyright", "Copyright (c) 2004-2005, AMX Mod X Dev Team"
|
VALUE "LegalCopyright", "Copyright (c) 2004-2005, AMX Mod X Dev Team"
|
||||||
VALUE "OriginalFilename", "amxmodx_mm.dll"
|
VALUE "OriginalFilename", "amxmodx_mm.dll"
|
||||||
VALUE "ProductName", "AMX Mod X"
|
VALUE "ProductName", "AMX Mod X"
|
||||||
VALUE "ProductVersion", "1.10-RC1"
|
VALUE "ProductVersion", "1.50-RC1"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user