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