From f6b91f9258d32170e0c147946e7579bc1525356e Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 25 Jul 2005 00:01:54 +0000 Subject: [PATCH] Initial import of amxxpc --- compiler/amxxpc/amx.cpp | 3984 +++++++++++++++++++++++++++++ compiler/amxxpc/amx.h | 439 ++++ compiler/amxxpc/amxxpc.cpp | 326 +++ compiler/amxxpc/amxxpc.h | 51 + compiler/amxxpc/amxxpc.sln | 21 + compiler/amxxpc/amxxpc.vcproj | 164 ++ compiler/amxxpc/amxxpc1.rc | 72 + compiler/amxxpc/favicon.ico | Bin 0 -> 766 bytes compiler/amxxpc/osdefs.h | 60 + compiler/amxxpc/resource.h | 17 + compiler/amxxpc/resource1.h | 16 + compiler/amxxpc/sclinux.h | 47 + compiler/amxxpc/testmini.c | 155 ++ compiler/amxxpc/zconf.h | 323 +++ compiler/amxxpc/zlib.h | 1200 +++++++++ compiler/amxxpc/zlib.lib | Bin 0 -> 221206 bytes compiler/libpc300/amx.h | 17 +- compiler/libpc300/libpawnc.c | 41 +- compiler/libpc300/libpc300.vcproj | 3 + compiler/libpc300/sclist.c | 14 +- 20 files changed, 6894 insertions(+), 56 deletions(-) create mode 100755 compiler/amxxpc/amx.cpp create mode 100755 compiler/amxxpc/amx.h create mode 100755 compiler/amxxpc/amxxpc.cpp create mode 100755 compiler/amxxpc/amxxpc.h create mode 100755 compiler/amxxpc/amxxpc.sln create mode 100755 compiler/amxxpc/amxxpc.vcproj create mode 100755 compiler/amxxpc/amxxpc1.rc create mode 100755 compiler/amxxpc/favicon.ico create mode 100755 compiler/amxxpc/osdefs.h create mode 100755 compiler/amxxpc/resource.h create mode 100755 compiler/amxxpc/resource1.h create mode 100755 compiler/amxxpc/sclinux.h create mode 100755 compiler/amxxpc/testmini.c create mode 100755 compiler/amxxpc/zconf.h create mode 100755 compiler/amxxpc/zlib.h create mode 100755 compiler/amxxpc/zlib.lib diff --git a/compiler/amxxpc/amx.cpp b/compiler/amxxpc/amx.cpp new file mode 100755 index 00000000..912a12fa --- /dev/null +++ b/compiler/amxxpc/amx.cpp @@ -0,0 +1,3984 @@ +/* Pawn Abstract Machine (for the Pawn language) + * + * 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 + * the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in + * a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * Version: $Id$ + */ + +#if BUILD_PLATFORM == WINDOWS && BUILD_TYPE == RELEASE && BUILD_COMPILER == MSVC && PAWN_CELL_SIZE == 64 + /* bad bad workaround but we have to prevent a compiler crash :/ */ + #pragma optimize("g",off) +#endif + +#define WIN32_LEAN_AND_MEAN +#if defined _UNICODE || defined __UNICODE__ || defined UNICODE +# if !defined UNICODE /* for Windows API */ +# define UNICODE +# endif +# if !defined _UNICODE /* for C library */ +# define _UNICODE +# endif +#endif + +#include +#include +#include +#include /* for wchar_t */ +#include +#include "osdefs.h" +#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ + #include + #if !defined AMX_NODYNALOAD + #include + #endif + #if defined JIT + #include + #include + #endif +#endif +#if defined __LCC__ + #include /* for wcslen() */ +#endif +#include "amx.h" +#if (defined _Windows && !defined AMX_NODYNALOAD) || (defined JIT && __WIN32__) + #include +#endif + + +/* When one or more of the AMX_funcname macris are defined, we want + * to compile only those functions. However, when none of these macros + * is present, we want to compile everything. + */ +#if defined AMX_ALIGN || defined AMX_ALLOT || defined AMX_CLEANUP + #define AMX_EXPLIT_FUNCTIONS +#endif +#if defined AMX_CLONE || defined AMX_EXEC || defined AMX_FLAGS + #define AMX_EXPLIT_FUNCTIONS +#endif +#if defined AMX_GETADDR || defined AMX_INIT || defined AMX_MEMINFO + #define AMX_EXPLIT_FUNCTIONS +#endif +#if defined AMX_NAMELENGTH || defined AMX_NATIVEINFO || defined AMX_RAISEERROR + #define AMX_EXPLIT_FUNCTIONS +#endif +#if defined AMX_REGISTER || defined AMX_SETCALLBACK || defined AMX_SETDEBUGHOOK + #define AMX_EXPLIT_FUNCTIONS +#endif +#if defined AMX_XXXNATIVES || defined AMX_XXXPUBLICS || defined AMX_XXXPUBVARS + #define AMX_EXPLIT_FUNCTIONS +#endif +#if defined AMX_XXXSTRING || defined AMX_XXXTAGS || defined AMX_XXXUSERDATA + #define AMX_EXPLIT_FUNCTIONS +#endif +#if defined AMX_UTF8XXX + #define AMX_EXPLIT_FUNCTIONS +#endif +#if !defined AMX_EXPLIT_FUNCTIONS + /* no constant set, set them all */ + #define AMX_ALIGN /* amx_Align16(), amx_Align32() and amx_Align64() */ + #define AMX_ALLOT /* amx_Allot() and amx_Release() */ + #define AMX_CLEANUP /* amx_Cleanup() */ + #define AMX_CLONE /* amx_Clone() */ + #define AMX_EXEC /* amx_Exec() plus amx_Push(), amx_PushArray() and amx_PushString() */ + #define AMX_FLAGS /* amx_Flags() */ + #define AMX_GETADDR /* amx_GetAddr() */ + #define AMX_INIT /* amx_Init() and amx_InitJIT() */ + #define AMX_MEMINFO /* amx_MemInfo() */ + #define AMX_NAMELENGTH /* amx_NameLength() */ + #define AMX_NATIVEINFO /* amx_NativeInfo() */ + #define AMX_RAISEERROR /* amx_RaiseError() */ + #define AMX_REGISTER /* amx_Register() */ + #define AMX_SETCALLBACK /* amx_SetCallback() */ + #define AMX_SETDEBUGHOOK /* amx_SetDebugHook() */ + #define AMX_XXXNATIVES /* amx_NumNatives(), amx_GetNative() and amx_FindNative() */ + #define AMX_XXXPUBLICS /* amx_NumPublics(), amx_GetPublic() and amx_FindPublic() */ + #define AMX_XXXPUBVARS /* amx_NumPubVars(), amx_GetPubVar() and amx_FindPubVar() */ + #define AMX_XXXSTRING /* amx_StrLen(), amx_GetString() and amx_SetString() */ + #define AMX_XXXTAGS /* amx_NumTags(), amx_GetTag() and amx_FindTagId() */ + #define AMX_XXXUSERDATA /* amx_GetUserData() and amx_SetUserData() */ + #define AMX_UTF8XXX /* amx_UTF8Get(), amx_UTF8Put(), amx_UTF8Check() */ +#endif +#undef AMX_EXPLIT_FUNCTIONS +#if defined AMX_ANSIONLY + #undef AMX_UTF8XXX /* no UTF-8 support in ANSI/ASCII-only version */ +#endif + +typedef enum { + OP_NONE, /* invalid opcode */ + OP_LOAD_PRI, + OP_LOAD_ALT, + OP_LOAD_S_PRI, + OP_LOAD_S_ALT, + OP_LREF_PRI, + OP_LREF_ALT, + OP_LREF_S_PRI, + OP_LREF_S_ALT, + OP_LOAD_I, + OP_LODB_I, + OP_CONST_PRI, + OP_CONST_ALT, + OP_ADDR_PRI, + OP_ADDR_ALT, + OP_STOR_PRI, + OP_STOR_ALT, + OP_STOR_S_PRI, + OP_STOR_S_ALT, + OP_SREF_PRI, + OP_SREF_ALT, + OP_SREF_S_PRI, + OP_SREF_S_ALT, + OP_STOR_I, + OP_STRB_I, + OP_LIDX, + OP_LIDX_B, + OP_IDXADDR, + OP_IDXADDR_B, + OP_ALIGN_PRI, + OP_ALIGN_ALT, + OP_LCTRL, + OP_SCTRL, + OP_MOVE_PRI, + OP_MOVE_ALT, + OP_XCHG, + OP_PUSH_PRI, + OP_PUSH_ALT, + OP_PUSH_R, + OP_PUSH_C, + OP_PUSH, + OP_PUSH_S, + OP_POP_PRI, + OP_POP_ALT, + OP_STACK, + OP_HEAP, + OP_PROC, + OP_RET, + OP_RETN, + OP_CALL, + OP_CALL_PRI, + OP_JUMP, + OP_JREL, + OP_JZER, + OP_JNZ, + OP_JEQ, + OP_JNEQ, + OP_JLESS, + OP_JLEQ, + OP_JGRTR, + OP_JGEQ, + OP_JSLESS, + OP_JSLEQ, + OP_JSGRTR, + OP_JSGEQ, + OP_SHL, + OP_SHR, + OP_SSHR, + OP_SHL_C_PRI, + OP_SHL_C_ALT, + OP_SHR_C_PRI, + OP_SHR_C_ALT, + OP_SMUL, + OP_SDIV, + OP_SDIV_ALT, + OP_UMUL, + OP_UDIV, + OP_UDIV_ALT, + OP_ADD, + OP_SUB, + OP_SUB_ALT, + OP_AND, + OP_OR, + OP_XOR, + OP_NOT, + OP_NEG, + OP_INVERT, + OP_ADD_C, + OP_SMUL_C, + OP_ZERO_PRI, + OP_ZERO_ALT, + OP_ZERO, + OP_ZERO_S, + OP_SIGN_PRI, + OP_SIGN_ALT, + OP_EQ, + OP_NEQ, + OP_LESS, + OP_LEQ, + OP_GRTR, + OP_GEQ, + OP_SLESS, + OP_SLEQ, + OP_SGRTR, + OP_SGEQ, + OP_EQ_C_PRI, + OP_EQ_C_ALT, + OP_INC_PRI, + OP_INC_ALT, + OP_INC, + OP_INC_S, + OP_INC_I, + OP_DEC_PRI, + OP_DEC_ALT, + OP_DEC, + OP_DEC_S, + OP_DEC_I, + OP_MOVS, + OP_CMPS, + OP_FILL, + OP_HALT, + OP_BOUNDS, + OP_SYSREQ_PRI, + OP_SYSREQ_C, + OP_FILE, /* obsolete */ + OP_LINE, /* obsolete */ + OP_SYMBOL, /* obsolete */ + OP_SRANGE, /* obsolete */ + OP_JUMP_PRI, + OP_SWITCH, + OP_CASETBL, + OP_SWAP_PRI, + OP_SWAP_ALT, + OP_PUSHADDR, + OP_NOP, + OP_SYSREQ_D, + OP_SYMTAG, /* obsolete */ + OP_BREAK, + /* ----- */ + OP_NUM_OPCODES +} OPCODE; + +#define USENAMETABLE(hdr) \ + ((hdr)->defsize==sizeof(AMX_FUNCSTUBNT)) +#define NUMENTRIES(hdr,field,nextfield) \ + (unsigned)(((hdr)->nextfield - (hdr)->field) / (hdr)->defsize) +#define GETENTRY(hdr,table,index) \ + (AMX_FUNCSTUB *)((unsigned char*)(hdr) + (unsigned)(hdr)->table + (unsigned)index*(hdr)->defsize) +#define GETENTRYNAME(hdr,entry) \ + ( USENAMETABLE(hdr) \ + ? (char *)((unsigned char*)(hdr) + (unsigned)((AMX_FUNCSTUBNT*)(entry))->nameofs) \ + : ((AMX_FUNCSTUB*)(entry))->name ) + +#if !defined NDEBUG + static int check_endian(void) + { + uint16_t val=0x00ff; + unsigned char *ptr=(unsigned char *)&val; + /* "ptr" points to the starting address of "val". If that address + * holds the byte "0xff", the computer stored the low byte of "val" + * at the lower address, and so the memory lay out is Little Endian. + */ + assert(*ptr==0xff || *ptr==0x00); + #if BYTE_ORDER==BIG_ENDIAN + return *ptr==0x00; /* return "true" if big endian */ + #else + return *ptr==0xff; /* return "true" if little endian */ + #endif + } +#endif + +#if BYTE_ORDER==BIG_ENDIAN || PAWN_CELL_SIZE==16 + static void swap16(uint16_t *v) + { + unsigned char *s = (unsigned char *)v; + unsigned char t; + + assert(sizeof(*v)==2); + /* swap two bytes */ + t=s[0]; + s[0]=s[1]; + s[1]=t; + } +#endif + +#if BYTE_ORDER==BIG_ENDIAN || PAWN_CELL_SIZE==32 + static void swap32(uint32_t *v) + { + unsigned char *s = (unsigned char *)v; + unsigned char t; + + assert(sizeof(*v)==4); + /* swap outer two bytes */ + t=s[0]; + s[0]=s[3]; + s[3]=t; + /* swap inner two bytes */ + t=s[1]; + s[1]=s[2]; + s[2]=t; + } +#endif + +#if (BYTE_ORDER==BIG_ENDIAN || PAWN_CELL_SIZE==64) && (defined _I64_MAX || defined HAVE_I64) + static void swap64(uint64_t *v) + { + unsigned char *s = (unsigned char *)v; + unsigned char t; + + assert(sizeof(*v)==8); + + t=s[0]; + s[0]=s[7]; + s[7]=t; + + t=s[1]; + s[1]=s[6]; + s[6]=t; + + t=s[2]; + s[2]=s[5]; + s[5]=t; + + t=s[3]; + s[3]=s[4]; + s[4]=t; + } +#endif + +#if defined AMX_ALIGN || defined AMX_INIT +uint16_t * AMXAPI amx_Align16(uint16_t *v) +{ + assert(sizeof(*v)==2); + assert(check_endian()); + #if BYTE_ORDER==BIG_ENDIAN + swap16(v); + #endif + return v; +} + +uint32_t * AMXAPI amx_Align32(uint32_t *v) +{ + assert(sizeof(*v)==4); + assert(check_endian()); + #if BYTE_ORDER==BIG_ENDIAN + swap32(v); + #endif + return v; +} + +#if defined _I64_MAX || defined HAVE_I64 +uint64_t * AMXAPI amx_Align64(uint64_t *v) +{ + assert(sizeof(*v)==8); + assert(check_endian()); + #if BYTE_ORDER==BIG_ENDIAN + swap64(v); + #endif + return v; +} +#endif /* _I64_MAX || HAVE_I64 */ +#endif /* AMX_ALIGN || AMX_INIT */ + +#if PAWN_CELL_SIZE==16 + #define swapcell swap16 +#elif PAWN_CELL_SIZE==32 + #define swapcell swap32 +#elif PAWN_CELL_SIZE==64 && (defined _I64_MAX || defined HAVE_I64) + #define swapcell swap64 +#else + #error Unsupported cell size +#endif + +#if defined AMX_FLAGS +int AMXAPI amx_Flags(AMX *amx,uint16_t *flags) +{ + AMX_HEADER *hdr; + + *flags=0; + if (amx==NULL) + return AMX_ERR_FORMAT; + hdr=(AMX_HEADER *)amx->base; + if (hdr->magic!=AMX_MAGIC) + return AMX_ERR_FORMAT; + if (hdr->file_version>CUR_FILE_VERSION || hdr->amx_versionflags; + return AMX_ERR_NONE; +} +#endif /* AMX_FLAGS */ + +#if defined AMX_INIT +int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params) +{ + AMX_HEADER *hdr; + AMX_FUNCSTUB *func; + AMX_NATIVE f; + + assert(amx!=NULL); + hdr=(AMX_HEADER *)amx->base; + assert(hdr!=NULL); + assert(hdr->magic==AMX_MAGIC); + assert(hdr->natives<=hdr->libraries); +#if defined AMX_NATIVETABLE + if (index=0 && index<(cell)NUMENTRIES(hdr,natives,libraries)); + func=GETENTRY(hdr,natives,index); + f=(AMX_NATIVE)func->address; +#if defined AMX_NATIVETABLE + } /* if */ +#endif + assert(f!=NULL); + + /* Now that we have found the function, patch the program so that any + * subsequent call will call the function directly (bypassing this + * callback). + * This trick cannot work in the JIT, because the program would need to + * be re-JIT-compiled after patching a P-code instruction. + */ + #if defined JIT && !defined NDEBUG + if ((amx->flags & AMX_FLAG_JITC)!=0) + assert(amx->sysreq_d==0); + #endif + if (amx->sysreq_d!=0) { + /* at the point of the call, the CIP pseudo-register points directly + * behind the SYSREQ instruction and its parameter. + */ + unsigned char *code=amx->base+(int)hdr->cod+(int)amx->cip-4; + assert(amx->cip >= 4 && amx->cip < (hdr->dat - hdr->cod)); + assert(sizeof(f)<=sizeof(cell)); /* function pointer must fit in a cell */ +#if defined __GNUC__ || defined ASM32 + if (*(cell*)code==index) { +#else + if (*(cell*)code!=OP_SYSREQ_PRI) { + assert(*(cell*)(code-sizeof(cell))==OP_SYSREQ_C); + assert(*(cell*)code==index); +#endif + *(cell*)(code-sizeof(cell))=amx->sysreq_d; + *(cell*)code=(cell)f; + } /* if */ + } /* if */ + + /* Note: + * params[0] == number of bytes for the additional parameters passed to the native function + * params[1] == first argument + * etc. + */ + + amx->error=AMX_ERR_NONE; + *result = f(amx,params); + return amx->error; +} +#endif /* defined AMX_INIT */ + + +#if defined JIT + extern int AMXAPI getMaxCodeSize(void); + extern int AMXAPI asm_runJIT(void *sourceAMXbase, void *jumparray, void *compiledAMXbase); +#endif + +#if PAWN_CELL_SIZE==16 + #define JUMPABS(base,ip) ((cell *)((base) + *(ip))) + #define RELOC_ABS(base, off) + #define RELOC_VALUE(base, v) +#else + #define JUMPABS(base, ip) ((cell *)*(ip)) + #define RELOC_ABS(base, off) (*(ucell *)((base)+(int)(off)) += (ucell)(base)) + #define RELOC_VALUE(base, v) ((v)+((ucell)(base))) +#endif + +#define DBGPARAM(v) ( (v)=*(cell *)(code+(int)cip), cip+=sizeof(cell) ) + +#if defined AMX_INIT + +static int amx_BrowseRelocate(AMX *amx) +{ + AMX_HEADER *hdr; + unsigned char *code; + cell cip; + long codesize; + OPCODE op; + #if defined __GNUC__ || defined ASM32 || defined JIT + cell *opcode_list; + #endif + #if defined JIT + int opcode_count = 0; + int reloc_count = 0; + #endif + + assert(amx!=NULL); + hdr=(AMX_HEADER *)amx->base; + assert(hdr!=NULL); + assert(hdr->magic==AMX_MAGIC); + code=amx->base+(int)hdr->cod; + codesize=hdr->dat - hdr->cod; + amx->flags=AMX_FLAG_BROWSE; + + /* sanity checks */ + assert(OP_PUSH_PRI==36); + assert(OP_PROC==46); + assert(OP_SHL==65); + assert(OP_SMUL==72); + assert(OP_EQ==95); + assert(OP_INC_PRI==107); + assert(OP_MOVS==117); + assert(OP_SYMBOL==126); + + amx->sysreq_d=0; /* preset */ + #if (defined __GNUC__ || defined ASM32 || defined JIT) && !defined __64BIT__ + amx_Exec(amx, (cell*)(void*)&opcode_list, 0); + /* to use direct system requests, a function pointer must fit in a cell; + * because the native function's address will be stored as the parameter + * of SYSREQ.D + */ + if ((amx->flags & AMX_FLAG_JITC)==0 && sizeof(AMX_NATIVE)<=sizeof(cell)) + amx->sysreq_d=opcode_list[OP_SYSREQ_D]; + #else + /* ANSI C + * to use direct system requests, a function pointer must fit in a cell; + * see the comment above + */ + if (sizeof(AMX_NATIVE)<=sizeof(cell)) + amx->sysreq_d=OP_SYSREQ_D; + #endif + + /* start browsing code */ + for (cip=0; cip0 && op=256) { + amx->flags &= ~AMX_FLAG_BROWSE; + return AMX_ERR_INVINSTR; + } /* if */ + #if defined __GNUC__ || defined ASM32 || defined JIT + /* relocate opcode (only works if the size of an opcode is at least + * as big as the size of a pointer (jump address); so basically we + * rely on the opcode and a pointer being 32-bit + */ + *(cell *)(code+(int)cip) = opcode_list[op]; + #endif + #if defined JIT + opcode_count++; + #endif + cip+=sizeof(cell); + switch (op) { + case OP_LOAD_PRI: /* instructions with 1 parameter */ + case OP_LOAD_ALT: + case OP_LOAD_S_PRI: + case OP_LOAD_S_ALT: + case OP_LREF_PRI: + case OP_LREF_ALT: + case OP_LREF_S_PRI: + case OP_LREF_S_ALT: + case OP_LODB_I: + case OP_CONST_PRI: + case OP_CONST_ALT: + case OP_ADDR_PRI: + case OP_ADDR_ALT: + case OP_STOR_PRI: + case OP_STOR_ALT: + case OP_STOR_S_PRI: + case OP_STOR_S_ALT: + case OP_SREF_PRI: + case OP_SREF_ALT: + case OP_SREF_S_PRI: + case OP_SREF_S_ALT: + case OP_STRB_I: + case OP_LIDX_B: + case OP_IDXADDR_B: + case OP_ALIGN_PRI: + case OP_ALIGN_ALT: + case OP_LCTRL: + case OP_SCTRL: + case OP_PUSH_R: + case OP_PUSH_C: + case OP_PUSH: + case OP_PUSH_S: + case OP_STACK: + case OP_HEAP: + case OP_JREL: + case OP_SHL_C_PRI: + case OP_SHL_C_ALT: + case OP_SHR_C_PRI: + case OP_SHR_C_ALT: + case OP_ADD_C: + case OP_SMUL_C: + case OP_ZERO: + case OP_ZERO_S: + case OP_EQ_C_PRI: + case OP_EQ_C_ALT: + case OP_INC: + case OP_INC_S: + case OP_DEC: + case OP_DEC_S: + case OP_MOVS: + case OP_CMPS: + case OP_FILL: + case OP_HALT: + case OP_BOUNDS: + case OP_SYSREQ_C: + case OP_PUSHADDR: + case OP_SYSREQ_D: + cip+=sizeof(cell); + break; + + case OP_LOAD_I: /* instructions without parameters */ + case OP_STOR_I: + case OP_LIDX: + case OP_IDXADDR: + case OP_MOVE_PRI: + case OP_MOVE_ALT: + case OP_XCHG: + case OP_PUSH_PRI: + case OP_PUSH_ALT: + case OP_POP_PRI: + case OP_POP_ALT: + case OP_PROC: + case OP_RET: + case OP_RETN: + case OP_CALL_PRI: + case OP_SHL: + case OP_SHR: + case OP_SSHR: + case OP_SMUL: + case OP_SDIV: + case OP_SDIV_ALT: + case OP_UMUL: + case OP_UDIV: + case OP_UDIV_ALT: + case OP_ADD: + case OP_SUB: + case OP_SUB_ALT: + case OP_AND: + case OP_OR: + case OP_XOR: + case OP_NOT: + case OP_NEG: + case OP_INVERT: + case OP_ZERO_PRI: + case OP_ZERO_ALT: + case OP_SIGN_PRI: + case OP_SIGN_ALT: + case OP_EQ: + case OP_NEQ: + case OP_LESS: + case OP_LEQ: + case OP_GRTR: + case OP_GEQ: + case OP_SLESS: + case OP_SLEQ: + case OP_SGRTR: + case OP_SGEQ: + case OP_INC_PRI: + case OP_INC_ALT: + case OP_INC_I: + case OP_DEC_PRI: + case OP_DEC_ALT: + case OP_DEC_I: + case OP_SYSREQ_PRI: + case OP_JUMP_PRI: + case OP_SWAP_PRI: + case OP_SWAP_ALT: + case OP_NOP: + case OP_BREAK: + break; + + case OP_CALL: /* opcodes that need relocation */ + case OP_JUMP: + case OP_JZER: + case OP_JNZ: + case OP_JEQ: + case OP_JNEQ: + case OP_JLESS: + case OP_JLEQ: + case OP_JGRTR: + case OP_JGEQ: + case OP_JSLESS: + case OP_JSLEQ: + case OP_JSGRTR: + case OP_JSGEQ: + case OP_SWITCH: + #if defined JIT + reloc_count++; + #endif + RELOC_ABS(code, cip); + cip+=sizeof(cell); + break; + + case OP_FILE: + case OP_SYMBOL: { + cell num; + DBGPARAM(num); + cip+=num; + break; + } /* case */ + case OP_LINE: + case OP_SRANGE: + cip+=2*sizeof(cell); + break; + case OP_SYMTAG: + cip+=sizeof(cell); + break; + case OP_CASETBL: { + cell num; + int i; + DBGPARAM(num); /* number of records follows the opcode */ + for (i=0; i<=num; i++) { + RELOC_ABS(code, cip+2*i*sizeof(cell)); + #if defined JIT + reloc_count++; + #endif + } /* for */ + cip+=(2*num + 1)*sizeof(cell); + break; + } /* case */ + default: + amx->flags &= ~AMX_FLAG_BROWSE; + return AMX_ERR_INVINSTR; + } /* switch */ + } /* for */ + + #if defined JIT + amx->code_size = getMaxCodeSize()*opcode_count + hdr->cod + + (hdr->stp - hdr->dat); + amx->reloc_size = 2*sizeof(cell)*reloc_count; + #endif + + amx->flags &= ~AMX_FLAG_BROWSE; + amx->flags |= AMX_FLAG_RELOC; + return AMX_ERR_NONE; +} + +#if AMX_COMPACTMARGIN > 2 +static void expand(unsigned char *code, long codesize, long memsize) +{ + ucell c; + struct { + long memloc; + ucell c; + } spare[AMX_COMPACTMARGIN]; + int sh=0,st=0,sc=0; + int shift; + + /* for in-place expansion, move from the end backward */ + assert(memsize % sizeof(cell) == 0); + while (codesize>0) { + c=0; + shift=0; + do { + codesize--; + /* no input byte should be shifted out completely */ + assert(shift<8*sizeof(cell)); + /* we work from the end of a sequence backwards; the final code in + * a sequence may not have the continuation bit set */ + assert(shift>0 || (code[(size_t)codesize] & 0x80)==0); + c|=(ucell)(code[(size_t)codesize] & 0x7f) << shift; + shift+=7; + } while (codesize>0 && (code[(size_t)codesize-1] & 0x80)!=0); + /* sign expand */ + if ((code[(size_t)codesize] & 0x40)!=0) { + while (shift < (int)(8*sizeof(cell))) { + c|=(ucell)0xff << shift; + shift+=8; + } /* while */ + } /* if */ + /* store */ + while (sc && (spare[sh].memloc>codesize)) { + *(ucell *)(code+(int)spare[sh].memloc)=spare[sh].c; + sh=(sh+1)%AMX_COMPACTMARGIN; + sc--; + } /* while */ + memsize -= sizeof(cell); + assert(memsize>=0); + if ((memsize>codesize)||((memsize==codesize)&&(memsize==0))) { + *(ucell *)(code+(size_t)memsize)=c; + } else { + assert(scflags & AMX_FLAG_RELOC)!=0) + return AMX_ERR_INIT; /* already initialized (may not do so twice) */ + + hdr=(AMX_HEADER *)program; + /* the header is in Little Endian, on a Big Endian machine, swap all + * multi-byte words + */ + assert(check_endian()); + #if BYTE_ORDER==BIG_ENDIAN + amx_Align32((uint32_t*)&hdr->size); + amx_Align16(&hdr->magic); + amx_Align16((uint16_t*)&hdr->flags); + amx_Align16((uint16_t*)&hdr->defsize); + amx_Align32((uint32_t*)&hdr->cod); + amx_Align32((uint32_t*)&hdr->dat); + amx_Align32((uint32_t*)&hdr->hea); + amx_Align32((uint32_t*)&hdr->stp); + amx_Align32((uint32_t*)&hdr->cip); + amx_Align32((uint32_t*)&hdr->publics); + amx_Align32((uint32_t*)&hdr->natives); + amx_Align32((uint32_t*)&hdr->libraries); + amx_Align32((uint32_t*)&hdr->pubvars); + amx_Align32((uint32_t*)&hdr->tags); + #endif + + if (hdr->magic!=AMX_MAGIC) + return AMX_ERR_FORMAT; + if (hdr->file_versionamx_version>CUR_FILE_VERSION) + return AMX_ERR_VERSION; + if (hdr->defsize!=sizeof(AMX_FUNCSTUB) && hdr->defsize!=sizeof(AMX_FUNCSTUBNT)) + return AMX_ERR_FORMAT; + if (USENAMETABLE(hdr)) { + uint16_t *namelength; + /* when there is a separate name table, check the maximum name length + * in that table + */ + amx_Align32((uint32_t*)&hdr->nametable); + namelength=(uint16_t*)((unsigned char*)program + (unsigned)hdr->nametable); + amx_Align16(namelength); + if (*namelength>sNAMEMAX) + return AMX_ERR_FORMAT; + } /* if */ + if (hdr->stp<=0) + return AMX_ERR_FORMAT; + #if BYTE_ORDER==BIG_ENDIAN + if ((hdr->flags & AMX_FLAG_COMPACT)==0) { + ucell *code=(ucell *)((unsigned char *)program+(int)hdr->cod); + while (code<(ucell *)((unsigned char *)program+(int)hdr->hea)) + swapcell(code++); + } /* if */ + #endif + assert((hdr->flags & AMX_FLAG_COMPACT)!=0 || hdr->hea == hdr->size); + if ((hdr->flags & AMX_FLAG_COMPACT)!=0) { + #if AMX_COMPACTMARGIN > 2 + expand((unsigned char *)program+(int)hdr->cod, + hdr->size - hdr->cod, hdr->hea - hdr->cod); + #else + return AMX_ERR_FORMAT; + #endif + } /* if */ + + amx->base=(unsigned char *)program; + + /* Set a zero cell at the top of the stack, which functions + * as a sentinel for strings. + */ + * (cell *)(amx->base+(int)hdr->stp-sizeof(cell)) = 0; + + /* set initial values */ + amx->hlw=hdr->hea - hdr->dat; /* stack and heap relative to data segment */ + amx->stp=hdr->stp - hdr->dat - sizeof(cell); + amx->hea=amx->hlw; + amx->stk=amx->stp; + if (amx->callback==NULL) + amx->callback=amx_Callback; + amx->data=NULL; + + /* also align all addresses in the public function, public variable, + * public tag and native function tables --offsets into the name table + * (if present) must also be swapped. + */ + #if BYTE_ORDER==BIG_ENDIAN + { /* local */ + AMX_FUNCSTUB *fs; + int i,num; + + fs=GETENTRY(hdr,natives,0); + num=NUMENTRIES(hdr,natives,libraries); + for (i=0; iaddress); /* redundant, because it should be zero */ + if (USENAMETABLE(hdr)) + amx_Align32(&((AMX_FUNCSTUBNT*)fs)->nameofs); + fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize); + } /* for */ + + fs=GETENTRY(hdr,publics,0); + assert(hdr->publics<=hdr->natives); + num=NUMENTRIES(hdr,publics,natives); + for (i=0; iaddress); + if (USENAMETABLE(hdr)) + amx_Align32(&((AMX_FUNCSTUBNT*)fs)->nameofs); + fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize); + } /* for */ + + fs=GETENTRY(hdr,pubvars,0); + assert(hdr->pubvars<=hdr->tags); + num=NUMENTRIES(hdr,pubvars,tags); + for (i=0; iaddress); + if (USENAMETABLE(hdr)) + amx_Align32(&((AMX_FUNCSTUBNT*)fs)->nameofs); + fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize); + } /* for */ + + fs=GETENTRY(hdr,tags,0); + if (hdr->file_version<7) { + assert(hdr->tags<=hdr->cod); + num=NUMENTRIES(hdr,tags,cod); + } else { + assert(hdr->tags<=hdr->nametable); + num=NUMENTRIES(hdr,tags,nametable); + } /* if */ + for (i=0; iaddress); + if (USENAMETABLE(hdr)) + amx_Align32(&((AMX_FUNCSTUBNT*)fs)->nameofs); + fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize); + } /* for */ + } /* local */ + #endif + + /* relocate call and jump instructions */ + amx_BrowseRelocate(amx); + + /* load any extension modules that the AMX refers to */ + #if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD + hdr=(AMX_HEADER *)amx->base; + numlibraries=NUMENTRIES(hdr,libraries,pubvars); + for (i=0; iaddress=(ucell)hlib; + } /* for */ + #endif + + return AMX_ERR_NONE; +} + +#if defined JIT + + #define CODESIZE_JIT 8192 /* approximate size of the code for the JIT */ + + #if defined __WIN32__ /* this also applies to Win32 "console" applications */ + + #define PROT_READ 0x1 /* page can be read */ + #define PROT_WRITE 0x2 /* page can be written */ + #define PROT_EXEC 0x4 /* page can be executed */ + #define PROT_NONE 0x0 /* page can not be accessed */ + + static int mprotect(void *addr, size_t len, int prot) + { + DWORD prev, p = 0; + if ((prot & PROT_WRITE)!=0) + p = PAGE_EXECUTE_READWRITE; + else + p |= PAGE_EXECUTE_READ; + return !VirtualProtect(addr, len, p, &prev); + } + + #elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ + + /* Linux already has mprotect() */ + + #else + + // TODO: Add cases for Linux, Unix, OS/2, ... + + /* DOS32 has no imposed limits on its segments */ + #define mprotect(addr, len, prot) (0) + + #endif /* #if defined __WIN32 __ */ + +int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code) +{ + int res; + AMX_HEADER *hdr; + + if ((amx->flags & AMX_FLAG_JITC)==0) + return AMX_ERR_INIT_JIT; /* flag not set, this AMX is not prepared for JIT */ + + /* Patching SYSREQ opcodes to SYSREQ_D cannot work in the JIT, because the + * program would need to be re-JIT-compiled after patching a P-code + * instruction. If this field is not zero, something went wrong with the + * amx_BrowseRelocate(). + */ + assert(amx->sysreq_d==0); + + if (mprotect(asm_runJIT, CODESIZE_JIT, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) + return AMX_ERR_INIT_JIT; + + /* copy the prefix */ + memcpy(native_code, amx->base, ((AMX_HEADER *)(amx->base))->cod); + hdr = native_code; + + /* JIT rulz! (TM) */ + /* MP: added check for correct compilation */ + if ((res = asm_runJIT(amx->base, reloc_table, native_code)) != 0) { + /* update the required memory size (the previous value was a + * conservative estimate, now we know the exact size) + */ + amx->code_size = (hdr->dat + hdr->stp + 3) & ~3; + /* The compiled code is relocatable, since only relative jumps are + * used for destinations within the generated code and absoulute + * addresses for jumps into the runtime, which is fixed in memory. + */ + amx->base = (unsigned char*) native_code; + amx->cip = hdr->cip; + amx->hea = hdr->hea; + amx->stp = hdr->stp - sizeof(cell); + /* also put a sentinel for strings at the top the stack */ + *(cell *)((char*)native_code + hdr->dat + hdr->stp - sizeof(cell)) = 0; + amx->stk = amx->stp; + } /* if */ + + return (res == 0) ? AMX_ERR_NONE : AMX_ERR_INIT_JIT; +} + +#else /* #if defined JIT */ + +int AMXAPI amx_InitJIT(AMX *amx,void *compiled_program,void *reloc_table) +{ + (void)amx; + (void)compiled_program; + (void)reloc_table; + return AMX_ERR_INIT_JIT; +} + +#endif /* #if defined JIT */ + +#endif /* AMX_INIT */ + +#if defined AMX_CLEANUP +int AMXAPI amx_Cleanup(AMX *amx) +{ + #if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD + #if defined _Windows + typedef int (FAR WINAPI *AMX_ENTRY)(AMX FAR *amx); + #elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ + typedef int (*AMX_ENTRY)(AMX *amx); + #endif + AMX_HEADER *hdr; + int numlibraries,i; + AMX_FUNCSTUB *lib; + AMX_ENTRY libcleanup; + #endif + + /* unload all extension modules */ + #if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD + hdr=(AMX_HEADER *)amx->base; + assert(hdr->magic==AMX_MAGIC); + numlibraries=NUMENTRIES(hdr,libraries,pubvars); + for (i=0; iaddress!=0) { + char funcname[sNAMEMAX+12]; /* +1 for '\0', +4 for 'amx_', +7 for 'Cleanup' */ + strcpy(funcname,"amx_"); + strcat(funcname,GETENTRYNAME(hdr,lib)); + strcat(funcname,"Cleanup"); + #if defined _Windows + libcleanup=(AMX_ENTRY)GetProcAddress((HINSTANCE)lib->address,funcname); + #elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ + libcleanup=(AMX_ENTRY)dlsym((void*)lib->address,funcname); + #endif + if (libcleanup!=NULL) + libcleanup(amx); + #if defined _Windows + FreeLibrary((HINSTANCE)lib->address); + #elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ + dlclose((void*)lib->address); + #endif + } /* if */ + } /* for */ + #else + (void)amx; + #endif + return AMX_ERR_NONE; +} +#endif /* AMX_CLEANUP */ + +#if defined AMX_CLONE +int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data) +{ + AMX_HEADER *hdr; + unsigned char _FAR *dataSource; + + if (amxSource==NULL) + return AMX_ERR_FORMAT; + if (amxClone==NULL) + return AMX_ERR_PARAMS; + if ((amxSource->flags & AMX_FLAG_RELOC)==0) + return AMX_ERR_INIT; + hdr=(AMX_HEADER *)amxSource->base; + if (hdr->magic!=AMX_MAGIC) + return AMX_ERR_FORMAT; + if (hdr->file_version>CUR_FILE_VERSION || hdr->amx_versionbase=amxSource->base; + amxClone->hlw=hdr->hea - hdr->dat; /* stack and heap relative to data segment */ + amxClone->stp=hdr->stp - hdr->dat - sizeof(cell); + amxClone->hea=amxClone->hlw; + amxClone->stk=amxClone->stp; + if (amxClone->callback==NULL) + amxClone->callback=amxSource->callback; + if (amxClone->debug==NULL) + amxClone->debug=amxSource->debug; + amxClone->flags=amxSource->flags; + + /* copy the data segment; the stack and the heap can be left uninitialized */ + assert(data!=NULL); + amxClone->data=(unsigned char _FAR *)data; + dataSource=(amxSource->data!=NULL) ? amxSource->data : amxSource->base+(int)hdr->dat; + memcpy(amxClone->data,dataSource,(size_t)(hdr->hea-hdr->dat)); + + /* Set a zero cell at the top of the stack, which functions + * as a sentinel for strings. + */ + * (cell *)(amxClone->data+(int)amxClone->stp) = 0; + + return AMX_ERR_NONE; +} +#endif /* AMX_CLONE */ + +#if defined AMX_MEMINFO +int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap) +{ + AMX_HEADER *hdr; + + if (amx==NULL) + return AMX_ERR_FORMAT; + hdr=(AMX_HEADER *)amx->base; + if (hdr->magic!=AMX_MAGIC) + return AMX_ERR_FORMAT; + if (hdr->file_version>CUR_FILE_VERSION || hdr->amx_versiondat - hdr->cod; + if (datasize!=NULL) + *datasize=hdr->hea - hdr->dat; + if (stackheap!=NULL) + *stackheap=hdr->stp - hdr->hea; + + return AMX_ERR_NONE; +} +#endif /* AMX_MEMINFO */ + +#if defined AMX_NAMELENGTH +int AMXAPI amx_NameLength(AMX *amx, int *length) +{ + AMX_HEADER *hdr=(AMX_HEADER *)amx->base; + assert(hdr!=NULL); + assert(hdr->magic==AMX_MAGIC); + if (USENAMETABLE(hdr)) { + uint16_t *namelength=(uint16_t*)(amx->base + (unsigned)hdr->nametable); + *length=*namelength; + assert(hdr->file_version>=7); /* name table exists only for file version 7+ */ + } else { + *length=hdr->defsize - sizeof(ucell); + } /* if */ + return AMX_ERR_NONE; +} +#endif /* AMX_NAMELENGTH */ + +#if defined AMX_XXXNATIVES +int AMXAPI amx_NumNatives(AMX *amx, int *number) +{ + AMX_HEADER *hdr=(AMX_HEADER *)amx->base; + assert(hdr!=NULL); + assert(hdr->magic==AMX_MAGIC); + assert(hdr->natives<=hdr->libraries); + *number=NUMENTRIES(hdr,natives,libraries); + return AMX_ERR_NONE; +} + +int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname) +{ + AMX_HEADER *hdr; + AMX_FUNCSTUB *func; + + hdr=(AMX_HEADER *)amx->base; + assert(hdr!=NULL); + assert(hdr->magic==AMX_MAGIC); + assert(hdr->natives<=hdr->libraries); + if (index>=(cell)NUMENTRIES(hdr,natives,libraries)) + return AMX_ERR_INDEX; + + func=GETENTRY(hdr,natives,index); + strcpy(funcname,GETENTRYNAME(hdr,func)); + return AMX_ERR_NONE; +} + +int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index) +{ + int first,last,mid,result; + char pname[sNAMEMAX+1]; + + amx_NumNatives(amx, &last); + last--; /* last valid index is 1 less than the number of functions */ + first=0; + /* binary search */ + while (first<=last) { + mid=(first+last)/2; + amx_GetNative(amx, mid, pname); + result=strcmp(pname,name); + if (result>0) { + last=mid-1; + } else if (result<0) { + first=mid+1; + } else { + *index=mid; + return AMX_ERR_NONE; + } /* if */ + } /* while */ + /* not found, set to an invalid index, so amx_Exec() will fail */ + *index=INT_MAX; + return AMX_ERR_NOTFOUND; +} +#endif /* AMX_XXXNATIVES */ + +#if defined AMX_XXXPUBLICS +int AMXAPI amx_NumPublics(AMX *amx, int *number) +{ + AMX_HEADER *hdr=(AMX_HEADER *)amx->base; + assert(hdr!=NULL); + assert(hdr->magic==AMX_MAGIC); + assert(hdr->publics<=hdr->natives); + *number=NUMENTRIES(hdr,publics,natives); + return AMX_ERR_NONE; +} + +int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname) +{ + AMX_HEADER *hdr; + AMX_FUNCSTUB *func; + + hdr=(AMX_HEADER *)amx->base; + assert(hdr!=NULL); + assert(hdr->magic==AMX_MAGIC); + assert(hdr->publics<=hdr->natives); + if (index>=(cell)NUMENTRIES(hdr,publics,natives)) + return AMX_ERR_INDEX; + + func=GETENTRY(hdr,publics,index); + strcpy(funcname,GETENTRYNAME(hdr,func)); + return AMX_ERR_NONE; +} + +int AMXAPI amx_FindPublic(AMX *amx, const char *name, int *index) +{ + int first,last,mid,result; + char pname[sNAMEMAX+1]; + + amx_NumPublics(amx, &last); + last--; /* last valid index is 1 less than the number of functions */ + first=0; + /* binary search */ + while (first<=last) { + mid=(first+last)/2; + amx_GetPublic(amx, mid, pname); + result=strcmp(pname,name); + if (result>0) { + last=mid-1; + } else if (result<0) { + first=mid+1; + } else { + *index=mid; + return AMX_ERR_NONE; + } /* if */ + } /* while */ + /* not found, set to an invalid index, so amx_Exec() will fail */ + *index=INT_MAX; + return AMX_ERR_NOTFOUND; +} +#endif /* AMX_XXXPUBLICS */ + +#if defined AMX_XXXPUBVARS +int AMXAPI amx_NumPubVars(AMX *amx, int *number) +{ + AMX_HEADER *hdr=(AMX_HEADER *)amx->base; + assert(hdr!=NULL); + assert(hdr->magic==AMX_MAGIC); + assert(hdr->pubvars<=hdr->tags); + *number=NUMENTRIES(hdr,pubvars,tags); + return AMX_ERR_NONE; +} + +int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr) +{ + AMX_HEADER *hdr; + AMX_FUNCSTUB *var; + + hdr=(AMX_HEADER *)amx->base; + assert(hdr!=NULL); + assert(hdr->magic==AMX_MAGIC); + assert(hdr->pubvars<=hdr->tags); + if (index>=(cell)NUMENTRIES(hdr,pubvars,tags)) + return AMX_ERR_INDEX; + + var=GETENTRY(hdr,pubvars,index); + strcpy(varname,GETENTRYNAME(hdr,var)); + *amx_addr=var->address; + return AMX_ERR_NONE; +} + +int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr) +{ + int first,last,mid,result; + char pname[sNAMEMAX+1]; + cell paddr; + + amx_NumPubVars(amx, &last); + last--; /* last valid index is 1 less than the number of functions */ + first=0; + /* binary search */ + while (first<=last) { + mid=(first+last)/2; + amx_GetPubVar(amx, mid, pname, &paddr); + result=strcmp(pname,varname); + if (result>0) { + last=mid-1; + } else if (result<0) { + first=mid+1; + } else { + *amx_addr=paddr; + return AMX_ERR_NONE; + } /* if */ + } /* while */ + /* not found */ + *amx_addr=0; + return AMX_ERR_NOTFOUND; +} +#endif /* AMX_XXXPUBVARS */ + +#if defined AMX_XXXTAGS +int AMXAPI amx_NumTags(AMX *amx, int *number) +{ + AMX_HEADER *hdr=(AMX_HEADER *)amx->base; + assert(hdr!=NULL); + assert(hdr->magic==AMX_MAGIC); + if (hdr->file_version<5) { /* the tagname table appeared in file format 5 */ + *number=0; + return AMX_ERR_VERSION; + } /* if */ + if (hdr->file_version<7) { + assert(hdr->tags<=hdr->cod); + *number=NUMENTRIES(hdr,tags,cod); + } else { + assert(hdr->tags<=hdr->nametable); + *number=NUMENTRIES(hdr,tags,nametable); + } /* if */ + return AMX_ERR_NONE; +} + +int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id) +{ + AMX_HEADER *hdr; + AMX_FUNCSTUB *tag; + + hdr=(AMX_HEADER *)amx->base; + assert(hdr!=NULL); + assert(hdr->magic==AMX_MAGIC); + if (hdr->file_version<5) { /* the tagname table appeared in file format 5 */ + *tagname='\0'; + *tag_id=0; + return AMX_ERR_VERSION; + } /* if */ + + if (hdr->file_version<7) { + assert(hdr->tags<=hdr->cod); + if (index>=(cell)NUMENTRIES(hdr,tags,cod)) + return AMX_ERR_INDEX; + } else { + assert(hdr->tags<=hdr->nametable); + if (index>=(cell)NUMENTRIES(hdr,tags,nametable)) + return AMX_ERR_INDEX; + } /* if */ + + tag=GETENTRY(hdr,tags,index); + strcpy(tagname,GETENTRYNAME(hdr,tag)); + *tag_id=tag->address; + + return AMX_ERR_NONE; +} + +int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname) +{ + int first,last,mid; + cell mid_id; + + #if !defined NDEBUG + /* verify that the tagname table is sorted on the tag_id */ + amx_NumTags(amx, &last); + if (last>0) { + cell cur_id; + amx_GetTag(amx,0,tagname,&cur_id); + for (first=1; firsttag_id) + last=mid-1; + else if (mid_idusertags[index]!=tag; index++) + /* nothing */; + if (index>=AMX_USERNUM) + return AMX_ERR_USERDATA; + *ptr=amx->userdata[index]; + return AMX_ERR_NONE; +} + +int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr) +{ + int index; + + assert(amx!=NULL); + assert(tag!=0); + /* try to find existing tag */ + for (index=0; indexusertags[index]!=tag; index++) + /* nothing */; + /* if not found, try to find empty tag */ + if (index>=AMX_USERNUM) + for (index=0; indexusertags[index]!=0; index++) + /* nothing */; + /* if still not found, quit with error */ + if (index>=AMX_USERNUM) + return AMX_ERR_INDEX; + /* set the tag and the value */ + amx->usertags[index]=tag; + amx->userdata[index]=ptr; + return AMX_ERR_NONE; +} +#endif /* AMX_XXXUSERDATA */ + +#if defined AMX_REGISTER || defined AMX_EXEC || defined AMX_INIT +static AMX_NATIVE findfunction(const char *name, const AMX_NATIVE_INFO *list, int number) +{ + int i; + + assert(list!=NULL); + for (i=0; list[i].name!=NULL && (ibase; + assert(hdr!=NULL); + assert(hdr->magic==AMX_MAGIC); + assert(hdr->natives<=hdr->libraries); + numnatives=NUMENTRIES(hdr,natives,libraries); + + err=AMX_ERR_NONE; + func=GETENTRY(hdr,natives,0); + for (i=0; iaddress==0) { + /* this function is not yet located */ + funcptr=(list!=NULL) ? findfunction(GETENTRYNAME(hdr,func),list,number) : NULL; + if (funcptr!=NULL) + func->address=(ucell)funcptr; + else + err=AMX_ERR_NOTFOUND; + } /* if */ + func=(AMX_FUNCSTUB*)((unsigned char*)func+hdr->defsize); + } /* for */ + if (err==AMX_ERR_NONE) + amx->flags|=AMX_FLAG_NTVREG; + return err; +} +#endif /* AMX_REGISTER || AMX_EXEC || AMX_INIT */ + +#if defined AMX_NATIVEINFO +AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func) +{ + static AMX_NATIVE_INFO n; + n.name=name; + n.func=func; + return &n; +} +#endif /* AMX_NATIVEINFO */ + +#if defined AMX_EXEC || defined AMX_INIT + +#define STKMARGIN ((cell)(16*sizeof(cell))) + +int AMXAPI amx_Push(AMX *amx, cell value) +{ + AMX_HEADER *hdr; + unsigned char *data; + + if (amx->hea+STKMARGIN>amx->stk) + return AMX_ERR_STACKERR; + hdr=(AMX_HEADER *)amx->base; + data=(amx->data!=NULL) ? amx->data : amx->base+(int)hdr->dat; + amx->stk-=sizeof(cell); + amx->paramcount+=1; + *(cell *)(data+(int)amx->stk)=value; + return AMX_ERR_NONE; +} + +int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells) +{ + cell *paddr; + int err; + + assert(amx!=NULL); + assert(amx_addr!=NULL); + assert(array!=NULL); + + err=amx_Allot(amx,numcells,amx_addr,&paddr); + if (err==AMX_ERR_NONE) { + if (phys_addr!=NULL) + *phys_addr=paddr; + memcpy(paddr,array,numcells*sizeof(cell)); + err=amx_Push(amx,*amx_addr); + } /* if */ + return err; +} + +int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar) +{ + cell *paddr; + int numcells,err; + + assert(amx!=NULL); + assert(amx_addr!=NULL); + assert(string!=NULL); + + #if defined AMX_ANSIONLY + numcells=strlen(string) + 1; + #else + numcells= (use_wchar ? wcslen((const wchar_t*)string) : strlen(string)) + 1; + #endif + if (pack) + numcells=(numcells+sizeof(cell)-1)/sizeof(cell); + err=amx_Allot(amx,numcells,amx_addr,&paddr); + if (err==AMX_ERR_NONE) { + if (phys_addr!=NULL) + *phys_addr=paddr; + amx_SetString(paddr,string,pack,use_wchar,UNLIMITED); + err=amx_Push(amx,*amx_addr); + } /* if */ + return err; +} + +#define GETPARAM(v) ( v=*(cell *)cip++ ) +#define SKIPPARAM(n) ( cip=(cell *)cip+(n) ) +#define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v ) +#define POP(v) ( v=*(cell *)(data+(int)stk), stk+=sizeof(cell) ) +#define ABORT(amx,v) { (amx)->stk=reset_stk; (amx)->hea=reset_hea; return v; } + +#define CHKMARGIN() if (hea+STKMARGIN>stk) return AMX_ERR_STACKERR +#define CHKSTACK() if (stk>amx->stp) return AMX_ERR_STACKLOW +#define CHKHEAP() if (heahlw) return AMX_ERR_HEAPLOW + +#if defined __GNUC__ && !(defined ASM32 || defined JIT) + /* GNU C version uses the "labels as values" extension to create + * fast "indirect threaded" interpreter. + */ + +#define NEXT(cip) goto **cip++ + +int AMXAPI amx_Exec(AMX *amx, cell *retval, int index) +{ +static const void * const amx_opcodelist[] = { + &&op_none, &&op_load_pri, &&op_load_alt, &&op_load_s_pri, + &&op_load_s_alt,&&op_lref_pri, &&op_lref_alt, &&op_lref_s_pri, + &&op_lref_s_alt,&&op_load_i, &&op_lodb_i, &&op_const_pri, + &&op_const_alt, &&op_addr_pri, &&op_addr_alt, &&op_stor_pri, + &&op_stor_alt, &&op_stor_s_pri,&&op_stor_s_alt,&&op_sref_pri, + &&op_sref_alt, &&op_sref_s_pri,&&op_sref_s_alt,&&op_stor_i, + &&op_strb_i, &&op_lidx, &&op_lidx_b, &&op_idxaddr, + &&op_idxaddr_b, &&op_align_pri, &&op_align_alt, &&op_lctrl, + &&op_sctrl, &&op_move_pri, &&op_move_alt, &&op_xchg, + &&op_push_pri, &&op_push_alt, &&op_push_r, &&op_push_c, + &&op_push, &&op_push_s, &&op_pop_pri, &&op_pop_alt, + &&op_stack, &&op_heap, &&op_proc, &&op_ret, + &&op_retn, &&op_call, &&op_call_pri, &&op_jump, + &&op_jrel, &&op_jzer, &&op_jnz, &&op_jeq, + &&op_jneq, &&op_jless, &&op_jleq, &&op_jgrtr, + &&op_jgeq, &&op_jsless, &&op_jsleq, &&op_jsgrtr, + &&op_jsgeq, &&op_shl, &&op_shr, &&op_sshr, + &&op_shl_c_pri, &&op_shl_c_alt, &&op_shr_c_pri, &&op_shr_c_alt, + &&op_smul, &&op_sdiv, &&op_sdiv_alt, &&op_umul, + &&op_udiv, &&op_udiv_alt, &&op_add, &&op_sub, + &&op_sub_alt, &&op_and, &&op_or, &&op_xor, + &&op_not, &&op_neg, &&op_invert, &&op_add_c, + &&op_smul_c, &&op_zero_pri, &&op_zero_alt, &&op_zero, + &&op_zero_s, &&op_sign_pri, &&op_sign_alt, &&op_eq, + &&op_neq, &&op_less, &&op_leq, &&op_grtr, + &&op_geq, &&op_sless, &&op_sleq, &&op_sgrtr, + &&op_sgeq, &&op_eq_c_pri, &&op_eq_c_alt, &&op_inc_pri, + &&op_inc_alt, &&op_inc, &&op_inc_s, &&op_inc_i, + &&op_dec_pri, &&op_dec_alt, &&op_dec, &&op_dec_s, + &&op_dec_i, &&op_movs, &&op_cmps, &&op_fill, + &&op_halt, &&op_bounds, &&op_sysreq_pri,&&op_sysreq_c, + &&op_file, &&op_line, &&op_symbol, &&op_srange, + &&op_jump_pri, &&op_switch, &&op_casetbl, &&op_swap_pri, + &&op_swap_alt, &&op_pushaddr, &&op_nop, &&op_sysreq_d, + &&op_symtag, &&op_break }; + AMX_HEADER *hdr; + AMX_FUNCSTUB *func; + unsigned char *code, *data; + cell pri,alt,stk,frm,hea; + cell reset_stk, reset_hea, *cip; + cell offs; + ucell codesize; + int num,i; + + /* HACK: return label table (for amx_BrowseRelocate) if amx structure + * has the AMX_FLAG_BROWSE flag set. + */ + assert(amx!=NULL); + if ((amx->flags & AMX_FLAG_BROWSE)==AMX_FLAG_BROWSE) { + assert(sizeof(cell)==sizeof(void *)); + assert(retval!=NULL); + *retval=(cell)amx_opcodelist; + return 0; + } /* if */ + + if (amx->callback==NULL) + return AMX_ERR_CALLBACK; + if ((amx->flags & AMX_FLAG_NTVREG)==0) + return AMX_ERR_NOTFOUND; + if ((amx->flags & AMX_FLAG_RELOC)==0) + return AMX_ERR_INIT; + assert((amx->flags & AMX_FLAG_BROWSE)==0); + + /* set up the registers */ + hdr=(AMX_HEADER *)amx->base; + assert(hdr->magic==AMX_MAGIC); + codesize=(ucell)(hdr->dat-hdr->cod); + code=amx->base+(int)hdr->cod; + data=(amx->data!=NULL) ? amx->data : amx->base+(int)hdr->dat; + hea=amx->hea; + stk=amx->stk; + reset_stk=stk; + reset_hea=hea; + alt=frm=0; /* just to avoid compiler warnings */ + num=0; /* just to avoid compiler warnings */ + + /* get the start address */ + if (index==AMX_EXEC_MAIN) { + if (hdr->cip<0) + return AMX_ERR_INDEX; + cip=(cell *)(code + (int)hdr->cip); + } else if (index==AMX_EXEC_CONT) { + /* all registers: pri, alt, frm, cip, hea, stk, reset_stk, reset_hea */ + frm=amx->frm; + stk=amx->stk; + hea=amx->hea; + pri=amx->pri; + alt=amx->alt; + reset_stk=amx->reset_stk; + reset_hea=amx->reset_hea; + cip=(cell *)(code + (int)amx->cip); + } else if (index<0) { + return AMX_ERR_INDEX; + } else { + if (index>=(int)NUMENTRIES(hdr,publics,natives)) + return AMX_ERR_INDEX; + func=GETENTRY(hdr,publics,index); + cip=(cell *)(code + (int)func->address); + } /* if */ + /* check values just copied */ + CHKSTACK(); + CHKHEAP(); + assert(check_endian()); + + /* sanity checks */ + assert(OP_PUSH_PRI==36); + assert(OP_PROC==46); + assert(OP_SHL==65); + assert(OP_SMUL==72); + assert(OP_EQ==95); + assert(OP_INC_PRI==107); + assert(OP_MOVS==117); + assert(OP_SYMBOL==126); + #if PAWN_CELL_SIZE==16 + assert(sizeof(cell)==2); + #elif PAWN_CELL_SIZE==32 + assert(sizeof(cell)==4); + #elif PAWN_CELL_SIZE==64 + assert(sizeof(cell)==8); + #else + #error Unsupported cell size + #endif + + if (index!=AMX_EXEC_CONT) { + reset_stk+=amx->paramcount*sizeof(cell); + PUSH(amx->paramcount*sizeof(cell)); + amx->paramcount=0; /* push the parameter count to the stack & reset */ + PUSH(0); /* zero return address */ + } /* if */ + /* check stack/heap before starting to run */ + CHKMARGIN(); + + /* start running */ + NEXT(cip); + + op_none: + ABORT(amx,AMX_ERR_INVINSTR); + op_load_pri: + GETPARAM(offs); + pri= * (cell *)(data+(int)offs); + NEXT(cip); + op_load_alt: + GETPARAM(offs); + alt= * (cell *)(data+(int)offs); + NEXT(cip); + op_load_s_pri: + GETPARAM(offs); + pri= * (cell *)(data+(int)frm+(int)offs); + NEXT(cip); + op_load_s_alt: + GETPARAM(offs); + alt= * (cell *)(data+(int)frm+(int)offs); + NEXT(cip); + op_lref_pri: + GETPARAM(offs); + offs= * (cell *)(data+(int)offs); + pri= * (cell *)(data+(int)offs); + NEXT(cip); + op_lref_alt: + GETPARAM(offs); + offs= * (cell *)(data+(int)offs); + alt= * (cell *)(data+(int)offs); + NEXT(cip); + op_lref_s_pri: + GETPARAM(offs); + offs= * (cell *)(data+(int)frm+(int)offs); + pri= * (cell *)(data+(int)offs); + NEXT(cip); + op_lref_s_alt: + GETPARAM(offs); + offs= * (cell *)(data+(int)frm+(int)offs); + alt= * (cell *)(data+(int)offs); + NEXT(cip); + op_load_i: + /* verify address */ + if (pri>=hea && pri=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + pri= * (cell *)(data+(int)pri); + NEXT(cip); + op_lodb_i: + GETPARAM(offs); + /* verify address */ + if (pri>=hea && pri=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + switch (offs) { + case 1: + pri= * (data+(int)pri); + break; + case 2: + pri= * (uint16_t *)(data+(int)pri); + break; + case 4: + pri= * (uint32_t *)(data+(int)pri); + break; + } /* switch */ + NEXT(cip); + op_const_pri: + GETPARAM(pri); + NEXT(cip); + op_const_alt: + GETPARAM(alt); + NEXT(cip); + op_addr_pri: + GETPARAM(pri); + pri+=frm; + NEXT(cip); + op_addr_alt: + GETPARAM(alt); + alt+=frm; + NEXT(cip); + op_stor_pri: + GETPARAM(offs); + *(cell *)(data+(int)offs)=pri; + NEXT(cip); + op_stor_alt: + GETPARAM(offs); + *(cell *)(data+(int)offs)=alt; + NEXT(cip); + op_stor_s_pri: + GETPARAM(offs); + *(cell *)(data+(int)frm+(int)offs)=pri; + NEXT(cip); + op_stor_s_alt: + GETPARAM(offs); + *(cell *)(data+(int)frm+(int)offs)=alt; + NEXT(cip); + op_sref_pri: + GETPARAM(offs); + offs= * (cell *)(data+(int)offs); + *(cell *)(data+(int)offs)=pri; + NEXT(cip); + op_sref_alt: + GETPARAM(offs); + offs= * (cell *)(data+(int)offs); + *(cell *)(data+(int)offs)=alt; + NEXT(cip); + op_sref_s_pri: + GETPARAM(offs); + offs= * (cell *)(data+(int)frm+(int)offs); + *(cell *)(data+(int)offs)=pri; + NEXT(cip); + op_sref_s_alt: + GETPARAM(offs); + offs= * (cell *)(data+(int)frm+(int)offs); + *(cell *)(data+(int)offs)=alt; + NEXT(cip); + op_stor_i: + /* verify address */ + if (alt>=hea && alt=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + *(cell *)(data+(int)alt)=pri; + NEXT(cip); + op_strb_i: + GETPARAM(offs); + /* verify address */ + if (alt>=hea && alt=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + switch (offs) { + case 1: + *(data+(int)alt)=(unsigned char)pri; + break; + case 2: + *(uint16_t *)(data+(int)alt)=(uint16_t)pri; + break; + case 4: + *(uint32_t *)(data+(int)alt)=(uint32_t)pri; + break; + } /* switch */ + NEXT(cip); + op_lidx: + offs=pri*sizeof(cell)+alt; + /* verify address */ + if (offs>=hea && offs=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + pri= * (cell *)(data+(int)offs); + NEXT(cip); + op_lidx_b: + GETPARAM(offs); + offs=(pri << (int)offs)+alt; + /* verify address */ + if (offs>=hea && offs=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + pri= * (cell *)(data+(int)offs); + NEXT(cip); + op_idxaddr: + pri=pri*sizeof(cell)+alt; + NEXT(cip); + op_idxaddr_b: + GETPARAM(offs); + pri=(pri << (int)offs)+alt; + NEXT(cip); + op_align_pri: + GETPARAM(offs); + #if BYTE_ORDER==LITTLE_ENDIAN + if (offs<(int)sizeof(cell)) + pri ^= sizeof(cell)-offs; + #endif + NEXT(cip); + op_align_alt: + GETPARAM(offs); + #if BYTE_ORDER==LITTLE_ENDIAN + if (offs<(int)sizeof(cell)) + alt ^= sizeof(cell)-offs; + #endif + NEXT(cip); + op_lctrl: + GETPARAM(offs); + switch (offs) { + case 0: + pri=hdr->cod; + break; + case 1: + pri=hdr->dat; + break; + case 2: + pri=hea; + break; + case 3: + pri=amx->stp; + break; + case 4: + pri=stk; + break; + case 5: + pri=frm; + break; + case 6: + pri=(cell)((unsigned char *)cip - code); + break; + } /* switch */ + NEXT(cip); + op_sctrl: + GETPARAM(offs); + switch (offs) { + case 0: + case 1: + case 3: + /* cannot change these parameters */ + break; + case 2: + hea=pri; + break; + case 4: + stk=pri; + break; + case 5: + frm=pri; + break; + case 6: + cip=(cell *)(code + (int)pri); + break; + } /* switch */ + NEXT(cip); + op_move_pri: + pri=alt; + NEXT(cip); + op_move_alt: + alt=pri; + NEXT(cip); + op_xchg: + offs=pri; /* offs is a temporary variable */ + pri=alt; + alt=offs; + NEXT(cip); + op_push_pri: + PUSH(pri); + NEXT(cip); + op_push_alt: + PUSH(alt); + NEXT(cip); + op_push_c: + GETPARAM(offs); + PUSH(offs); + NEXT(cip); + op_push_r: + GETPARAM(offs); + while (offs--) + PUSH(pri); + NEXT(cip); + op_push: + GETPARAM(offs); + PUSH(* (cell *)(data+(int)offs)); + NEXT(cip); + op_push_s: + GETPARAM(offs); + PUSH(* (cell *)(data+(int)frm+(int)offs)); + NEXT(cip); + op_pop_pri: + POP(pri); + NEXT(cip); + op_pop_alt: + POP(alt); + NEXT(cip); + op_stack: + GETPARAM(offs); + alt=stk; + stk+=offs; + CHKMARGIN(); + CHKSTACK(); + NEXT(cip); + op_heap: + GETPARAM(offs); + alt=hea; + hea+=offs; + CHKMARGIN(); + CHKHEAP(); + NEXT(cip); + op_proc: + PUSH(frm); + frm=stk; + CHKMARGIN(); + NEXT(cip); + op_ret: + POP(frm); + POP(offs); + /* verify the return address */ + if ((ucell)offs>=codesize) + ABORT(amx,AMX_ERR_MEMACCESS); + cip=(cell *)(code+(int)offs); + NEXT(cip); + op_retn: + POP(frm); + POP(offs); + /* verify the return address */ + if ((ucell)offs>=codesize) + ABORT(amx,AMX_ERR_MEMACCESS); + cip=(cell *)(code+(int)offs); + stk+= *(cell *)(data+(int)stk) + sizeof(cell); /* remove parameters from the stack */ + NEXT(cip); + op_call: + PUSH(((unsigned char *)cip-code)+sizeof(cell));/* push address behind instruction */ + cip=JUMPABS(code, cip); /* jump to the address */ + NEXT(cip); + op_call_pri: + PUSH((unsigned char *)cip-code); + cip=(cell *)(code+(int)pri); + NEXT(cip); + op_jump: + /* since the GETPARAM() macro modifies cip, you cannot + * do GETPARAM(cip) directly */ + cip=JUMPABS(code, cip); + NEXT(cip); + op_jrel: + offs=*cip; + cip=(cell *)((unsigned char *)cip + (int)offs + sizeof(cell)); + NEXT(cip); + op_jzer: + if (pri==0) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + NEXT(cip); + op_jnz: + if (pri!=0) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + NEXT(cip); + op_jeq: + if (pri==alt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + NEXT(cip); + op_jneq: + if (pri!=alt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + NEXT(cip); + op_jless: + if ((ucell)pri < (ucell)alt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + NEXT(cip); + op_jleq: + if ((ucell)pri <= (ucell)alt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + NEXT(cip); + op_jgrtr: + if ((ucell)pri > (ucell)alt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + NEXT(cip); + op_jgeq: + if ((ucell)pri >= (ucell)alt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + NEXT(cip); + op_jsless: + if (prialt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + NEXT(cip); + op_jsgeq: + if (pri>=alt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + NEXT(cip); + op_shl: + pri<<=alt; + NEXT(cip); + op_shr: + pri=(ucell)pri >> (ucell)alt; + NEXT(cip); + op_sshr: + pri>>=alt; + NEXT(cip); + op_shl_c_pri: + GETPARAM(offs); + pri<<=offs; + NEXT(cip); + op_shl_c_alt: + GETPARAM(offs); + alt<<=offs; + NEXT(cip); + op_shr_c_pri: + GETPARAM(offs); + pri=(ucell)pri >> (ucell)offs; + NEXT(cip); + op_shr_c_alt: + GETPARAM(offs); + alt=(ucell)alt >> (ucell)offs; + NEXT(cip); + op_smul: + pri*=alt; + NEXT(cip); + op_sdiv: + if (alt==0) + ABORT(amx,AMX_ERR_DIVIDE); + /* divide must always round down; this is a bit + * involved to do in a machine-independent way. + */ + offs=(pri % alt + alt) % alt; /* true modulus */ + pri=(pri - offs) / alt; /* division result */ + alt=offs; + NEXT(cip); + op_sdiv_alt: + if (pri==0) + ABORT(amx,AMX_ERR_DIVIDE); + /* divide must always round down; this is a bit + * involved to do in a machine-independent way. + */ + offs=(alt % pri + pri) % pri; /* true modulus */ + pri=(alt - offs) / pri; /* division result */ + alt=offs; + NEXT(cip); + op_umul: + pri=(ucell)pri * (ucell)alt; + NEXT(cip); + op_udiv: + if (alt==0) + ABORT(amx,AMX_ERR_DIVIDE); + offs=(ucell)pri % (ucell)alt; /* temporary storage */ + pri=(ucell)pri / (ucell)alt; + alt=offs; + NEXT(cip); + op_udiv_alt: + if (pri==0) + ABORT(amx,AMX_ERR_DIVIDE); + offs=(ucell)alt % (ucell)pri; /* temporary storage */ + pri=(ucell)alt / (ucell)pri; + alt=offs; + NEXT(cip); + op_add: + pri+=alt; + NEXT(cip); + op_sub: + pri-=alt; + NEXT(cip); + op_sub_alt: + pri=alt-pri; + NEXT(cip); + op_and: + pri&=alt; + NEXT(cip); + op_or: + pri|=alt; + NEXT(cip); + op_xor: + pri^=alt; + NEXT(cip); + op_not: + pri=!pri; + NEXT(cip); + op_neg: + pri=-pri; + NEXT(cip); + op_invert: + pri=~pri; + NEXT(cip); + op_add_c: + GETPARAM(offs); + pri+=offs; + NEXT(cip); + op_smul_c: + GETPARAM(offs); + pri*=offs; + NEXT(cip); + op_zero_pri: + pri=0; + NEXT(cip); + op_zero_alt: + alt=0; + NEXT(cip); + op_zero: + GETPARAM(offs); + *(cell *)(data+(int)offs)=0; + NEXT(cip); + op_zero_s: + GETPARAM(offs); + *(cell *)(data+(int)frm+(int)offs)=0; + NEXT(cip); + op_sign_pri: + if ((pri & 0xff)>=0x80) + pri|= ~ (ucell)0xff; + NEXT(cip); + op_sign_alt: + if ((alt & 0xff)>=0x80) + alt|= ~ (ucell)0xff; + NEXT(cip); + op_eq: + pri= pri==alt ? 1 : 0; + NEXT(cip); + op_neq: + pri= pri!=alt ? 1 : 0; + NEXT(cip); + op_less: + pri= (ucell)pri < (ucell)alt ? 1 : 0; + NEXT(cip); + op_leq: + pri= (ucell)pri <= (ucell)alt ? 1 : 0; + NEXT(cip); + op_grtr: + pri= (ucell)pri > (ucell)alt ? 1 : 0; + NEXT(cip); + op_geq: + pri= (ucell)pri >= (ucell)alt ? 1 : 0; + NEXT(cip); + op_sless: + pri= prialt ? 1 : 0; + NEXT(cip); + op_sgeq: + pri= pri>=alt ? 1 : 0; + NEXT(cip); + op_eq_c_pri: + GETPARAM(offs); + pri= pri==offs ? 1 : 0; + NEXT(cip); + op_eq_c_alt: + GETPARAM(offs); + pri= alt==offs ? 1 : 0; + NEXT(cip); + op_inc_pri: + pri++; + NEXT(cip); + op_inc_alt: + alt++; + NEXT(cip); + op_inc: + GETPARAM(offs); + *(cell *)(data+(int)offs) += 1; + NEXT(cip); + op_inc_s: + GETPARAM(offs); + *(cell *)(data+(int)frm+(int)offs) += 1; + NEXT(cip); + op_inc_i: + *(cell *)(data+(int)pri) += 1; + NEXT(cip); + op_dec_pri: + pri--; + NEXT(cip); + op_dec_alt: + alt--; + NEXT(cip); + op_dec: + GETPARAM(offs); + *(cell *)(data+(int)offs) -= 1; + NEXT(cip); + op_dec_s: + GETPARAM(offs); + *(cell *)(data+(int)frm+(int)offs) -= 1; + NEXT(cip); + op_dec_i: + *(cell *)(data+(int)pri) -= 1; + NEXT(cip); + op_movs: + GETPARAM(offs); + /* verify top & bottom memory addresses, for both source and destination + * addresses + */ + if (pri>=hea && pri=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + if ((pri+offs)>hea && (pri+offs)(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + if (alt>=hea && alt=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + if ((alt+offs)>hea && (alt+offs)(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + memcpy(data+(int)alt, data+(int)pri, (int)offs); + NEXT(cip); + op_cmps: + GETPARAM(offs); + /* verify top & bottom memory addresses, for both source and destination + * addresses + */ + if (pri>=hea && pri=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + if ((pri+offs)>hea && (pri+offs)(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + if (alt>=hea && alt=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + if ((alt+offs)>hea && (alt+offs)(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + pri=memcmp(data+(int)alt, data+(int)pri, (int)offs); + NEXT(cip); + op_fill: + GETPARAM(offs); + /* verify top & bottom memory addresses */ + if (alt>=hea && alt=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + if ((alt+offs)>hea && (alt+offs)(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + for (i=(int)alt; offs>=(int)sizeof(cell); i+=sizeof(cell), offs-=sizeof(cell)) + *(cell *)(data+i) = pri; + NEXT(cip); + op_halt: + GETPARAM(offs); + if (retval!=NULL) + *retval=pri; + /* store complete status (stk and hea are already set in the ABORT macro) */ + amx->frm=frm; + amx->pri=pri; + amx->alt=alt; + amx->cip=(cell)((unsigned char*)cip-code); + if (offs==AMX_ERR_SLEEP) { + amx->reset_stk=reset_stk; + amx->reset_hea=reset_hea; + return (int)offs; + } /* if */ + ABORT(amx,(int)offs); + op_bounds: + GETPARAM(offs); + if ((ucell)pri>(ucell)offs) + ABORT(amx,AMX_ERR_BOUNDS); + NEXT(cip); + op_sysreq_pri: + /* save a few registers */ + amx->cip=(cell)((unsigned char *)cip-code); + amx->hea=hea; + amx->frm=frm; + amx->stk=stk; + num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk)); + if (num!=AMX_ERR_NONE) { + if (num==AMX_ERR_SLEEP) { + amx->pri=pri; + amx->alt=alt; + amx->reset_stk=reset_stk; + amx->reset_hea=reset_hea; + return num; + } /* if */ + ABORT(amx,num); + } /* if */ + NEXT(cip); + op_sysreq_c: + GETPARAM(offs); + /* save a few registers */ + amx->cip=(cell)((unsigned char *)cip-code); + amx->hea=hea; + amx->frm=frm; + amx->stk=stk; + num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk)); + if (num!=AMX_ERR_NONE) { + if (num==AMX_ERR_SLEEP) { + amx->pri=pri; + amx->alt=alt; + amx->reset_stk=reset_stk; + amx->reset_hea=reset_hea; + return num; + } /* if */ + ABORT(amx,num); + } /* if */ + NEXT(cip); + op_sysreq_d: + GETPARAM(offs); + /* save a few registers */ + amx->cip=(cell)((unsigned char *)cip-code); + amx->hea=hea; + amx->frm=frm; + amx->stk=stk; + pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk)); + if (amx->error!=AMX_ERR_NONE) { + if (amx->error==AMX_ERR_SLEEP) { + amx->pri=pri; + amx->alt=alt; + amx->reset_stk=reset_stk; + amx->reset_hea=reset_hea; + return num; + } /* if */ + ABORT(amx,amx->error); + } /* if */ + NEXT(cip); + op_file: + GETPARAM(offs); + cip=(cell *)((unsigned char *)cip + (int)offs); + assert(0); /* this code should not occur during execution */ + NEXT(cip); + op_line: + SKIPPARAM(2); + NEXT(cip); + op_symbol: + GETPARAM(offs); + cip=(cell *)((unsigned char *)cip + (int)offs); + NEXT(cip); + op_srange: + SKIPPARAM(2); + NEXT(cip); + op_symtag: + SKIPPARAM(1); + NEXT(cip); + op_jump_pri: + cip=(cell *)(code+(int)pri); + NEXT(cip); + op_switch: { + cell *cptr; + cptr=JUMPABS(code,cip)+1; /* +1, to skip the "casetbl" opcode */ + cip=JUMPABS(code,cptr+1); /* preset to "none-matched" case */ + num=(int)*cptr; /* number of records in the case table */ + for (cptr+=2; num>0 && *cptr!=pri; num--,cptr+=2) + /* nothing */; + if (num>0) + cip=JUMPABS(code,cptr+1); /* case found */ + NEXT(cip); + } + op_casetbl: + assert(0); /* this should not occur during execution */ + NEXT(cip); + op_swap_pri: + offs=*(cell *)(data+(int)stk); + *(cell *)(data+(int)stk)=pri; + pri=offs; + NEXT(cip); + op_swap_alt: + offs=*(cell *)(data+(int)stk); + *(cell *)(data+(int)stk)=alt; + alt=offs; + NEXT(cip); + op_pushaddr: + GETPARAM(offs); + PUSH(frm+offs); + NEXT(cip); + op_nop: + NEXT(cip); + op_break: + if (amx->debug!=NULL) { + /* store status */ + amx->frm=frm; + amx->stk=stk; + amx->hea=hea; + amx->cip=(cell)((unsigned char*)cip-code); + num=amx->debug(amx); + if (num!=AMX_ERR_NONE) { + if (num==AMX_ERR_SLEEP) { + amx->pri=pri; + amx->alt=alt; + amx->reset_stk=reset_stk; + amx->reset_hea=reset_hea; + return num; + } /* if */ + ABORT(amx,num); + } /* if */ + } /* if */ + NEXT(cip); +} + +#else + /* ANSI C & assembler versions */ + +#if defined ASM32 || defined JIT + /* For Watcom C/C++ use register calling convention (faster); for + * Microsoft C/C++ (and most other C compilers) use "cdecl". + * The important point is that you assemble AMXEXEC.ASM with the matching + * calling convention, or the right JIT, respectively. + * AMXJITR.ASM is for Watcom's register calling convention, AMXJITS.ASM and + * AMXJITSN.ASM are for "cdecl". + */ + #if defined __WATCOMC__ + #if !defined STACKARGS /* for AMX32.DLL */ + extern cell amx_exec_asm(cell *regs,cell *retval,cell stp,cell hea); + /* The following pragma tells the compiler into which registers + * the parameters have to go. */ + #pragma aux amx_exec_asm parm [eax] [edx] [ebx] [ecx]; + extern cell amx_exec_jit(cell *regs,cell *retval,cell stp,cell hea); + #pragma aux amx_exec_jit parm [eax] [edx] [ebx] [ecx]; + #else + extern cell __cdecl amx_exec_asm(cell *regs,cell *retval,cell stp,cell hea); + extern cell __cdecl amx_exec_jit(cell *regs,cell *retval,cell stp,cell hea); + #endif + #elif defined __GNUC__ + /* force "cdecl" by adding an "attribute" to the declaration */ + extern cell amx_exec_asm(cell *regs,cell *retval,cell stp,cell hea) __attribute__((cdecl)); + extern cell amx_exec_jit(cell *regs,cell *retval,cell stp,cell hea) __attribute__((cdecl)); + #else + /* force "cdecl" by specifying it as a "function class" with the "__cdecl" keyword */ + extern cell __cdecl amx_exec_asm(cell *regs,cell *retval,cell stp,cell hea); + extern cell __cdecl amx_exec_jit(cell *regs,cell *retval,cell stp,cell hea); + #endif +#endif + +int AMXAPI amx_Exec(AMX *amx, cell *retval, int index) +{ + AMX_HEADER *hdr; + AMX_FUNCSTUB *func; + unsigned char *code, *data; + cell pri,alt,stk,frm,hea; + cell reset_stk, reset_hea, *cip; + ucell codesize; + int i; + #if defined ASM32 || defined JIT + cell parms[9]; /* registers and parameters for assembler AMX */ + #else + OPCODE op; + cell offs; + int num; + #endif + #if defined ASM32 + extern void const *amx_opcodelist[]; + #ifdef __WATCOMC__ + #pragma aux amx_opcodelist "_*" + #endif + #endif + #if defined JIT + extern void const *amx_opcodelist_jit[]; + #ifdef __WATCOMC__ + #pragma aux amx_opcodelist_jit "_*" + #endif + #endif + + assert(amx!=NULL); + #if defined ASM32 || defined JIT + /* HACK: return label table (for amx_BrowseRelocate) if amx structure + * is not passed. + */ + if ((amx->flags & AMX_FLAG_BROWSE)==AMX_FLAG_BROWSE) { + assert(sizeof(cell)==sizeof(void *)); + assert(retval!=NULL); + #if defined ASM32 && defined JIT + if ((amx->flags & AMX_FLAG_JITC)!=0) + *retval=(cell)amx_opcodelist_jit; + else + *retval=(cell)amx_opcodelist; + #elif defined ASM32 + *retval=(cell)amx_opcodelist; + #else + *retval=(cell)amx_opcodelist_jit; + #endif + return 0; + } /* if */ + #endif + + if (amx->callback==NULL) + return AMX_ERR_CALLBACK; + if ((amx->flags & AMX_FLAG_NTVREG)==0) + return AMX_ERR_NOTFOUND; + if ((amx->flags & AMX_FLAG_RELOC)==0) + return AMX_ERR_INIT; + assert((amx->flags & AMX_FLAG_BROWSE)==0); + + /* set up the registers */ + hdr=(AMX_HEADER *)amx->base; + assert(hdr->magic==AMX_MAGIC); + codesize=(ucell)(hdr->dat-hdr->cod); + code=amx->base+(int)hdr->cod; + data=(amx->data!=NULL) ? amx->data : amx->base+(int)hdr->dat; + hea=amx->hea; + stk=amx->stk; + reset_stk=stk; + reset_hea=hea; + frm=alt=pri=0; /* silence up compiler */ + + /* get the start address */ + if (index==AMX_EXEC_MAIN) { + if (hdr->cip<0) + return AMX_ERR_INDEX; + cip=(cell *)(code + (int)hdr->cip); + } else if (index==AMX_EXEC_CONT) { + /* all registers: pri, alt, frm, cip, hea, stk, reset_stk, reset_hea */ + frm=amx->frm; + stk=amx->stk; + hea=amx->hea; + pri=amx->pri; + alt=amx->alt; + reset_stk=amx->reset_stk; + reset_hea=amx->reset_hea; + cip=(cell *)(code + (int)amx->cip); + } else if (index<0) { + return AMX_ERR_INDEX; + } else { + if (index>=(cell)NUMENTRIES(hdr,publics,natives)) + return AMX_ERR_INDEX; + func=GETENTRY(hdr,publics,index); + cip=(cell *)(code + (int)func->address); + } /* if */ + /* check values just copied */ + CHKSTACK(); + CHKHEAP(); + assert(check_endian()); + + /* sanity checks */ + assert(OP_PUSH_PRI==36); + assert(OP_PROC==46); + assert(OP_SHL==65); + assert(OP_SMUL==72); + assert(OP_EQ==95); + assert(OP_INC_PRI==107); + assert(OP_MOVS==117); + assert(OP_SYMBOL==126); + #if PAWN_CELL_SIZE==16 + assert(sizeof(cell)==2); + #elif PAWN_CELL_SIZE==32 + assert(sizeof(cell)==4); + #elif PAWN_CELL_SIZE==64 + assert(sizeof(cell)==8); + #else + #error Unsupported cell size + #endif + + if (index!=AMX_EXEC_CONT) { + reset_stk+=amx->paramcount*sizeof(cell); + PUSH(amx->paramcount*sizeof(cell)); + amx->paramcount=0; /* push the parameter count to the stack & reset */ + #if defined ASM32 || defined JIT + PUSH(RELOC_VALUE(code,0));/* relocated zero return address */ + #else + PUSH(0); /* zero return address */ + #endif + } /* if */ + /* check stack/heap before starting to run */ + CHKMARGIN(); + + /* start running */ +#if defined ASM32 || defined JIT + /* either the assembler abstract machine or the JIT; both by Marc Peter */ + + parms[0] = pri; + parms[1] = alt; + parms[2] = (cell)cip; + parms[3] = (cell)data; + parms[4] = stk; + parms[5] = frm; + parms[6] = (cell)amx; + parms[7] = (cell)code; + parms[8] = (cell)codesize; + + #if defined ASM32 && defined JIT + if ((amx->flags & AMX_FLAG_JITC)!=0) + i = amx_exec_jit(parms,retval,amx->stp,hea); + else + i = amx_exec_asm(parms,retval,amx->stp,hea); + #elif defined ASM32 + i = amx_exec_asm(parms,retval,amx->stp,hea); + #else + i = amx_exec_jit(parms,retval,amx->stp,hea); + #endif + if (i == AMX_ERR_SLEEP) { + amx->reset_stk=reset_stk; + amx->reset_hea=reset_hea; + } else { + /* remove parameters from the stack; do this the "hard" way, because + * the assembler version has no internal knowledge of the local + * variables, so any "clean" way would be a kludge anyway. + */ + amx->stk=reset_stk; + amx->hea=reset_hea; + } /* if */ + return i; + +#else + + for ( ;; ) { + op=(OPCODE) *cip++; + switch (op) { + case OP_LOAD_PRI: + GETPARAM(offs); + pri= * (cell *)(data+(int)offs); + break; + case OP_LOAD_ALT: + GETPARAM(offs); + alt= * (cell *)(data+(int)offs); + break; + case OP_LOAD_S_PRI: + GETPARAM(offs); + pri= * (cell *)(data+(int)frm+(int)offs); + break; + case OP_LOAD_S_ALT: + GETPARAM(offs); + alt= * (cell *)(data+(int)frm+(int)offs); + break; + case OP_LREF_PRI: + GETPARAM(offs); + offs= * (cell *)(data+(int)offs); + pri= * (cell *)(data+(int)offs); + break; + case OP_LREF_ALT: + GETPARAM(offs); + offs= * (cell *)(data+(int)offs); + alt= * (cell *)(data+(int)offs); + break; + case OP_LREF_S_PRI: + GETPARAM(offs); + offs= * (cell *)(data+(int)frm+(int)offs); + pri= * (cell *)(data+(int)offs); + break; + case OP_LREF_S_ALT: + GETPARAM(offs); + offs= * (cell *)(data+(int)frm+(int)offs); + alt= * (cell *)(data+(int)offs); + break; + case OP_LOAD_I: + /* verify address */ + if (pri>=hea && pri=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + pri= * (cell *)(data+(int)pri); + break; + case OP_LODB_I: + GETPARAM(offs); + /* verify address */ + if (pri>=hea && pri=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + switch (offs) { + case 1: + pri= * (data+(int)pri); + break; + case 2: + pri= * (uint16_t *)(data+(int)pri); + break; + case 4: + pri= * (uint32_t *)(data+(int)pri); + break; + } /* switch */ + break; + case OP_CONST_PRI: + GETPARAM(pri); + break; + case OP_CONST_ALT: + GETPARAM(alt); + break; + case OP_ADDR_PRI: + GETPARAM(pri); + pri+=frm; + break; + case OP_ADDR_ALT: + GETPARAM(alt); + alt+=frm; + break; + case OP_STOR_PRI: + GETPARAM(offs); + *(cell *)(data+(int)offs)=pri; + break; + case OP_STOR_ALT: + GETPARAM(offs); + *(cell *)(data+(int)offs)=alt; + break; + case OP_STOR_S_PRI: + GETPARAM(offs); + *(cell *)(data+(int)frm+(int)offs)=pri; + break; + case OP_STOR_S_ALT: + GETPARAM(offs); + *(cell *)(data+(int)frm+(int)offs)=alt; + break; + case OP_SREF_PRI: + GETPARAM(offs); + offs= * (cell *)(data+(int)offs); + *(cell *)(data+(int)offs)=pri; + break; + case OP_SREF_ALT: + GETPARAM(offs); + offs= * (cell *)(data+(int)offs); + *(cell *)(data+(int)offs)=alt; + break; + case OP_SREF_S_PRI: + GETPARAM(offs); + offs= * (cell *)(data+(int)frm+(int)offs); + *(cell *)(data+(int)offs)=pri; + break; + case OP_SREF_S_ALT: + GETPARAM(offs); + offs= * (cell *)(data+(int)frm+(int)offs); + *(cell *)(data+(int)offs)=alt; + break; + case OP_STOR_I: + /* verify address */ + if (alt>=hea && alt=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + *(cell *)(data+(int)alt)=pri; + break; + case OP_STRB_I: + GETPARAM(offs); + /* verify address */ + if (alt>=hea && alt=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + switch (offs) { + case 1: + *(data+(int)alt)=(unsigned char)pri; + break; + case 2: + *(uint16_t *)(data+(int)alt)=(uint16_t)pri; + break; + case 4: + *(uint32_t *)(data+(int)alt)=(uint32_t)pri; + break; + } /* switch */ + break; + case OP_LIDX: + offs=pri*sizeof(cell)+alt; + /* verify address */ + if (offs>=hea && offs=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + pri= * (cell *)(data+(int)offs); + break; + case OP_LIDX_B: + GETPARAM(offs); + offs=(pri << (int)offs)+alt; + /* verify address */ + if (offs>=hea && offs=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + pri= * (cell *)(data+(int)offs); + break; + case OP_IDXADDR: + pri=pri*sizeof(cell)+alt; + break; + case OP_IDXADDR_B: + GETPARAM(offs); + pri=(pri << (int)offs)+alt; + break; + case OP_ALIGN_PRI: + GETPARAM(offs); + #if BYTE_ORDER==LITTLE_ENDIAN + if ((size_t)offscod; + break; + case 1: + pri=hdr->dat; + break; + case 2: + pri=hea; + break; + case 3: + pri=amx->stp; + break; + case 4: + pri=stk; + break; + case 5: + pri=frm; + break; + case 6: + pri=(cell)((unsigned char *)cip - code); + break; + } /* switch */ + break; + case OP_SCTRL: + GETPARAM(offs); + switch (offs) { + case 0: + case 1: + case 3: + /* cannot change these parameters */ + break; + case 2: + hea=pri; + break; + case 4: + stk=pri; + break; + case 5: + frm=pri; + break; + case 6: + cip=(cell *)(code + (int)pri); + break; + } /* switch */ + break; + case OP_MOVE_PRI: + pri=alt; + break; + case OP_MOVE_ALT: + alt=pri; + break; + case OP_XCHG: + offs=pri; /* offs is a temporary variable */ + pri=alt; + alt=offs; + break; + case OP_PUSH_PRI: + PUSH(pri); + break; + case OP_PUSH_ALT: + PUSH(alt); + break; + case OP_PUSH_C: + GETPARAM(offs); + PUSH(offs); + break; + case OP_PUSH_R: + GETPARAM(offs); + while (offs--) + PUSH(pri); + break; + case OP_PUSH: + GETPARAM(offs); + PUSH(* (cell *)(data+(int)offs)); + break; + case OP_PUSH_S: + GETPARAM(offs); + PUSH(* (cell *)(data+(int)frm+(int)offs)); + break; + case OP_POP_PRI: + POP(pri); + break; + case OP_POP_ALT: + POP(alt); + break; + case OP_STACK: + GETPARAM(offs); + alt=stk; + stk+=offs; + CHKMARGIN(); + CHKSTACK(); + break; + case OP_HEAP: + GETPARAM(offs); + alt=hea; + hea+=offs; + CHKMARGIN(); + CHKHEAP(); + break; + case OP_PROC: + PUSH(frm); + frm=stk; + CHKMARGIN(); + break; + case OP_RET: + POP(frm); + POP(offs); + /* verify the return address */ + if ((ucell)offs>=codesize) + ABORT(amx,AMX_ERR_MEMACCESS); + cip=(cell *)(code+(int)offs); + break; + case OP_RETN: + POP(frm); + POP(offs); + /* verify the return address */ + if ((ucell)offs>=codesize) + ABORT(amx,AMX_ERR_MEMACCESS); + cip=(cell *)(code+(int)offs); + stk+= *(cell *)(data+(int)stk) + sizeof(cell); /* remove parameters from the stack */ + amx->stk=stk; + break; + case OP_CALL: + PUSH(((unsigned char *)cip-code)+sizeof(cell));/* skip address */ + cip=JUMPABS(code, cip); /* jump to the address */ + break; + case OP_CALL_PRI: + PUSH((unsigned char *)cip-code); + cip=(cell *)(code+(int)pri); + break; + case OP_JUMP: + /* since the GETPARAM() macro modifies cip, you cannot + * do GETPARAM(cip) directly */ + cip=JUMPABS(code, cip); + break; + case OP_JREL: + offs=*cip; + cip=(cell *)((unsigned char *)cip + (int)offs + sizeof(cell)); + break; + case OP_JZER: + if (pri==0) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + break; + case OP_JNZ: + if (pri!=0) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + break; + case OP_JEQ: + if (pri==alt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + break; + case OP_JNEQ: + if (pri!=alt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + break; + case OP_JLESS: + if ((ucell)pri < (ucell)alt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + break; + case OP_JLEQ: + if ((ucell)pri <= (ucell)alt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + break; + case OP_JGRTR: + if ((ucell)pri > (ucell)alt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + break; + case OP_JGEQ: + if ((ucell)pri >= (ucell)alt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + break; + case OP_JSLESS: + if (prialt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + break; + case OP_JSGEQ: + if (pri>=alt) + cip=JUMPABS(code, cip); + else + cip=(cell *)((unsigned char *)cip+sizeof(cell)); + break; + case OP_SHL: + pri<<=alt; + break; + case OP_SHR: + pri=(ucell)pri >> (int)alt; + break; + case OP_SSHR: + pri>>=alt; + break; + case OP_SHL_C_PRI: + GETPARAM(offs); + pri<<=offs; + break; + case OP_SHL_C_ALT: + GETPARAM(offs); + alt<<=offs; + break; + case OP_SHR_C_PRI: + GETPARAM(offs); + pri=(ucell)pri >> (int)offs; + break; + case OP_SHR_C_ALT: + GETPARAM(offs); + alt=(ucell)alt >> (int)offs; + break; + case OP_SMUL: + pri*=alt; + break; + case OP_SDIV: + if (alt==0) + ABORT(amx,AMX_ERR_DIVIDE); + /* divide must always round down; this is a bit + * involved to do in a machine-independent way. + */ + offs=(pri % alt + alt) % alt; /* true modulus */ + pri=(pri - offs) / alt; /* division result */ + alt=offs; + break; + case OP_SDIV_ALT: + if (pri==0) + ABORT(amx,AMX_ERR_DIVIDE); + /* divide must always round down; this is a bit + * involved to do in a machine-independent way. + */ + offs=(alt % pri + pri) % pri; /* true modulus */ + pri=(alt - offs) / pri; /* division result */ + alt=offs; + break; + case OP_UMUL: + pri=(ucell)pri * (ucell)alt; + break; + case OP_UDIV: + if (alt==0) + ABORT(amx,AMX_ERR_DIVIDE); + offs=(ucell)pri % (ucell)alt; /* temporary storage */ + pri=(ucell)pri / (ucell)alt; + alt=offs; + break; + case OP_UDIV_ALT: + if (pri==0) + ABORT(amx,AMX_ERR_DIVIDE); + offs=(ucell)alt % (ucell)pri; /* temporary storage */ + pri=(ucell)alt / (ucell)pri; + alt=offs; + break; + case OP_ADD: + pri+=alt; + break; + case OP_SUB: + pri-=alt; + break; + case OP_SUB_ALT: + pri=alt-pri; + break; + case OP_AND: + pri&=alt; + break; + case OP_OR: + pri|=alt; + break; + case OP_XOR: + pri^=alt; + break; + case OP_NOT: + pri=!pri; + break; + case OP_NEG: + pri=-pri; + break; + case OP_INVERT: + pri=~pri; + break; + case OP_ADD_C: + GETPARAM(offs); + pri+=offs; + break; + case OP_SMUL_C: + GETPARAM(offs); + pri*=offs; + break; + case OP_ZERO_PRI: + pri=0; + break; + case OP_ZERO_ALT: + alt=0; + break; + case OP_ZERO: + GETPARAM(offs); + *(cell *)(data+(int)offs)=0; + break; + case OP_ZERO_S: + GETPARAM(offs); + *(cell *)(data+(int)frm+(int)offs)=0; + break; + case OP_SIGN_PRI: + if ((pri & 0xff)>=0x80) + pri|= ~ (ucell)0xff; + break; + case OP_SIGN_ALT: + if ((alt & 0xff)>=0x80) + alt|= ~ (ucell)0xff; + break; + case OP_EQ: + pri= pri==alt ? 1 : 0; + break; + case OP_NEQ: + pri= pri!=alt ? 1 : 0; + break; + case OP_LESS: + pri= (ucell)pri < (ucell)alt ? 1 : 0; + break; + case OP_LEQ: + pri= (ucell)pri <= (ucell)alt ? 1 : 0; + break; + case OP_GRTR: + pri= (ucell)pri > (ucell)alt ? 1 : 0; + break; + case OP_GEQ: + pri= (ucell)pri >= (ucell)alt ? 1 : 0; + break; + case OP_SLESS: + pri= prialt ? 1 : 0; + break; + case OP_SGEQ: + pri= pri>=alt ? 1 : 0; + break; + case OP_EQ_C_PRI: + GETPARAM(offs); + pri= pri==offs ? 1 : 0; + break; + case OP_EQ_C_ALT: + GETPARAM(offs); + pri= alt==offs ? 1 : 0; + break; + case OP_INC_PRI: + pri++; + break; + case OP_INC_ALT: + alt++; + break; + case OP_INC: + GETPARAM(offs); + *(cell *)(data+(int)offs) += 1; + break; + case OP_INC_S: + GETPARAM(offs); + *(cell *)(data+(int)frm+(int)offs) += 1; + break; + case OP_INC_I: + *(cell *)(data+(int)pri) += 1; + break; + case OP_DEC_PRI: + pri--; + break; + case OP_DEC_ALT: + alt--; + break; + case OP_DEC: + GETPARAM(offs); + *(cell *)(data+(int)offs) -= 1; + break; + case OP_DEC_S: + GETPARAM(offs); + *(cell *)(data+(int)frm+(int)offs) -= 1; + break; + case OP_DEC_I: + *(cell *)(data+(int)pri) -= 1; + break; + case OP_MOVS: + GETPARAM(offs); + /* verify top & bottom memory addresses, for both source and destination + * addresses + */ + if (pri>=hea && pri=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + if ((pri+offs)>hea && (pri+offs)(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + if (alt>=hea && alt=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + if ((alt+offs)>hea && (alt+offs)(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + memcpy(data+(int)alt, data+(int)pri, (int)offs); + break; + case OP_CMPS: + GETPARAM(offs); + /* verify top & bottom memory addresses, for both source and destination + * addresses + */ + if (pri>=hea && pri=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + if ((pri+offs)>hea && (pri+offs)(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + if (alt>=hea && alt=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + if ((alt+offs)>hea && (alt+offs)(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + pri=memcmp(data+(int)alt, data+(int)pri, (int)offs); + break; + case OP_FILL: + GETPARAM(offs); + /* verify top & bottom memory addresses (destination only) */ + if (alt>=hea && alt=(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + if ((alt+offs)>hea && (alt+offs)(ucell)amx->stp) + ABORT(amx,AMX_ERR_MEMACCESS); + for (i=(int)alt; (size_t)offs>=sizeof(cell); i+=sizeof(cell), offs-=sizeof(cell)) + *(cell *)(data+i) = pri; + break; + case OP_HALT: + GETPARAM(offs); + if (retval!=NULL) + *retval=pri; + /* store complete status (stk and hea are already set in the ABORT macro) */ + amx->frm=frm; + amx->pri=pri; + amx->alt=alt; + amx->cip=(cell)((unsigned char*)cip-code); + if (offs==AMX_ERR_SLEEP) { + amx->reset_stk=reset_stk; + amx->reset_hea=reset_hea; + return (int)offs; + } /* if */ + ABORT(amx,(int)offs); + case OP_BOUNDS: + GETPARAM(offs); + if ((ucell)pri>(ucell)offs) + ABORT(amx,AMX_ERR_BOUNDS); + break; + case OP_SYSREQ_PRI: + /* save a few registers */ + amx->cip=(cell)((unsigned char *)cip-code); + amx->hea=hea; + amx->frm=frm; + amx->stk=stk; + num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk)); + if (num!=AMX_ERR_NONE) { + if (num==AMX_ERR_SLEEP) { + amx->pri=pri; + amx->alt=alt; + amx->reset_stk=reset_stk; + amx->reset_hea=reset_hea; + return num; + } /* if */ + ABORT(amx,num); + } /* if */ + break; + case OP_SYSREQ_C: + GETPARAM(offs); + /* save a few registers */ + amx->cip=(cell)((unsigned char *)cip-code); + amx->hea=hea; + amx->frm=frm; + amx->stk=stk; + num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk)); + if (num!=AMX_ERR_NONE) { + if (num==AMX_ERR_SLEEP) { + amx->pri=pri; + amx->alt=alt; + amx->reset_stk=reset_stk; + amx->reset_hea=reset_hea; + return num; + } /* if */ + ABORT(amx,num); + } /* if */ + break; + case OP_SYSREQ_D: + GETPARAM(offs); + /* save a few registers */ + amx->cip=(cell)((unsigned char *)cip-code); + amx->hea=hea; + amx->frm=frm; + amx->stk=stk; + pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk)); + if (amx->error!=AMX_ERR_NONE) { + if (amx->error==AMX_ERR_SLEEP) { + amx->pri=pri; + amx->alt=alt; + amx->reset_stk=reset_stk; + amx->reset_hea=reset_hea; + return num; + } /* if */ + ABORT(amx,amx->error); + } /* if */ + break; + case OP_LINE: + SKIPPARAM(2); + break; + case OP_SYMBOL: + GETPARAM(offs); + cip=(cell *)((unsigned char *)cip + (int)offs); + break; + case OP_SRANGE: + SKIPPARAM(2); + break; + case OP_SYMTAG: + SKIPPARAM(1); + break; + case OP_JUMP_PRI: + cip=(cell *)(code+(int)pri); + break; + case OP_SWITCH: { + cell *cptr; + + cptr=JUMPABS(code,cip)+1; /* +1, to skip the "casetbl" opcode */ + cip=JUMPABS(code,cptr+1); /* preset to "none-matched" case */ + num=(int)*cptr; /* number of records in the case table */ + for (cptr+=2; num>0 && *cptr!=pri; num--,cptr+=2) + /* nothing */; + if (num>0) + cip=JUMPABS(code,cptr+1); /* case found */ + break; + } /* case */ + case OP_SWAP_PRI: + offs=*(cell *)(data+(int)stk); + *(cell *)(data+(int)stk)=pri; + pri=offs; + break; + case OP_SWAP_ALT: + offs=*(cell *)(data+(int)stk); + *(cell *)(data+(int)stk)=alt; + alt=offs; + break; + case OP_PUSHADDR: + GETPARAM(offs); + PUSH(frm+offs); + break; + case OP_NOP: + break; + case OP_BREAK: + assert((amx->flags & AMX_FLAG_BROWSE)==0); + if (amx->debug!=NULL) { + /* store status */ + amx->frm=frm; + amx->stk=stk; + amx->hea=hea; + amx->cip=(cell)((unsigned char*)cip-code); + num=amx->debug(amx); + if (num!=AMX_ERR_NONE) { + if (num==AMX_ERR_SLEEP) { + amx->pri=pri; + amx->alt=alt; + amx->reset_stk=reset_stk; + amx->reset_hea=reset_hea; + return num; + } /* if */ + ABORT(amx,num); + } /* if */ + } /* if */ + break; + default: + /* case OP_FILE: should not occur during execution + * case OP_CASETBL: should not occur during execution + */ + assert(0); + ABORT(amx,AMX_ERR_INVINSTR); + } /* switch */ + } /* for */ +#endif +} + +#endif /* __GNUC__ */ + +#endif /* AMX_EXEC || AMX_INIT */ + +#if defined AMX_SETCALLBACK +int AMXAPI amx_SetCallback(AMX *amx,AMX_CALLBACK callback) +{ + assert(amx!=NULL); + assert(callback!=NULL); + amx->callback=callback; + return AMX_ERR_NONE; +} +#endif /* AMX_SETCALLBACK */ + +#if defined AMX_SETDEBUGHOOK +int AMXAPI amx_SetDebugHook(AMX *amx,AMX_DEBUG debug) +{ + assert(amx!=NULL); + amx->debug=debug; + return AMX_ERR_NONE; +} +#endif /* AMX_SETDEBUGHOOK */ + +#if defined AMX_RAISEERROR +int AMXAPI amx_RaiseError(AMX *amx, int error) +{ + assert(error>0); + amx->error=error; + return AMX_ERR_NONE; +} +#endif /* AMX_RAISEERROR */ + +#if defined AMX_GETADDR +int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr) +{ + AMX_HEADER *hdr; + unsigned char *data; + + assert(amx!=NULL); + hdr=(AMX_HEADER *)amx->base; + assert(hdr!=NULL); + assert(hdr->magic==AMX_MAGIC); + data=(amx->data!=NULL) ? amx->data : amx->base+(int)hdr->dat; + + assert(phys_addr!=NULL); + if (amx_addr>=amx->hea && amx_addrstk || amx_addr<0 || amx_addr>=amx->stp) { + *phys_addr=NULL; + return AMX_ERR_MEMACCESS; + } /* if */ + + *phys_addr=(cell *)(data + (int)amx_addr); + return AMX_ERR_NONE; +} +#endif /* AMX_GETADDR */ + +#if defined AMX_ALLOT || defined AMX_EXEC +int AMXAPI amx_Allot(AMX *amx,int cells,cell *amx_addr,cell **phys_addr) +{ + AMX_HEADER *hdr; + unsigned char *data; + + assert(amx!=NULL); + hdr=(AMX_HEADER *)amx->base; + assert(hdr!=NULL); + assert(hdr->magic==AMX_MAGIC); + data=(amx->data!=NULL) ? amx->data : amx->base+(int)hdr->dat; + + if (amx->stk - amx->hea - cells*sizeof(cell) < STKMARGIN) + return AMX_ERR_MEMORY; + assert(amx_addr!=NULL); + assert(phys_addr!=NULL); + *amx_addr=amx->hea; + *phys_addr=(cell *)(data + (int)amx->hea); + amx->hea += cells*sizeof(cell); + return AMX_ERR_NONE; +} + +int AMXAPI amx_Release(AMX *amx,cell amx_addr) +{ + if (amx->hea > amx_addr) + amx->hea=amx_addr; + return AMX_ERR_NONE; +} +#endif /* AMX_ALLOT */ + +#if defined AMX_XXXSTRING || defined AMX_UTF8XXX + +#define CHARBITS (8*sizeof(char)) +#if PAWN_CELL_SIZE==16 + #define CHARMASK (0xffffu << 8*(2-sizeof(char))) +#elif PAWN_CELL_SIZE==32 + #define CHARMASK (0xffffffffuL << 8*(4-sizeof(char))) +#elif PAWN_CELL_SIZE==64 + #define CHARMASK (0xffffffffffffffffuLL << 8*(8-sizeof(char))) +#else + #error Unsupported cell size +#endif + +int AMXAPI amx_StrLen(const cell *cstr, int *length) +{ + int len; + #if BYTE_ORDER==LITTLE_ENDIAN + cell c; + #endif + + assert(length!=NULL); + if (cstr==NULL) { + *length=0; + return AMX_ERR_PARAMS; + } /* if */ + + if ((ucell)*cstr>UNPACKEDMAX) { + /* packed string */ + assert(sizeof(char)==1); + len=strlen((char *)cstr); /* find '\0' */ + assert(check_endian()); + #if BYTE_ORDER==LITTLE_ENDIAN + /* on Little Endian machines, toggle the last bytes */ + c=cstr[len/sizeof(cell)]; /* get last cell */ + len=len - len % sizeof(cell); /* len = multiple of "cell" bytes */ + while ((c & CHARMASK)!=0) { + len++; + c <<= 8*sizeof(char); + } /* if */ + #endif + } else { + for (len=0; cstr[len]!=0; len++) + /* nothing */; + } /* if */ + *length = len; + return AMX_ERR_NONE; +} +#endif + +#if defined AMX_XXXSTRING || defined AMX_EXEC +int AMXAPI amx_SetString(cell *dest,const char *source,int pack,int use_wchar,size_t size) +{ /* the memory blocks should not overlap */ + int len, i; + + assert(UNLIMITED>0); + #if defined AMX_ANSIONLY + (void)use_wchar; + len=strlen(source); + #else + len= use_wchar ? wcslen((const wchar_t*)source) : strlen(source); + #endif + if (pack) { + /* create a packed string */ + if (size=size*sizeof(cell)) + len=size*sizeof(cell)-1; + dest[len/sizeof(cell)]=0; /* clear last bytes of last (semi-filled) cell*/ + #if defined AMX_ANSIONLY + memcpy(dest,source,len); + #else + if (use_wchar) { + for (i=0; i=0) + swapcell((ucell *)&dest[len--]); + #endif + + } else { + /* create an unpacked string */ + if (size=size) + len=size-1; + #if defined AMX_ANSIONLY + for (i=0; iUNPACKEDMAX) { + /* source string is packed */ + cell c = 0; /* to avoid a compiler warning */ + int i=sizeof(cell)-1; + while ((size_t)len> i*CHARBITS); + #else + if (use_wchar) + ((wchar_t*)dest)[len++]=(char)(c >> i*CHARBITS); + else + dest[len++]=(char)(c >> i*CHARBITS); + #endif + if (dest[len-1]=='\0') + break; /* terminating zero character found */ + i=(i+sizeof(cell)-1) % sizeof(cell); + } /* for */ + } else { + /* source string is unpacked */ + #if defined AMX_ANSIONLY + while (*source!=0 && (size_t)len=size) + len=size-1; + if (len>=0) + dest[len]='\0'; /* store terminator */ + return AMX_ERR_NONE; +} +#endif /* AMX_XXXSTRING */ + +#if defined AMX_UTF8XXX + #if defined __BORLANDC__ + #pragma warn -amb -8000 /* ambiguous operators need parentheses */ + #endif +/* amx_UTF8Get() + * Extract a single UTF-8 encoded character from a string and return a pointer + * to the character just behind that UTF-8 character. The parameters "endptr" + * and "value" may be NULL. + * If the code is not valid UTF-8, "endptr" has the value of the input + * parameter "string" and "value" is zero. + */ +int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value) +{ +static const char utf8_count[16]={ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4 }; +static const long utf8_lowmark[5] = { 0x80, 0x800, 0x10000L, 0x200000L, 0x4000000L }; + unsigned char c; + cell result; + int followup; + + assert(string!=NULL); + if (value!=NULL) /* preset, in case of an error */ + *value=0; + if (endptr!=NULL) + *endptr=string; + + c = *(const unsigned char*)string++; + if (c<0x80) { + /* ASCII */ + result=c; + } else { + if (c<0xc0 || c>=0xfe) + return AMX_ERR_PARAMS; /* invalid or "follower" code, quit with error */ + /* At this point we know that the two top bits of c are ones. The two + * bottom bits are always part of the code. We only need to consider + * the 4 remaining bits; i.e., a 16-byte table. This is "utf8_count[]". + * (Actually the utf8_count[] table records the number of follow-up + * bytes minus 1. This is just for convenience.) + */ + assert((c & 0xc0)==0xc0); + followup=(int)utf8_count[(c >> 2) & 0x0f]; + /* The mask depends on the code length; this is just a very simple + * relation. + */ + #define utf8_mask (0x1f >> followup) + result= c & utf8_mask; + /* Collect the follow-up codes using a drop-through switch statement; + * this avoids a loop. In each case, verify the two leading bits. + */ + assert(followup>=0 && followup<=4); + switch (followup) { + case 4: + if (((c=*string++) & 0xc0) != 0x80) goto error; + result = (result << 6) | c & 0x3f; + case 3: + if (((c=*string++) & 0xc0) != 0x80) goto error; + result = (result << 6) | c & 0x3f; + case 2: + if (((c=*string++) & 0xc0) != 0x80) goto error; + result = (result << 6) | c & 0x3f; + case 1: + if (((c=*string++) & 0xc0) != 0x80) goto error; + result = (result << 6) | c & 0x3f; + case 0: + if (((c=*string++) & 0xc0) != 0x80) goto error; + result = (result << 6) | c & 0x3f; + } /* switch */ + /* Do additional checks: shortest encoding & reserved positions. The + * lowmark limits also depends on the code length; it can be read from + * a table with 5 elements. This is "utf8_lowmark[]". + */ + if (result=0xd800 && result<=0xdfff || result==0xfffe || result==0xffff) + goto error; + } /* if */ + + if (value!=NULL) + *value=result; + if (endptr!=NULL) + *endptr=string; + + return AMX_ERR_NONE; + +error: + return AMX_ERR_PARAMS; +} + +/* amx_UTF8Put() + * Encode a single character into a byte string. The character may result in + * a string of up to 6 bytes. The function returns an error code if "maxchars" + * is lower than the required number of characters; in this case nothing is + * stored. + * The function does not zero-terminate the string. + */ +int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value) +{ + assert(string!=NULL); + if (endptr!=NULL) /* preset, in case of an error */ + *endptr=string; + + if (value<0x80) { + /* 0xxxxxxx */ + if (maxchars < 1) goto error; + *string++ = (char)value; + } else if (value<0x800) { + /* 110xxxxx 10xxxxxx */ + if (maxchars < 2) goto error; + *string++ = (char)((value>>6) & 0x1f | 0xc0); + *string++ = (char)(value & 0x3f | 0x80); + } else if (value<0x10000) { + /* 1110xxxx 10xxxxxx 10xxxxxx (16 bits, BMP plane) */ + if (maxchars < 3) goto error; + if (value>=0xd800 && value<=0xdfff || value==0xfffe || value==0xffff) + goto error; /* surrogate pairs and invalid characters */ + *string++ = (char)((value>>12) & 0x0f | 0xe0); + *string++ = (char)((value>>6) & 0x3f | 0x80); + *string++ = (char)(value & 0x3f | 0x80); + } else if (value<0x200000) { + /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (maxchars < 4) goto error; + *string++ = (char)((value>>18) & 0x07 | 0xf0); + *string++ = (char)((value>>12) & 0x3f | 0x80); + *string++ = (char)((value>>6) & 0x3f | 0x80); + *string++ = (char)(value & 0x3f | 0x80); + } else if (value<0x4000000) { + /* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (maxchars < 5) goto error; + *string++ = (char)((value>>24) & 0x03 | 0xf8); + *string++ = (char)((value>>18) & 0x3f | 0x80); + *string++ = (char)((value>>12) & 0x3f | 0x80); + *string++ = (char)((value>>6) & 0x3f | 0x80); + *string++ = (char)(value & 0x3f | 0x80); + } else { + /* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx (31 bits) */ + if (maxchars < 6) goto error; + *string++ = (char)((value>>30) & 0x01 | 0xfc); + *string++ = (char)((value>>24) & 0x3f | 0x80); + *string++ = (char)((value>>18) & 0x3f | 0x80); + *string++ = (char)((value>>12) & 0x3f | 0x80); + *string++ = (char)((value>>6) & 0x3f | 0x80); + *string++ = (char)(value & 0x3f | 0x80); + } /* if */ + + if (endptr!=NULL) + *endptr=string; + return AMX_ERR_NONE; + +error: + return AMX_ERR_PARAMS; +} + +/* amx_UTF8Check() + * Run through a zero-terminated string and check the validity of the UTF-8 + * encoding. The function returns an error code, it is AMX_ERR_NONE if the + * string is valid UTF-8 (or valid ASCII for that matter). + */ +int AMXAPI amx_UTF8Check(const char *string, int *length) +{ + int err=AMX_ERR_NONE; + int len=0; + while (err==AMX_ERR_NONE && *string!='\0') { + err=amx_UTF8Get(string,&string,NULL); + len++; + } /* while */ + if (length!=NULL) + *length=len; + return err; +} + +/* amx_UTF8Len() + * Run through a wide string and return how many 8-bit characters are needed to + * store the string in UTF-8 format. The returned cound excludes the terminating + * zero byte. The function returns an error code. + */ +int AMXAPI amx_UTF8Len(const cell *cstr, int *length) +{ + int err; + + assert(length!=NULL); + err=amx_StrLen(cstr, length); + if (err==AMX_ERR_NONE && (ucell)*cstr<=UNPACKEDMAX) { + char buffer[10]; /* maximum UTF-8 code is 6 characters */ + char *endptr; + int len=*length, count=0; + while (len-->0) { + amx_UTF8Put(buffer, &endptr, sizeof buffer, *cstr++); + count+=(int)(endptr-buffer); + } /* while */ + *length=count; + } /* while */ + return err; +} +#endif /* AMX_UTF8XXX */ diff --git a/compiler/amxxpc/amx.h b/compiler/amxxpc/amx.h new file mode 100755 index 00000000..cf194750 --- /dev/null +++ b/compiler/amxxpc/amx.h @@ -0,0 +1,439 @@ +/* Pawn Abstract Machine (for the Pawn language) + * + * 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 + * the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in + * a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * Version: $Id$ + */ + +#if defined FREEBSD && !defined __FreeBSD__ + #define __FreeBSD__ +#endif +#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ + #include +#endif + +#ifndef AMX_H_INCLUDED +#define AMX_H_INCLUDED + +#if defined HAVE_STDINT_H + #include +#else + #if defined __LCC__ || defined __DMC__ || defined LINUX + #if defined HAVE_INTTYPES_H + #include + #else + #include + #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 __MACH__ + #include + typedef unsigned short int uint16_t; + typedef unsigned long int uint32_t; + #elif defined __FreeBSD__ + #include + #else + typedef short int int16_t; + typedef unsigned short int uint16_t; + #if defined SN_TARGET_PS2 + typedef int int32_t; + typedef unsigned int uint32_t; + #else + typedef long int int32_t; + typedef unsigned long int uint32_t; + #endif + #if defined __WIN32__ || defined _WIN32 || defined WIN32 + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; + #define HAVE_I64 + #elif defined __GNUC__ + typedef long long int64_t; + typedef unsigned long long uint64_t; + #define HAVE_I64 + #endif + #endif + #endif + #define HAVE_STDINT_H +#endif +#if defined _LP64 || defined WIN64 || defined _WIN64 + #if !defined __64BIT__ + #define __64BIT__ + #endif +#endif + +#if HAVE_ALLOCA_H + #include +#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 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 +#endif +/* calling convention for all interface functions and callback functions */ +#if !defined AMXAPI + #if defined STDECL + #define AMXAPI __stdcall + #elif defined CDECL + #define AMXAPI __cdecl + #elif defined GCC_HASCLASSVISIBILITY + #define AMXAPI __attribute__ ((visibility("default"))) + #else + #define AMXAPI + #endif +#endif +#if !defined AMXEXPORT + #define AMXEXPORT +#endif + +/* File format version Required AMX version + * 0 (original version) 0 + * 1 (opcodes JUMP.pri, SWITCH and CASETBL) 1 + * 2 (compressed files) 2 + * 3 (public variables) 2 + * 4 (opcodes SWAP.pri/alt and PUSHADDR) 4 + * 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 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 8 /* minimum AMX version needed to support the current file format */ + +#if !defined PAWN_CELL_SIZE + #define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */ +#endif +#if PAWN_CELL_SIZE==16 + typedef uint16_t ucell; + typedef int16_t cell; +#elif PAWN_CELL_SIZE==32 + typedef uint32_t ucell; + typedef int32_t cell; +#elif PAWN_CELL_SIZE==64 + typedef uint64_t ucell; + typedef int64_t cell; +#else + #error Unsupported cell size (PAWN_CELL_SIZE) +#endif + +#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); +#if !defined _FAR + #define _FAR +#endif + +#if defined _MSC_VER + #pragma warning(disable:4103) /* disable warning message 4103 that complains + * about pragma pack in a header file */ + #pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */ +#endif + +/* 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__) && !defined AMX_NO_ALIGN + #define AMX_NO_ALIGN +#endif + +#if defined __GNUC__ + #define PACKED __attribute__((packed)) +#else + #define PACKED +#endif + +#if !defined AMX_NO_ALIGN + #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) */ + #if defined __TURBOC__ + #pragma option -a- /* "pack" pragma for older Borland compilers */ + #endif + #endif +#endif + +typedef struct tagAMX_NATIVE_INFO { + const char _FAR *name PACKED; + AMX_NATIVE func PACKED; +} PACKED AMX_NATIVE_INFO; + +#define AMX_USERNUM 4 +#define sEXPMAX 19 /* maximum name length for file version <= 6 */ +#define sNAMEMAX 31 /* maximum name length of symbol name */ + +typedef struct tagAMX_FUNCSTUB { + ucell address PACKED; + char name[sEXPMAX+1] PACKED; +} PACKED AMX_FUNCSTUB; + +typedef struct tagFUNCSTUBNT { + ucell address PACKED; + uint32_t nameofs PACKED; +} 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 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 */ + /* for external functions a few registers must be accessible from the outside */ + cell cip PACKED; /* instruction pointer: relative to base + amxhdr->cod */ + cell frm PACKED; /* stack frame base: relative to base + amxhdr->dat */ + cell hea PACKED; /* top of the heap: relative to base + amxhdr->dat */ + cell hlw PACKED; /* bottom of the heap: relative to base + amxhdr->dat */ + cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */ + cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */ + int flags PACKED; /* current status, see amx_Flags() */ + /* user data */ + long usertags[AMX_USERNUM] PACKED; + void _FAR *userdata[AMX_USERNUM] PACKED; + /* native functions can raise an error */ + int error PACKED; + /* passing parameters requires a "count" field */ + int paramcount; + /* the sleep opcode needs to store the full AMX status */ + cell pri PACKED; + cell alt PACKED; + cell reset_stk PACKED; + cell reset_hea PACKED; + cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */ + #if defined JIT + /* support variables for the JIT */ + int reloc_size PACKED; /* required temporary buffer for relocations */ + long code_size PACKED; /* estimated memory footprint of the native code */ + #endif +} PACKED AMX; + +/* The AMX_HEADER structure is both the memory format as the file format. The + * structure is used internaly. + */ +typedef struct tagAMX_HEADER { + int32_t size PACKED; /* size of the "file" */ + uint16_t magic PACKED; /* signature */ + char file_version PACKED; /* file format version */ + char amx_version PACKED; /* required version of the AMX */ + int16_t flags PACKED; + int16_t defsize PACKED; /* size of a definition record */ + int32_t cod PACKED; /* initial value of COD - code block */ + int32_t dat PACKED; /* initial value of DAT - data block */ + int32_t hea PACKED; /* initial value of HEA - start of the heap */ + int32_t stp PACKED; /* initial value of STP - stack top */ + int32_t cip PACKED; /* initial value of CIP - the instruction pointer */ + int32_t publics PACKED; /* offset to the "public functions" table */ + int32_t natives PACKED; /* offset to the "native functions" table */ + 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 */ +} PACKED AMX_HEADER; + +#if PAWN_CELL_SIZE==16 + #define AMX_MAGIC 0xf1e2 +#elif PAWN_CELL_SIZE==32 + #define AMX_MAGIC 0xf1e0 +#elif PAWN_CELL_SIZE==64 + #define AMX_MAGIC 0xf1e1 +#endif + +enum { + AMX_ERR_NONE, + /* reserve the first 15 error codes for exit codes of the abstract machine */ + AMX_ERR_EXIT, /* forced exit */ + AMX_ERR_ASSERT, /* assertion failed */ + AMX_ERR_STACKERR, /* stack/heap collision */ + AMX_ERR_BOUNDS, /* index out of bounds */ + AMX_ERR_MEMACCESS, /* invalid memory access */ + AMX_ERR_INVINSTR, /* invalid instruction */ + AMX_ERR_STACKLOW, /* stack underflow */ + AMX_ERR_HEAPLOW, /* heap underflow */ + AMX_ERR_CALLBACK, /* no callback, or invalid callback */ + 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 */ + AMX_ERR_VERSION, /* file is for a newer version of the AMX */ + AMX_ERR_NOTFOUND, /* function not found */ + AMX_ERR_INDEX, /* invalid index parameter (bad entry point) */ + AMX_ERR_DEBUG, /* debugger cannot run */ + AMX_ERR_INIT, /* AMX not initialized (or doubly initialized) */ + AMX_ERR_USERDATA, /* unable to set user data field (table full) */ + 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 */ + 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_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 */ +#define AMX_EXEC_CONT -2 /* continue from last address */ + +#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24)) + +#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 PAWN_CELL_SIZE==32 + #define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */ + #define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */ +#elif PAWN_CELL_SIZE==64 + #define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */ + #define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */ +#else + #error Unsupported cell size +#endif + +#define amx_StrParam(amx,param,result) \ + do { \ + cell *amx_cstr_; int amx_length_; \ + amx_GetAddr((amx), (param), &amx_cstr_); \ + 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_length_); \ + else (result) = NULL; \ + } while (0) + +uint16_t * AMXAPI amx_Align16(uint16_t *v); +uint32_t * AMXAPI amx_Align32(uint32_t *v); +#if defined _I64_MAX || defined HAVE_I64 + uint64_t * AMXAPI amx_Align64(uint64_t *v); +#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_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); +int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname); +int AMXAPI amx_Flags(AMX *amx,uint16_t *flags); +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, size_t size); +int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id); +int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr); +int AMXAPI amx_Init(AMX *amx, void *program); +int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code); +int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap); +int AMXAPI amx_NameLength(AMX *amx, int *length); +AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func); +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, 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, size_t size); +int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr); +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); + +#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 || defined __FreeBSD__ + #pragma pack() /* reset default packing */ + #elif defined MACOS && defined __MWERKS__ + #pragma options align=reset + #else + #pragma pack(pop) /* reset previous packing */ + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* AMX_H_INCLUDED */ diff --git a/compiler/amxxpc/amxxpc.cpp b/compiler/amxxpc/amxxpc.cpp new file mode 100755 index 00000000..28a8a3f4 --- /dev/null +++ b/compiler/amxxpc/amxxpc.cpp @@ -0,0 +1,326 @@ +#include +#ifdef __linux__ +#include +#else +#include +#include +#endif +#include "zlib.h" +#include "amx.h" +#include "amxxpc.h" + +int main(int argc, char **argv) +{ + struct abl pl32; + struct abl pl64; + +#ifdef _DEBUG + printf("debug clamp\n"); + getchar(); +#endif + +#ifdef __linux__ + HINSTANCE lib = dlmount("./amxxpc32.so"); +#else + HINSTANCE lib = dlmount("amxxpc32.dll"); +#endif + if (!lib) + { +#ifdef __linux__ + printf("32bit compiler failed to instantiate: %s\n", dlerror()); +#else + printf("32bit compiler failed to instantiate: %d\n", GetLastError()); +#endif + exit(0); + } + + COMPILER sc32 = (COMPILER)dlsym(lib, "Compile32"); + + if (!sc32) + { +#ifdef __linux__ + printf("32bit compiler failed to link: %p|%p.\n",sc32, sc_printf); +#else + printf("32bit compiler failed to link: %d.\n", GetLastError()); +#endif + exit(0); + } + + AMX_HEADER hdr; + + printf("Welcome to the AMX Mod X %s Compiler.\n", VERSION_STRING); + printf("Copyright (c) 1997-2005 ITB CompuPhase, AMX Mod X Team\n\n"); + + if (argc < 2) + { + printf("Usage: [options]\n"); + printf("Use -? or --help to see full options\n\n"); + getchar(); + exit(0); + } + + if (!strcmp(argv[1], "-?") || !strcmp(argv[1], "--help")) + { + show_help(); + printf("Press any key to continue.\n"); + getchar(); + exit(0); + } + + sc32(argc, argv); + + char *file = FindFileName(argc, argv); + + if (file == NULL) + { + printf("Could not locate the output file.\n"); + exit(0); + } else if (strstr(file, ".asm")) { + printf("Assembler output succeeded.\n"); + exit(0); + } else { + FILE *fp = fopen(file, "rb"); + if (fp == NULL) + { + printf("Could not locate output file %s (compile failed).\n", file); + exit(0); + } + fread(&hdr, sizeof(hdr), 1, fp); + amx_Align32((uint32_t *)&hdr.stp); + amx_Align32((uint32_t *)&hdr.size); + pl32.stp = hdr.stp; + pl32.cellsize = 4; + int size = sizeof(hdr) + hdr.size; + pl32.size = size; + pl32.data = new char[size]; + rewind(fp); + fread(pl32.data, 1, size, fp); + fclose(fp); + } + + unlink(file); + + HINSTANCE lib64 = 0; +#ifdef __linux__ + lib64 = dlmount("./amxxpc64.so"); +#else + lib64 = dlmount("amxxpc64.dll"); +#endif + if (!lib64) + { + printf("64bit compiler failed to instantiate.\n"); + exit(0); + } + + COMPILER sc64 = (COMPILER)dlsym(lib64, "Compile64"); + + if (!sc64) + { +#ifdef __linux__ + sc_printf("64bit compiler failed to link: %s.\n", dlerror()); +#else + printf("64bit compiler failed to link: %d.\n", GetLastError()); +#endif + exit(0); + } + + sc64(argc, argv); + + dlclose(lib64); + + if (file == NULL) + { + printf("Could not locate the output file on second pass.\n"); + exit(0); + } else { + FILE *fp = fopen(file, "rb"); + if (fp == NULL) + { + printf("Could not locate output file on second pass (compile failed).\n"); + exit(0); + } + fread(&hdr, sizeof(hdr), 1, fp); + amx_Align32((uint32_t *)&hdr.stp); + amx_Align32((uint32_t *)&hdr.size); + pl64.stp = hdr.stp; + pl64.cellsize = 8; + int size = sizeof(hdr) + hdr.size; + pl64.size = sizeof(hdr) + hdr.size; + pl64.data = new char[size]; + rewind(fp); + fread(pl64.data, 1, size, fp); + fclose(fp); + } + + ///////////// + // COMPRSSION + ///////////// + + int err; + + pl32.cmpsize = compressBound(pl32.size); + pl32.cmp = new char[pl32.cmpsize]; + err = compress((Bytef *)pl32.cmp, (uLongf *)&(pl32.cmpsize), (const Bytef*)pl32.data, pl32.size); + + if (err != Z_OK) + { + printf("internal error - compression failed on first pass: %d\n", err); + exit(0); + } + + pl64.cmpsize = compressBound(pl64.size); + pl64.cmp = new char[pl64.cmpsize]; + err = compress((Bytef *)pl64.cmp, (uLongf *)&(pl64.cmpsize), (const Bytef*)pl64.data, pl64.size); + + if (err != Z_OK) + { + printf("internal error - compression failed on second pass: %d\n", err); + exit(0); + } + + char *newfile = new char[strlen(file)+3]; + strcpy(newfile, file); + if (!strstr(file, ".amxx") && !strstr(file, ".AMXX")) + strcat(newfile, "x"); + + FILE *fp = fopen(newfile, "wb"); + if (!fp) + { + printf("Error trying to write file %s.\n", newfile); + exit(0); + } + + //magic + archn + int hdrsize = sizeof(long) + sizeof(char); + int entry = sizeof(long) + sizeof(long) + sizeof(char); + int offset1 = hdrsize + (entry * 2); + int offset2 = offset1 + pl32.cmpsize; + + int magic = MAGIC_HEADER; + fwrite((void *)&magic, sizeof(int), 1, fp); + char n = 2; + fwrite((void *)&n, sizeof(char), 1, fp); + + fwrite((void *)&(pl32.cellsize), sizeof(char), 1, fp); + fwrite((void *)&(pl32.stp), sizeof(long), 1, fp); + fwrite((void *)&(offset1), sizeof(long), 1, fp); + fwrite((void *)&(pl64.cellsize), sizeof(char), 1, fp); + fwrite((void *)&(pl64.stp), sizeof(long), 1, fp); + fwrite((void *)&(offset2), sizeof(long), 1, fp); + fwrite(pl32.cmp, sizeof(char), pl32.cmpsize, fp); + fwrite(pl64.cmp, sizeof(char), pl64.cmpsize, fp); + + fclose(fp); + + unlink(file); + + printf("Done.\n"); + + dlclose(lib); + + exit(0); +} + +//we get the full name of the file here +//our job is to a] switch the .sma extension to .amx +// and to b] strip everything but the trailing name +char *swiext(const char *file, const char *ext, int isO) +{ + int i = 0, pos = -1, j = 0; + int fileLen = strlen(file); + int extLen = strlen(ext); + int max = 0, odirFlag = -1; + + for (i=fileLen-1; i>=0; i--) + { + if (file[i] == '.' && pos == -1) + { + pos = i+1; + } + if ((file[i] == '/' || file[i] == '\\') && !isO) + { + odirFlag = i+1; + //realign pos - we've just stripped fileLen-i chars + pos -= i + 1; + break; + } + } + + char *newbuffer = new char[fileLen+strlen(ext)+2]; + fileLen += strlen(ext); + if (odirFlag == -1) + { + strcpy(newbuffer, file); + } else { + strcpy(newbuffer, &(file[odirFlag])); + } + + if (pos > -1) + { + for (i=pos; i0) + { + return swiext(argv[save], "amx", 0); + } + + return NULL; +} + +void show_help() +{ + printf("Options:\n"); + printf("\t-A alignment in bytes of the data segment and the stack\n"); + printf("\t-a output assembler code\n"); + printf("\t-C[+/-] compact encoding for output file (default=-)\n"); + printf("\t-c codepage name or number; e.g. 1252 for Windows Latin-1\n"); + printf("\t-Dpath active directory path\n"); + printf("\t-d0 no symbolic information, no run-time checks\n"); + printf("\t-d1 [default] run-time checks, no symbolic information\n"); + printf("\t-d2 full debug information and dynamic checking\n"); + printf("\t-d3 full debug information, dynamic checking, no optimization\n"); + printf("\t-e set name of error file (quiet compile)\n"); + printf("\t-H window handle to send a notification message on finish\n"); + printf("\t-i path for include files\n"); + printf("\t-l create list file (preprocess only)\n"); + printf("\t-o set base name of output file\n"); + printf("\t-p set name of \"prefix\" file\n"); + printf("\t-r[name] write cross reference report to console or to specified file\n"); +} diff --git a/compiler/amxxpc/amxxpc.h b/compiler/amxxpc/amxxpc.h new file mode 100755 index 00000000..cec83117 --- /dev/null +++ b/compiler/amxxpc/amxxpc.h @@ -0,0 +1,51 @@ +#ifndef _AMXXSC_INCLUDE_H +#define _AMXXSC_INCLUDE_H + +#define VERSION_STRING "1.50-300" +#define VERSION 03000 +#define MAGIC_HEADER 0x414D5842 + +#ifdef __linux__ +# include +#else +# include +#endif + +#include + +#ifdef __linux__ +# define dlmount(x) dlopen(x, RTLD_NOW) + typedef void* HINSTANCE; +#else +# define dlsym(x, s) GetProcAddress(x, s) +# define dlmount(x) LoadLibrary(x) +# define dlclose(x) FreeLibrary(x) +#endif + +#include "zlib.h" + +typedef int (*COMPILER)(int argc, char **argv); +typedef int (*PRINTF)(const char *message, ...); + +char *FindFileName(int argc, char **argv); +char *swiext(const char *file, const char *ext); +void show_help(); + + +struct ablhdr +{ + int magic; + char size; +}; + +struct abl +{ + long stp; + char cellsize; + int size; + long cmpsize; + char *data; + char *cmp; +}; + +#endif //_AMXXSC_INCLUDE_H diff --git a/compiler/amxxpc/amxxpc.sln b/compiler/amxxpc/amxxpc.sln new file mode 100755 index 00000000..a397c2e0 --- /dev/null +++ b/compiler/amxxpc/amxxpc.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxxpc", "amxxpc.vcproj", "{39412290-D01C-472F-A439-AB5592A04C08}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {39412290-D01C-472F-A439-AB5592A04C08}.Debug.ActiveCfg = Debug|Win32 + {39412290-D01C-472F-A439-AB5592A04C08}.Debug.Build.0 = Debug|Win32 + {39412290-D01C-472F-A439-AB5592A04C08}.Release.ActiveCfg = Release|Win32 + {39412290-D01C-472F-A439-AB5592A04C08}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/compiler/amxxpc/amxxpc.vcproj b/compiler/amxxpc/amxxpc.vcproj new file mode 100755 index 00000000..a16966d0 --- /dev/null +++ b/compiler/amxxpc/amxxpc.vcproj @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/compiler/amxxpc/amxxpc1.rc b/compiler/amxxpc/amxxpc1.rc new file mode 100755 index 00000000..0fd6c894 --- /dev/null +++ b/compiler/amxxpc/amxxpc1.rc @@ -0,0 +1,72 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource1.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource1.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +1 ICON "favicon.ico" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/compiler/amxxpc/favicon.ico b/compiler/amxxpc/favicon.ico new file mode 100755 index 0000000000000000000000000000000000000000..4e34066150f2ae52a44b6205ca69a43863b15bf6 GIT binary patch literal 766 zcmZQzU}RuqP*4zH0D%`w3=Con3=A3!3=9ek3=9qoAbA#$6axbjgaVNu)gTOFGcYuO z5ko@*h{XUR8$d!04Gaek9AIEz_zy-5|Nnzn3?TA9Na+861{W%Tv=opbZV<}F#pld1 z5dX{>u&|4ZPX~zQbD{^%?>Xk;a;5{$Khbd}#pguF8IUdzKGV^2>`X_`5fB@UPjs9? zk_PKVmUi(u(Sgtn(%}O)9K-`_0J{mogQ$nP1|)Q*qo)JpCJ@`j1tbl!53T^@7Lc2e zq`_*S3VgtBLGlmSElB=71NO-oxc{K$;G`e{2_Zp>+>&=QaBofnF(Ek3*x1+%YCBjY VEe)X>EI>2?Nk4QTnH#WL0stvk$l3q^ literal 0 HcmV?d00001 diff --git a/compiler/amxxpc/osdefs.h b/compiler/amxxpc/osdefs.h new file mode 100755 index 00000000..60d61e68 --- /dev/null +++ b/compiler/amxxpc/osdefs.h @@ -0,0 +1,60 @@ +/* __MSDOS__ set when compiling for DOS (not Windows) + * _Windows set when compiling for any version of Microsoft Windows + * __WIN32__ set when compiling for Windows95 or WindowsNT (32 bit mode) + * __32BIT__ set when compiling in 32-bit "flat" mode (DOS or Windows) + * + * Copyright 1998-2002, ITB CompuPhase, The Netherlands. + * info@compuphase.com. + */ + +#ifndef _OSDEFS_H +#define _OSDEFS_H + +/* Every compiler uses different "default" macros to indicate the mode + * it is in. Throughout the source, we use the Borland C++ macros, so + * the macros of Watcom C/C++ and Microsoft Visual C/C++ are mapped to + * those of Borland C++. + */ +#if defined(__WATCOMC__) +# if defined(__WINDOWS__) || defined(__NT__) +# define _Windows 1 +# endif +# ifdef __386__ +# define __32BIT__ 1 +# endif +# if defined(_Windows) && defined(__32BIT__) +# define __WIN32__ 1 +# endif +#elif defined(_MSC_VER) +# if defined(_WINDOWS) || defined(_WIN32) +# define _Windows 1 +# endif +# ifdef _WIN32 +# define __WIN32__ 1 +# define __32BIT__ 1 +# endif +#endif + +#if defined __linux__ + #include +#endif + +/* Linux NOW has these */ +#if !defined BIG_ENDIAN + #define BIG_ENDIAN 4321 +#endif +#if !defined LITTLE_ENDIAN + #define LITTLE_ENDIAN 1234 +#endif + +/* educated guess, BYTE_ORDER is undefined, i386 is common => little endian */ +#if !defined BYTE_ORDER + #if defined UCLINUX + #define BYTE_ORDER BIG_ENDIAN + #else + #define BYTE_ORDER LITTLE_ENDIAN + #endif +#endif + +#endif /* _OSDEFS_H */ + diff --git a/compiler/amxxpc/resource.h b/compiler/amxxpc/resource.h new file mode 100755 index 00000000..c5a4bded --- /dev/null +++ b/compiler/amxxpc/resource.h @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by amxxsc.rc +// +#define ICON 5 +#define IDI_ICON1 104 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 105 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/compiler/amxxpc/resource1.h b/compiler/amxxpc/resource1.h new file mode 100755 index 00000000..c32213f3 --- /dev/null +++ b/compiler/amxxpc/resource1.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by amxxsc1.rc +// +#define IDI_ICON1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/compiler/amxxpc/sclinux.h b/compiler/amxxpc/sclinux.h new file mode 100755 index 00000000..f22497a8 --- /dev/null +++ b/compiler/amxxpc/sclinux.h @@ -0,0 +1,47 @@ +/* + * Things needed to compile under linux. + * + * Should be reworked totally to use GNU's 'configure' + */ +#ifndef SCLINUX_H +#define SCLINUX_H + +/* getchar() is not a 'cool' replacement for MSDOS getch: Linux/unix depends on the features activated or not about the + * controlling terminal's tty. This means that ioctl(2) calls must be performed, for instance to have the controlling + * terminal tty's in 'raw' mode, if we want to be able to fetch a single character. This also means that everything must + * be put back correctly when the function ends. See GETCH.C for an implementation. + * + * For interactive use of SRUN/SDBG if would be much better to use GNU's readline package: the user would be able to + * have a complete emacs/vi like line editing system. + */ +#include "getch.h" + +#define stricmp(a,b) strcasecmp(a,b) +#define strnicmp(a,b,c) strncasecmp(a,b,c) + +/* + * WinWorld wants '\'. Unices do not. + */ +#define DIRECTORY_SEP_CHAR '/' +#define DIRECTORY_SEP_STR "/" + +/* + * SC assumes that a computer is Little Endian unless told otherwise. It uses + * (and defines) the macros BYTE_ORDER and BIG_ENDIAN. + * For Linux, we must overrule these settings with those defined in glibc. + */ +#if !defined __BYTE_ORDER +# include +#endif + +#if defined __OpenBSD__ || defined __FreeBSD__ +# define __BYTE_ORDER BYTE_ORDER +# define __LITTLE_ENDIAN LITTLE_ENDIAN +# define __BIG_ENDIAN BIG_ENDIAN +#endif + +#if !defined __BYTE_ORDER +# error "Can't figure computer byte order (__BYTE_ORDER macro not found)" +#endif + +#endif /* SCLINUX_H */ diff --git a/compiler/amxxpc/testmini.c b/compiler/amxxpc/testmini.c new file mode 100755 index 00000000..2e5e13f5 --- /dev/null +++ b/compiler/amxxpc/testmini.c @@ -0,0 +1,155 @@ +/* testmini.c -- very simple test program for the miniLZO library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer + + */ + + +#include +#include + + +/************************************************************************* +// This program shows the basic usage of the LZO library. +// We will compress a block of data and decompress again. +// +// For more information, documentation, example programs and other support +// files (like Makefiles and build scripts) please download the full LZO +// package from +// http://www.oberhumer.com/opensource/lzo/ +**************************************************************************/ + +/* First let's include "minizo.h". */ + +#include "minilzo.h" + + +/* We want to compress the data block at `in' with length `IN_LEN' to + * the block at `out'. Because the input block may be incompressible, + * we must provide a little more output space in case that compression + * is not possible. + */ + +#if defined(__LZO_STRICT_16BIT) +#define IN_LEN (8*1024) +#else +#define IN_LEN (128*1024L) +#endif +#define OUT_LEN (IN_LEN + IN_LEN / 64 + 16 + 3) + +static lzo_byte in [ IN_LEN ]; +static lzo_byte out [ OUT_LEN ]; + + +/* Work-memory needed for compression. Allocate memory in units + * of `lzo_align_t' (instead of `char') to make sure it is properly aligned. + */ + +#define HEAP_ALLOC(var,size) \ + lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ] + +static HEAP_ALLOC(wrkmem,LZO1X_1_MEM_COMPRESS); + + +/************************************************************************* +// +**************************************************************************/ + +int main(int argc, char *argv[]) +{ + int r; + lzo_uint in_len; + lzo_uint out_len; + lzo_uint new_len; + +#if defined(__EMX__) + _response(&argc,&argv); + _wildcard(&argc,&argv); +#endif + + if (argc < 0 && argv == NULL) /* avoid warning about unused args */ + return 0; + + printf("\nLZO real-time data compression library (v%s, %s).\n", + lzo_version_string(), lzo_version_date()); + printf("Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer\n\n"); + + +/* + * Step 1: initialize the LZO library + */ + if (lzo_init() != LZO_E_OK) + { + printf("lzo_init() failed !!!\n"); + return 3; + } + +/* + * Step 2: prepare the input block that will get compressed. + * We just fill it with zeros in this example program, + * but you would use your real-world data here. + */ + in_len = IN_LEN; + lzo_memset(in,0,in_len); + +/* + * Step 3: compress from `in' to `out' with LZO1X-1 + */ + r = lzo1x_1_compress(in,in_len,out,&out_len,wrkmem); + if (r == LZO_E_OK) + printf("compressed %lu bytes into %lu bytes\n", + (long) in_len, (long) out_len); + else + { + /* this should NEVER happen */ + printf("internal error - compression failed: %d\n", r); + return 2; + } + /* check for an incompressible block */ + if (out_len >= in_len) + { + printf("This block contains incompressible data.\n"); + return 0; + } + +/* + * Step 4: decompress again, now going from `out' to `in' + */ + r = lzo1x_decompress(out,out_len,in,&new_len,NULL); + if (r == LZO_E_OK && new_len == in_len) + printf("decompressed %lu bytes back into %lu bytes\n", + (long) out_len, (long) in_len); + else + { + /* this should NEVER happen */ + printf("internal error - decompression failed: %d\n", r); + return 1; + } + + printf("\nminiLZO simple compression test passed.\n"); + return 0; +} + +/* +vi:ts=4 +*/ + diff --git a/compiler/amxxpc/zconf.h b/compiler/amxxpc/zconf.h new file mode 100755 index 00000000..3cea897e --- /dev/null +++ b/compiler/amxxpc/zconf.h @@ -0,0 +1,323 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflatePrime z_deflatePrime +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +#define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/compiler/amxxpc/zlib.h b/compiler/amxxpc/zlib.h new file mode 100755 index 00000000..92edf96f --- /dev/null +++ b/compiler/amxxpc/zlib.h @@ -0,0 +1,1200 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.1, November 17th, 2003 + + Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler + + 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 the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.1" +#define ZLIB_VERNUM 0x1210 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by the in-memory functions is the zlib + format, which is a zlib wrapper documented in RFC 1950, wrapped around a + deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + This library does not provide any functions to write gzip files in memory. + However such functions could be easily written using zlib's deflate function, + the documentation in the gzip RFC, and the examples in gzio.c. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it get to the next deflate block boundary. When decoding the zlib + or gzip format, this will cause inflate() to return immediately after the + header and before the first block. When doing a raw inflate, inflate() will + go ahead and process the first block, and will return when it gets to the end + of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); + +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int err)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/compiler/amxxpc/zlib.lib b/compiler/amxxpc/zlib.lib new file mode 100755 index 0000000000000000000000000000000000000000..d5348407fc90c3a723bfc1a223e0b3baf671eef4 GIT binary patch literal 221206 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�W%|Hfsh^p&&d_bF;g9A!ibp> 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 literal 0 HcmV?d00001 diff --git a/compiler/libpc300/amx.h b/compiler/libpc300/amx.h index cf194750..b0443801 100755 --- a/compiler/libpc300/amx.h +++ b/compiler/libpc300/amx.h @@ -249,11 +249,9 @@ typedef struct tagAMX { cell reset_stk PACKED; cell reset_hea PACKED; cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */ - #if defined JIT - /* support variables for the JIT */ - int reloc_size PACKED; /* required temporary buffer for relocations */ - long code_size PACKED; /* estimated memory footprint of the native code */ - #endif + /* 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 */ } PACKED AMX; /* The AMX_HEADER structure is both the memory format as the file format. The @@ -279,13 +277,8 @@ typedef struct tagAMX_HEADER { int32_t nametable PACKED; /* name table */ } PACKED AMX_HEADER; -#if PAWN_CELL_SIZE==16 - #define AMX_MAGIC 0xf1e2 -#elif PAWN_CELL_SIZE==32 - #define AMX_MAGIC 0xf1e0 -#elif PAWN_CELL_SIZE==64 - #define AMX_MAGIC 0xf1e1 -#endif +//This is always the same for us +#define AMX_MAGIC 0xf1e0 enum { AMX_ERR_NONE, diff --git a/compiler/libpc300/libpawnc.c b/compiler/libpc300/libpawnc.c index 13fcc8e8..39b42ab0 100755 --- a/compiler/libpc300/libpawnc.c +++ b/compiler/libpc300/libpawnc.c @@ -56,48 +56,13 @@ # if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined __NT__ __declspec (dllexport) - void EXCOMPILER(HWND hwnd, HINSTANCE hinst, LPSTR lpCommandLine, int nCmdShow) + void EXCOMPILER(int argc, char **argv) # else - void extern EXCOMPILER(HWND hwnd, HINSTANCE hinst, LPSTR lpCommandLine, int nCmdShow) + void extern EXCOMPILER(int argc, char **argv) # endif { - char RootPath[_MAX_PATH]; - LPSTR ptr; - - /* RUNDLL32 may have passed us a HWND and a HINSTANCE, but we can hardly - * trust these. They may not contain values that we can use. - */ - - /* the root path in argv[0] */ - GetModuleFileName(hinstDLL, RootPath, sizeof RootPath); - argv[argc++]=RootPath; - - /* all other options */ - assert(lpCommandLine!=NULL); - ptr=dll_skipwhite(lpCommandLine); - while (*ptr!='\0') { - if (*ptr=='"') { - argv[argc++]=ptr+1; - while (*ptr!='"' && *ptr!='\0') - ptr++; - } else { - argv[argc++]=ptr; - while (*ptr>' ') - ptr++; - } /* if */ - if (*ptr!='\0') - *ptr++='\0'; - ptr=dll_skipwhite(ptr); - } /* while */ - pc_compile(argc,argv); - UNUSED_PARAM(hwnd); - UNUSED_PARAM(hinst); - UNUSED_PARAM(nCmdShow); + pc_compile(argc, argv); } - -#else /* PAWNC_DLL */ - - #endif /* PAWNC_DLL */ diff --git a/compiler/libpc300/libpc300.vcproj b/compiler/libpc300/libpc300.vcproj index 87880631..cf897b05 100755 --- a/compiler/libpc300/libpc300.vcproj +++ b/compiler/libpc300/libpc300.vcproj @@ -258,6 +258,9 @@ Name="Header Files" Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + + diff --git a/compiler/libpc300/sclist.c b/compiler/libpc300/sclist.c index ab96a9e7..7d24e142 100755 --- a/compiler/libpc300/sclist.c +++ b/compiler/libpc300/sclist.c @@ -409,16 +409,18 @@ SC_FUNC stringlist *insert_dbgline(int linenr) char string[40]; if (linenr>0) linenr--; /* line numbers are zero-based in the debug information */ -#if PAWN_CELL_SIZE==32 sprintf(string,"L:%08lx %04x",(long)code_idx,linenr); -#elif PAWN_CELL_SIZE==64 - sprintf(string,"L:%08Lx %04x",(long)code_idx,linenr); -#endif return insert_string(&dbgstrings,string); } /* if */ return NULL; } +#ifdef WIN32 +#define LONGCAST long +#else +#define LONGCAST cell +#endif + SC_FUNC stringlist *insert_dbgsymbol(symbol *sym) { if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) { @@ -440,10 +442,10 @@ SC_FUNC stringlist *insert_dbgsymbol(symbol *sym) symname,sym->codeaddr,code_idx,sym->ident,sym->vclass); #elif PAWN_CELL_SIZE==64 if (sym->ident==iFUNCTN) - sprintf(string,"S:%08Lx %x:%s %08Lx %08Lx %x %x",sym->addr,sym->tag, + sprintf(string,"S:%08Lx %x:%s %08Lx %08Lx %x %x",(LONGCAST)sym->addr,sym->tag, symname,sym->addr,sym->codeaddr,sym->ident,sym->vclass); else - sprintf(string,"S:%08Lx %x:%s %08Lx %08Lx %x %x",sym->addr,sym->tag, + sprintf(string,"S:%08Lx %x:%s %08Lx %08Lx %x %x",(LONGCAST)sym->addr,sym->tag, symname,sym->codeaddr,code_idx,sym->ident,sym->vclass); #endif if (sym->ident==iARRAY || sym->ident==iREFARRAY) {