|
dvander@27
|
1 |
/* Pawn Abstract Machine (for the Pawn language) |
|
dvander@27
|
2 |
* |
|
dvander@27
|
3 |
* Copyright (c) ITB CompuPhase, 1997-2006 |
|
dvander@27
|
4 |
* |
|
dvander@27
|
5 |
* This software is provided "as-is", without any express or implied warranty. |
|
dvander@27
|
6 |
* In no event will the authors be held liable for any damages arising from |
|
dvander@27
|
7 |
* the use of this software. |
|
dvander@27
|
8 |
* |
|
dvander@27
|
9 |
* Permission is granted to anyone to use this software for any purpose, |
|
dvander@27
|
10 |
* including commercial applications, and to alter it and redistribute it |
|
dvander@27
|
11 |
* freely, subject to the following restrictions: |
|
dvander@27
|
12 |
* |
|
dvander@27
|
13 |
* 1. The origin of this software must not be misrepresented; you must not |
|
dvander@27
|
14 |
* claim that you wrote the original software. If you use this software in |
|
dvander@27
|
15 |
* a product, an acknowledgment in the product documentation would be |
|
dvander@27
|
16 |
* appreciated but is not required. |
|
dvander@27
|
17 |
* 2. Altered source versions must be plainly marked as such, and must not be |
|
dvander@27
|
18 |
* misrepresented as being the original software. |
|
dvander@27
|
19 |
* 3. This notice may not be removed or altered from any source distribution. |
|
dvander@27
|
20 |
* |
|
dvander@365
|
21 |
* Version: $Id$ |
|
dvander@27
|
22 |
*/ |
|
dvander@27
|
23 |
|
|
dvander@27
|
24 |
#ifndef AMX_H_INCLUDED |
|
dvander@27
|
25 |
#define AMX_H_INCLUDED |
|
dvander@27
|
26 |
|
|
dvander@27
|
27 |
#include <stdlib.h> /* for size_t */ |
|
dvander@27
|
28 |
#include <limits.h> |
|
dvander@27
|
29 |
|
|
dvander@27
|
30 |
#if defined FREEBSD && !defined __FreeBSD__ |
|
dvander@27
|
31 |
#define __FreeBSD__ |
|
dvander@27
|
32 |
#endif |
|
dvander@27
|
33 |
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ |
|
dvander@27
|
34 |
#include <sclinux.h> |
|
dvander@27
|
35 |
#endif |
|
dvander@27
|
36 |
|
|
dvander@27
|
37 |
#if defined __GNUC__ |
|
dvander@27
|
38 |
#include <stdint.h> |
|
dvander@353
|
39 |
#if !defined HAVE_STDINT_H |
|
dvander@353
|
40 |
#define HAVE_STDINT_H |
|
dvander@353
|
41 |
#endif |
|
dvander@27
|
42 |
#elif !defined HAVE_STDINT_H |
|
dvander@27
|
43 |
#if defined __LCC__ || defined __DMC__ || defined LINUX || (defined __WATCOMC__ && __WATCOMC__ >= 1200) |
|
dvander@27
|
44 |
#if defined HAVE_INTTYPES_H |
|
dvander@27
|
45 |
#include <inttypes.h> |
|
dvander@27
|
46 |
#else |
|
dvander@27
|
47 |
#include <stdint.h> |
|
dvander@27
|
48 |
#endif |
|
dvander@27
|
49 |
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L |
|
dvander@27
|
50 |
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got |
|
dvander@27
|
51 |
* here, these types are probably undefined. |
|
dvander@27
|
52 |
*/ |
|
dvander@27
|
53 |
#if defined __MACH__ |
|
dvander@27
|
54 |
#include <ppc/types.h> |
|
dvander@27
|
55 |
typedef unsigned short int uint16_t; |
|
dvander@27
|
56 |
typedef unsigned long int uint32_t; |
|
dvander@27
|
57 |
#elif defined __FreeBSD__ |
|
dvander@27
|
58 |
#include <inttypes.h> |
|
dvander@27
|
59 |
#else |
|
dvander@27
|
60 |
typedef short int int16_t; |
|
dvander@27
|
61 |
typedef unsigned short int uint16_t; |
|
dvander@27
|
62 |
#if defined SN_TARGET_PS2 |
|
dvander@27
|
63 |
typedef int int32_t; |
|
dvander@27
|
64 |
typedef unsigned int uint32_t; |
|
dvander@27
|
65 |
#else |
|
dvander@27
|
66 |
typedef long int int32_t; |
|
dvander@27
|
67 |
typedef unsigned long int uint32_t; |
|
dvander@27
|
68 |
#endif |
|
dvander@27
|
69 |
#if defined __WIN32__ || defined _WIN32 || defined WIN32 |
|
dvander@27
|
70 |
typedef __int64 int64_t; |
|
dvander@27
|
71 |
typedef unsigned __int64 uint64_t; |
|
dvander@27
|
72 |
#define HAVE_I64 |
|
dvander@27
|
73 |
#elif defined __GNUC__ |
|
dvander@27
|
74 |
typedef long long int64_t; |
|
dvander@27
|
75 |
typedef unsigned long long uint64_t; |
|
dvander@27
|
76 |
#define HAVE_I64 |
|
dvander@27
|
77 |
#endif |
|
dvander@27
|
78 |
#endif |
|
dvander@27
|
79 |
#endif |
|
dvander@27
|
80 |
#define HAVE_STDINT_H |
|
dvander@27
|
81 |
#endif |
|
dvander@27
|
82 |
#if defined _LP64 || defined WIN64 || defined _WIN64 |
|
dvander@27
|
83 |
#if !defined __64BIT__ |
|
dvander@27
|
84 |
#define __64BIT__ |
|
dvander@27
|
85 |
#endif |
|
dvander@27
|
86 |
#endif |
|
dvander@27
|
87 |
|
|
dvander@27
|
88 |
#if HAVE_ALLOCA_H |
|
dvander@27
|
89 |
#include <alloca.h> |
|
dvander@27
|
90 |
#endif |
|
dvander@27
|
91 |
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */ |
|
dvander@27
|
92 |
#if !defined alloca |
|
dvander@27
|
93 |
#define alloca(n) _alloca(n) |
|
dvander@27
|
94 |
#endif |
|
dvander@27
|
95 |
#endif |
|
dvander@27
|
96 |
|
|
dvander@27
|
97 |
#if !defined arraysize |
|
dvander@27
|
98 |
#define arraysize(array) (sizeof(array) / sizeof((array)[0])) |
|
dvander@27
|
99 |
#endif |
|
dvander@27
|
100 |
#if !defined assert_static |
|
dvander@27
|
101 |
/* see "Compile-Time Assertions" by Ralf Holly, |
|
dvander@27
|
102 |
* C/C++ Users Journal, November 2004 |
|
dvander@27
|
103 |
*/ |
|
dvander@27
|
104 |
#define assert_static(e) \ |
|
dvander@27
|
105 |
do { \ |
|
dvander@27
|
106 |
enum { assert_static__ = 1/(e) }; \ |
|
dvander@27
|
107 |
} while (0) |
|
dvander@27
|
108 |
#endif |
|
dvander@27
|
109 |
|
|
dvander@27
|
110 |
#ifdef __cplusplus |
|
dvander@27
|
111 |
extern "C" { |
|
dvander@27
|
112 |
#endif |
|
dvander@27
|
113 |
|
|
dvander@27
|
114 |
#if defined PAWN_DLL |
|
dvander@27
|
115 |
#if !defined AMX_NATIVE_CALL |
|
dvander@27
|
116 |
#define AMX_NATIVE_CALL __stdcall |
|
dvander@27
|
117 |
#endif |
|
dvander@27
|
118 |
#if !defined AMXAPI |
|
dvander@27
|
119 |
#define AMXAPI __stdcall |
|
dvander@27
|
120 |
#endif |
|
dvander@27
|
121 |
#endif |
|
dvander@27
|
122 |
|
|
dvander@27
|
123 |
/* calling convention for native functions */ |
|
dvander@27
|
124 |
#if !defined AMX_NATIVE_CALL |
|
dvander@27
|
125 |
#define AMX_NATIVE_CALL |
|
dvander@27
|
126 |
#endif |
|
dvander@27
|
127 |
/* calling convention for all interface functions and callback functions */ |
|
dvander@27
|
128 |
#if !defined AMXAPI |
|
dvander@27
|
129 |
#if defined STDECL |
|
dvander@27
|
130 |
#define AMXAPI __stdcall |
|
dvander@27
|
131 |
#elif defined CDECL |
|
dvander@27
|
132 |
#define AMXAPI __cdecl |
|
dvander@27
|
133 |
#elif defined GCC_HASCLASSVISIBILITY |
|
dvander@27
|
134 |
#define AMXAPI __attribute__ ((visibility("default"))) |
|
dvander@27
|
135 |
#else |
|
dvander@27
|
136 |
#define AMXAPI |
|
dvander@27
|
137 |
#endif |
|
dvander@27
|
138 |
#endif |
|
dvander@27
|
139 |
#if !defined AMXEXPORT |
|
dvander@27
|
140 |
#define AMXEXPORT |
|
dvander@27
|
141 |
#endif |
|
dvander@27
|
142 |
|
|
dvander@27
|
143 |
/* File format version (in CUR_FILE_VERSION) |
|
dvander@27
|
144 |
* 0 (original version) |
|
dvander@27
|
145 |
* 1 (opcodes JUMP.pri, SWITCH and CASETBL) |
|
dvander@27
|
146 |
* 2 (compressed files) |
|
dvander@27
|
147 |
* 3 (public variables) |
|
dvander@27
|
148 |
* 4 (opcodes SWAP.pri/alt and PUSHADDR) |
|
dvander@27
|
149 |
* 5 (tagnames table) |
|
dvander@27
|
150 |
* 6 (reformatted header) |
|
dvander@27
|
151 |
* 7 (name table, opcodes SYMTAG & SYSREQ.D) |
|
dvander@27
|
152 |
* 8 (opcode STMT, renewed debug interface) |
|
dvander@27
|
153 |
* 9 (macro opcodes) |
|
dvander@27
|
154 |
* MIN_FILE_VERSION is the lowest file version number that the current AMX |
|
dvander@27
|
155 |
* implementation supports. If the AMX file header gets new fields, this number |
|
dvander@27
|
156 |
* often needs to be incremented. MAX_AMX_VERSION is the lowest AMX version that |
|
dvander@27
|
157 |
* is needed to support the current file version. When there are new opcodes, |
|
dvander@27
|
158 |
* this number needs to be incremented. |
|
dvander@27
|
159 |
* The file version supported by the JIT may run behind MIN_AMX_VERSION. So |
|
dvander@27
|
160 |
* there is an extra constant for it: MAX_FILE_VER_JIT. |
|
dvander@27
|
161 |
*/ |
|
dvander@27
|
162 |
#define CUR_FILE_VERSION 9 /* current file version; also the current AMX version */ |
|
dvander@27
|
163 |
#define MIN_FILE_VERSION 6 /* lowest supported file format version for the current AMX version */ |
|
dvander@27
|
164 |
#define MIN_AMX_VERSION 9 /* minimum AMX version needed to support the current file format */ |
|
dvander@27
|
165 |
#define MAX_FILE_VER_JIT 8 /* file version supported by the JIT */ |
|
dvander@27
|
166 |
#define MIN_AMX_VER_JIT 8 /* AMX version supported by the JIT */ |
|
dvander@27
|
167 |
|
|
dvander@27
|
168 |
#if !defined PAWN_CELL_SIZE |
|
dvander@27
|
169 |
#define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */ |
|
dvander@27
|
170 |
#endif |
|
dvander@27
|
171 |
#if PAWN_CELL_SIZE==16 |
|
dvander@27
|
172 |
typedef uint16_t ucell; |
|
dvander@27
|
173 |
typedef int16_t cell; |
|
dvander@27
|
174 |
#elif PAWN_CELL_SIZE==32 |
|
dvander@27
|
175 |
typedef uint32_t ucell; |
|
dvander@27
|
176 |
typedef int32_t cell; |
|
dvander@27
|
177 |
#elif PAWN_CELL_SIZE==64 |
|
dvander@27
|
178 |
typedef uint64_t ucell; |
|
dvander@27
|
179 |
typedef int64_t cell; |
|
dvander@27
|
180 |
#else |
|
dvander@27
|
181 |
#error Unsupported cell size (PAWN_CELL_SIZE) |
|
dvander@27
|
182 |
#endif |
|
dvander@27
|
183 |
|
|
dvander@27
|
184 |
#define UNPACKEDMAX (((cell)1 << (sizeof(cell)-1)*8) - 1) |
|
dvander@27
|
185 |
#define UNLIMITED (~1u >> 1) |
|
dvander@27
|
186 |
|
|
dvander@27
|
187 |
struct tagAMX; |
|
dvander@27
|
188 |
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params); |
|
dvander@27
|
189 |
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index, |
|
dvander@27
|
190 |
cell *result, cell *params); |
|
dvander@27
|
191 |
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx); |
|
dvander@27
|
192 |
typedef int (AMXAPI *AMX_IDLE)(struct tagAMX *amx, int AMXAPI Exec(struct tagAMX *, cell *, int)); |
|
dvander@27
|
193 |
#if !defined _FAR |
|
dvander@27
|
194 |
#define _FAR |
|
dvander@27
|
195 |
#endif |
|
dvander@27
|
196 |
|
|
dvander@27
|
197 |
#if defined _MSC_VER |
|
dvander@27
|
198 |
#pragma warning(disable:4103) /* disable warning message 4103 that complains |
|
dvander@27
|
199 |
* about pragma pack in a header file */ |
|
dvander@27
|
200 |
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */ |
|
dvander@27
|
201 |
#endif |
|
dvander@27
|
202 |
|
|
dvander@27
|
203 |
/* Some compilers do not support the #pragma align, which should be fine. Some |
|
dvander@27
|
204 |
* compilers give a warning on unknown #pragmas, which is not so fine... |
|
dvander@27
|
205 |
*/ |
|
dvander@27
|
206 |
#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN |
|
dvander@27
|
207 |
#define AMX_NO_ALIGN |
|
dvander@27
|
208 |
#endif |
|
dvander@27
|
209 |
|
|
dvander@27
|
210 |
#if !defined AMX_NO_ALIGN |
|
dvander@27
|
211 |
#if defined LINUX || defined __FreeBSD__ |
|
dvander@27
|
212 |
#pragma pack(1) /* structures must be packed (byte-aligned) */ |
|
dvander@27
|
213 |
#elif defined MACOS && defined __MWERKS__ |
|
dvander@27
|
214 |
#pragma options align=mac68k |
|
dvander@27
|
215 |
#else |
|
dvander@27
|
216 |
#pragma pack(push) |
|
dvander@27
|
217 |
#pragma pack(1) /* structures must be packed (byte-aligned) */ |
|
dvander@27
|
218 |
#if defined __TURBOC__ |
|
dvander@27
|
219 |
#pragma option -a- /* "pack" pragma for older Borland compilers */ |
|
dvander@27
|
220 |
#endif |
|
dvander@27
|
221 |
#endif |
|
dvander@27
|
222 |
#endif |
|
dvander@27
|
223 |
|
|
dvander@27
|
224 |
typedef struct tagAMX_NATIVE_INFO { |
|
dvander@31
|
225 |
const char _FAR *name; |
|
dvander@31
|
226 |
AMX_NATIVE func; |
|
dvander@27
|
227 |
} AMX_NATIVE_INFO; |
|
dvander@27
|
228 |
|
|
dvander@27
|
229 |
#define AMX_USERNUM 4 |
|
dvander@27
|
230 |
#define sEXPMAX 19 /* maximum name length for file version <= 6 */ |
|
dvander@27
|
231 |
#define sNAMEMAX 31 /* maximum name length of symbol name */ |
|
dvander@27
|
232 |
|
|
dvander@27
|
233 |
typedef struct tagAMX_FUNCSTUB { |
|
dvander@31
|
234 |
ucell address; |
|
dvander@31
|
235 |
char name[sEXPMAX+1]; |
|
dvander@27
|
236 |
} AMX_FUNCSTUB; |
|
dvander@27
|
237 |
|
|
dvander@27
|
238 |
typedef struct tagFUNCSTUBNT { |
|
dvander@31
|
239 |
ucell address; |
|
dvander@31
|
240 |
uint32_t nameofs; |
|
dvander@27
|
241 |
} AMX_FUNCSTUBNT; |
|
dvander@27
|
242 |
|
|
dvander@27
|
243 |
/* The AMX structure is the internal structure for many functions. Not all |
|
dvander@27
|
244 |
* fields are valid at all times; many fields are cached in local variables. |
|
dvander@27
|
245 |
*/ |
|
dvander@27
|
246 |
typedef struct tagAMX { |
|
dvander@31
|
247 |
unsigned char _FAR *base; /* points to the AMX header plus the code, optionally also the data */ |
|
dvander@31
|
248 |
unsigned char _FAR *data; /* points to separate data+stack+heap, may be NULL */ |
|
dvander@31
|
249 |
AMX_CALLBACK callback; |
|
dvander@31
|
250 |
AMX_DEBUG debug ; /* debug callback */ |
|
dvander@27
|
251 |
/* for external functions a few registers must be accessible from the outside */ |
|
dvander@31
|
252 |
cell cip ; /* instruction pointer: relative to base + amxhdr->cod */ |
|
dvander@31
|
253 |
cell frm ; /* stack frame base: relative to base + amxhdr->dat */ |
|
dvander@31
|
254 |
cell hea ; /* top of the heap: relative to base + amxhdr->dat */ |
|
dvander@31
|
255 |
cell hlw ; /* bottom of the heap: relative to base + amxhdr->dat */ |
|
dvander@31
|
256 |
cell stk ; /* stack pointer: relative to base + amxhdr->dat */ |
|
dvander@31
|
257 |
cell stp ; /* top of the stack: relative to base + amxhdr->dat */ |
|
dvander@31
|
258 |
int flags ; /* current status, see amx_Flags() */ |
|
dvander@27
|
259 |
/* user data */ |
|
dvander@31
|
260 |
long usertags[AMX_USERNUM] ; |
|
dvander@31
|
261 |
void _FAR *userdata[AMX_USERNUM] ; |
|
dvander@27
|
262 |
/* native functions can raise an error */ |
|
dvander@31
|
263 |
int error ; |
|
dvander@27
|
264 |
/* passing parameters requires a "count" field */ |
|
dvander@27
|
265 |
int paramcount; |
|
dvander@27
|
266 |
/* the sleep opcode needs to store the full AMX status */ |
|
dvander@31
|
267 |
cell pri ; |
|
dvander@31
|
268 |
cell alt ; |
|
dvander@31
|
269 |
cell reset_stk ; |
|
dvander@31
|
270 |
cell reset_hea ; |
|
faluco@62
|
271 |
/* extra fields for increased performance */ |
|
dvander@31
|
272 |
cell sysreq_d ; /* relocated address/value for the SYSREQ.D opcode */ |
|
dvander@27
|
273 |
#if defined JIT |
|
dvander@27
|
274 |
/* support variables for the JIT */ |
|
dvander@31
|
275 |
int reloc_size ; /* required temporary buffer for relocations */ |
|
dvander@31
|
276 |
long code_size ; /* estimated memory footprint of the native code */ |
|
dvander@27
|
277 |
#endif |
|
dvander@27
|
278 |
} AMX; |
|
dvander@27
|
279 |
|
|
dvander@27
|
280 |
/* The AMX_HEADER structure is both the memory format as the file format. The |
|
dvander@27
|
281 |
* structure is used internaly. |
|
dvander@27
|
282 |
*/ |
|
dvander@27
|
283 |
typedef struct tagAMX_HEADER { |
|
dvander@31
|
284 |
int32_t size ; /* size of the "file" */ |
|
dvander@31
|
285 |
uint16_t magic ; /* signature */ |
|
dvander@31
|
286 |
char file_version ; /* file format version */ |
|
dvander@31
|
287 |
char amx_version ; /* required version of the AMX */ |
|
dvander@31
|
288 |
int16_t flags ; |
|
dvander@31
|
289 |
int16_t defsize ; /* size of a definition record */ |
|
dvander@31
|
290 |
int32_t cod ; /* initial value of COD - code block */ |
|
dvander@31
|
291 |
int32_t dat ; /* initial value of DAT - data block */ |
|
dvander@31
|
292 |
int32_t hea ; /* initial value of HEA - start of the heap */ |
|
dvander@31
|
293 |
int32_t stp ; /* initial value of STP - stack top */ |
|
dvander@31
|
294 |
int32_t cip ; /* initial value of CIP - the instruction pointer */ |
|
dvander@31
|
295 |
int32_t publics ; /* offset to the "public functions" table */ |
|
dvander@31
|
296 |
int32_t natives ; /* offset to the "native functions" table */ |
|
dvander@31
|
297 |
int32_t libraries ; /* offset to the table of libraries */ |
|
dvander@31
|
298 |
int32_t pubvars ; /* the "public variables" table */ |
|
dvander@31
|
299 |
int32_t tags ; /* the "public tagnames" table */ |
|
dvander@31
|
300 |
int32_t nametable ; /* name table */ |
|
dvander@27
|
301 |
} AMX_HEADER; |
|
dvander@27
|
302 |
|
|
dvander@27
|
303 |
#if PAWN_CELL_SIZE==16 |
|
dvander@27
|
304 |
#define AMX_MAGIC 0xf1e2 |
|
dvander@27
|
305 |
#elif PAWN_CELL_SIZE==32 |
|
dvander@27
|
306 |
#define AMX_MAGIC 0xf1e0 |
|
dvander@27
|
307 |
#elif PAWN_CELL_SIZE==64 |
|
dvander@27
|
308 |
#define AMX_MAGIC 0xf1e1 |
|
dvander@27
|
309 |
#endif |
|
dvander@27
|
310 |
|
|
dvander@27
|
311 |
enum { |
|
dvander@27
|
312 |
AMX_ERR_NONE, |
|
dvander@27
|
313 |
/* reserve the first 15 error codes for exit codes of the abstract machine */ |
|
dvander@27
|
314 |
AMX_ERR_EXIT, /* forced exit */ |
|
dvander@27
|
315 |
AMX_ERR_ASSERT, /* assertion failed */ |
|
dvander@27
|
316 |
AMX_ERR_STACKERR, /* stack/heap collision */ |
|
dvander@27
|
317 |
AMX_ERR_BOUNDS, /* index out of bounds */ |
|
dvander@27
|
318 |
AMX_ERR_MEMACCESS, /* invalid memory access */ |
|
dvander@27
|
319 |
AMX_ERR_INVINSTR, /* invalid instruction */ |
|
dvander@27
|
320 |
AMX_ERR_STACKLOW, /* stack underflow */ |
|
dvander@27
|
321 |
AMX_ERR_HEAPLOW, /* heap underflow */ |
|
dvander@27
|
322 |
AMX_ERR_CALLBACK, /* no callback, or invalid callback */ |
|
dvander@27
|
323 |
AMX_ERR_NATIVE, /* native function failed */ |
|
dvander@27
|
324 |
AMX_ERR_DIVIDE, /* divide by zero */ |
|
dvander@27
|
325 |
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */ |
|
dvander@27
|
326 |
AMX_ERR_INVSTATE, /* invalid state for this access */ |
|
dvander@27
|
327 |
|
|
dvander@27
|
328 |
AMX_ERR_MEMORY = 16, /* out of memory */ |
|
dvander@27
|
329 |
AMX_ERR_FORMAT, /* invalid file format */ |
|
dvander@27
|
330 |
AMX_ERR_VERSION, /* file is for a newer version of the AMX */ |
|
dvander@27
|
331 |
AMX_ERR_NOTFOUND, /* function not found */ |
|
dvander@27
|
332 |
AMX_ERR_INDEX, /* invalid index parameter (bad entry point) */ |
|
dvander@27
|
333 |
AMX_ERR_DEBUG, /* debugger cannot run */ |
|
dvander@27
|
334 |
AMX_ERR_INIT, /* AMX not initialized (or doubly initialized) */ |
|
dvander@27
|
335 |
AMX_ERR_USERDATA, /* unable to set user data field (table full) */ |
|
dvander@27
|
336 |
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */ |
|
dvander@27
|
337 |
AMX_ERR_PARAMS, /* parameter error */ |
|
dvander@27
|
338 |
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */ |
|
dvander@27
|
339 |
AMX_ERR_GENERAL, /* general error (unknown or unspecific error) */ |
|
dvander@27
|
340 |
}; |
|
dvander@27
|
341 |
|
|
dvander@27
|
342 |
/* AMX_FLAG_CHAR16 0x01 no longer used */ |
|
dvander@27
|
343 |
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */ |
|
dvander@27
|
344 |
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */ |
|
dvander@27
|
345 |
#define AMX_FLAG_SLEEP 0x08 /* script uses the sleep instruction (possible re-entry or power-down mode) */ |
|
dvander@27
|
346 |
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no BREAK opcodes */ |
|
faluco@62
|
347 |
#define AMX_FLAG_SYSREQN 0x800 /* script new (optimized) version of SYSREQ opcode */ |
|
dvander@27
|
348 |
#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */ |
|
dvander@27
|
349 |
#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */ |
|
dvander@27
|
350 |
#define AMX_FLAG_BROWSE 0x4000 /* busy browsing */ |
|
dvander@27
|
351 |
#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */ |
|
dvander@27
|
352 |
|
|
dvander@27
|
353 |
#define AMX_EXEC_MAIN (-1) /* start at program entry point */ |
|
dvander@27
|
354 |
#define AMX_EXEC_CONT (-2) /* continue from last address */ |
|
dvander@27
|
355 |
|
|
dvander@27
|
356 |
#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24)) |
|
dvander@27
|
357 |
|
|
dvander@27
|
358 |
#if !defined AMX_COMPACTMARGIN |
|
dvander@27
|
359 |
#define AMX_COMPACTMARGIN 64 |
|
dvander@27
|
360 |
#endif |
|
dvander@27
|
361 |
|
|
dvander@27
|
362 |
/* for native functions that use floating point parameters, the following |
|
dvander@27
|
363 |
* two macros are convenient for casting a "cell" into a "float" type _without_ |
|
dvander@27
|
364 |
* changing the bit pattern |
|
dvander@27
|
365 |
*/ |
|
dvander@27
|
366 |
#if PAWN_CELL_SIZE==32 |
|
dvander@27
|
367 |
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */ |
|
dvander@27
|
368 |
#define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */ |
|
dvander@27
|
369 |
#elif PAWN_CELL_SIZE==64 |
|
dvander@27
|
370 |
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */ |
|
dvander@27
|
371 |
#define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */ |
|
dvander@27
|
372 |
#else |
|
dvander@27
|
373 |
#error Unsupported cell size |
|
dvander@27
|
374 |
#endif |
|
dvander@27
|
375 |
|
|
dvander@27
|
376 |
#define amx_StrParam(amx,param,result) \ |
|
dvander@27
|
377 |
do { \ |
|
dvander@27
|
378 |
cell *amx_cstr_; int amx_length_; \ |
|
dvander@27
|
379 |
amx_GetAddr((amx), (param), &amx_cstr_); \ |
|
dvander@27
|
380 |
amx_StrLen(amx_cstr_, &amx_length_); \ |
|
dvander@27
|
381 |
if (amx_length_ > 0 && \ |
|
dvander@27
|
382 |
((result) = (void*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \ |
|
dvander@27
|
383 |
amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1, amx_length_ + 1); \ |
|
dvander@27
|
384 |
else (result) = NULL; \ |
|
dvander@27
|
385 |
} while (0) |
|
dvander@27
|
386 |
|
|
dvander@27
|
387 |
uint16_t * AMXAPI amx_Align16(uint16_t *v); |
|
dvander@27
|
388 |
uint32_t * AMXAPI amx_Align32(uint32_t *v); |
|
dvander@27
|
389 |
#if defined _I64_MAX || defined HAVE_I64 |
|
dvander@27
|
390 |
uint64_t * AMXAPI amx_Align64(uint64_t *v); |
|
dvander@27
|
391 |
#endif |
|
dvander@27
|
392 |
int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr); |
|
dvander@27
|
393 |
int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params); |
|
dvander@27
|
394 |
int AMXAPI amx_Cleanup(AMX *amx); |
|
dvander@27
|
395 |
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data); |
|
dvander@27
|
396 |
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index); |
|
dvander@27
|
397 |
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index); |
|
dvander@27
|
398 |
int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index); |
|
dvander@27
|
399 |
int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr); |
|
dvander@27
|
400 |
int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname); |
|
dvander@27
|
401 |
int AMXAPI amx_Flags(AMX *amx,uint16_t *flags); |
|
dvander@27
|
402 |
int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr); |
|
dvander@27
|
403 |
int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname); |
|
dvander@27
|
404 |
int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname); |
|
dvander@27
|
405 |
int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr); |
|
dvander@27
|
406 |
int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar, size_t size); |
|
dvander@27
|
407 |
int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id); |
|
dvander@27
|
408 |
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr); |
|
dvander@27
|
409 |
int AMXAPI amx_Init(AMX *amx, void *program); |
|
dvander@27
|
410 |
int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code); |
|
dvander@27
|
411 |
int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap); |
|
dvander@27
|
412 |
int AMXAPI amx_NameLength(AMX *amx, int *length); |
|
dvander@27
|
413 |
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func); |
|
dvander@27
|
414 |
int AMXAPI amx_NumNatives(AMX *amx, int *number); |
|
dvander@27
|
415 |
int AMXAPI amx_NumPublics(AMX *amx, int *number); |
|
dvander@27
|
416 |
int AMXAPI amx_NumPubVars(AMX *amx, int *number); |
|
dvander@27
|
417 |
int AMXAPI amx_NumTags(AMX *amx, int *number); |
|
dvander@27
|
418 |
int AMXAPI amx_Push(AMX *amx, cell value); |
|
dvander@27
|
419 |
int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells); |
|
dvander@27
|
420 |
int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar); |
|
dvander@27
|
421 |
int AMXAPI amx_RaiseError(AMX *amx, int error); |
|
dvander@27
|
422 |
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number); |
|
dvander@27
|
423 |
int AMXAPI amx_Release(AMX *amx, cell amx_addr); |
|
dvander@27
|
424 |
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback); |
|
dvander@27
|
425 |
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug); |
|
dvander@27
|
426 |
int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size); |
|
dvander@27
|
427 |
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr); |
|
dvander@27
|
428 |
int AMXAPI amx_StrLen(const cell *cstring, int *length); |
|
dvander@27
|
429 |
int AMXAPI amx_UTF8Check(const char *string, int *length); |
|
dvander@27
|
430 |
int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value); |
|
dvander@27
|
431 |
int AMXAPI amx_UTF8Len(const cell *cstr, int *length); |
|
dvander@27
|
432 |
int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value); |
|
dvander@27
|
433 |
|
|
dvander@27
|
434 |
#if PAWN_CELL_SIZE==16 |
|
dvander@27
|
435 |
#define amx_AlignCell(v) amx_Align16(v) |
|
dvander@27
|
436 |
#elif PAWN_CELL_SIZE==32 |
|
dvander@27
|
437 |
#define amx_AlignCell(v) amx_Align32(v) |
|
dvander@27
|
438 |
#elif PAWN_CELL_SIZE==64 && (defined _I64_MAX || defined HAVE_I64) |
|
dvander@27
|
439 |
#define amx_AlignCell(v) amx_Align64(v) |
|
dvander@27
|
440 |
#else |
|
dvander@27
|
441 |
#error Unsupported cell size |
|
dvander@27
|
442 |
#endif |
|
dvander@27
|
443 |
|
|
dvander@27
|
444 |
#define amx_RegisterFunc(amx, name, func) \ |
|
dvander@27
|
445 |
amx_Register((amx), amx_NativeInfo((name),(func)), 1); |
|
dvander@27
|
446 |
|
|
dvander@27
|
447 |
#if !defined AMX_NO_ALIGN |
|
dvander@27
|
448 |
#if defined LINUX || defined __FreeBSD__ |
|
dvander@27
|
449 |
#pragma pack() /* reset default packing */ |
|
dvander@27
|
450 |
#elif defined MACOS && defined __MWERKS__ |
|
dvander@27
|
451 |
#pragma options align=reset |
|
dvander@27
|
452 |
#else |
|
dvander@27
|
453 |
#pragma pack(pop) /* reset previous packing */ |
|
dvander@27
|
454 |
#endif |
|
dvander@27
|
455 |
#endif |
|
dvander@27
|
456 |
|
|
dvander@27
|
457 |
#ifdef __cplusplus |
|
dvander@27
|
458 |
} |
|
dvander@27
|
459 |
#endif |
|
dvander@27
|
460 |
|
|
dvander@27
|
461 |
typedef enum { |
|
dvander@27
|
462 |
OP_NONE, /* invalid opcode */ |
|
dvander@27
|
463 |
OP_LOAD_PRI, |
|
dvander@27
|
464 |
OP_LOAD_ALT, |
|
dvander@27
|
465 |
OP_LOAD_S_PRI, |
|
dvander@27
|
466 |
OP_LOAD_S_ALT, |
|
dvander@27
|
467 |
OP_LREF_PRI, |
|
dvander@27
|
468 |
OP_LREF_ALT, |
|
dvander@27
|
469 |
OP_LREF_S_PRI, |
|
dvander@27
|
470 |
OP_LREF_S_ALT, |
|
dvander@27
|
471 |
OP_LOAD_I, |
|
dvander@27
|
472 |
OP_LODB_I, |
|
dvander@27
|
473 |
OP_CONST_PRI, |
|
dvander@27
|
474 |
OP_CONST_ALT, |
|
dvander@27
|
475 |
OP_ADDR_PRI, |
|
dvander@27
|
476 |
OP_ADDR_ALT, |
|
dvander@27
|
477 |
OP_STOR_PRI, |
|
dvander@27
|
478 |
OP_STOR_ALT, |
|
dvander@27
|
479 |
OP_STOR_S_PRI, |
|
dvander@27
|
480 |
OP_STOR_S_ALT, |
|
dvander@27
|
481 |
OP_SREF_PRI, |
|
dvander@27
|
482 |
OP_SREF_ALT, |
|
dvander@27
|
483 |
OP_SREF_S_PRI, |
|
dvander@27
|
484 |
OP_SREF_S_ALT, |
|
dvander@27
|
485 |
OP_STOR_I, |
|
dvander@27
|
486 |
OP_STRB_I, |
|
dvander@27
|
487 |
OP_LIDX, |
|
dvander@27
|
488 |
OP_LIDX_B, |
|
dvander@27
|
489 |
OP_IDXADDR, |
|
dvander@27
|
490 |
OP_IDXADDR_B, |
|
dvander@27
|
491 |
OP_ALIGN_PRI, |
|
dvander@27
|
492 |
OP_ALIGN_ALT, |
|
dvander@27
|
493 |
OP_LCTRL, |
|
dvander@27
|
494 |
OP_SCTRL, |
|
dvander@27
|
495 |
OP_MOVE_PRI, |
|
dvander@27
|
496 |
OP_MOVE_ALT, |
|
dvander@27
|
497 |
OP_XCHG, |
|
dvander@27
|
498 |
OP_PUSH_PRI, |
|
dvander@27
|
499 |
OP_PUSH_ALT, |
|
dvander@27
|
500 |
OP_PUSH_R, |
|
dvander@27
|
501 |
OP_PUSH_C, |
|
dvander@27
|
502 |
OP_PUSH, |
|
dvander@27
|
503 |
OP_PUSH_S, |
|
dvander@27
|
504 |
OP_POP_PRI, |
|
dvander@27
|
505 |
OP_POP_ALT, |
|
dvander@27
|
506 |
OP_STACK, |
|
dvander@27
|
507 |
OP_HEAP, |
|
dvander@27
|
508 |
OP_PROC, |
|
dvander@27
|
509 |
OP_RET, |
|
dvander@27
|
510 |
OP_RETN, |
|
dvander@27
|
511 |
OP_CALL, |
|
dvander@27
|
512 |
OP_CALL_PRI, |
|
dvander@27
|
513 |
OP_JUMP, |
|
dvander@27
|
514 |
OP_JREL, |
|
dvander@27
|
515 |
OP_JZER, |
|
dvander@27
|
516 |
OP_JNZ, |
|
dvander@27
|
517 |
OP_JEQ, |
|
dvander@27
|
518 |
OP_JNEQ, |
|
dvander@27
|
519 |
OP_JLESS, |
|
dvander@27
|
520 |
OP_JLEQ, |
|
dvander@27
|
521 |
OP_JGRTR, |
|
dvander@27
|
522 |
OP_JGEQ, |
|
dvander@27
|
523 |
OP_JSLESS, |
|
dvander@27
|
524 |
OP_JSLEQ, |
|
dvander@27
|
525 |
OP_JSGRTR, |
|
dvander@27
|
526 |
OP_JSGEQ, |
|
dvander@27
|
527 |
OP_SHL, |
|
dvander@27
|
528 |
OP_SHR, |
|
dvander@27
|
529 |
OP_SSHR, |
|
dvander@27
|
530 |
OP_SHL_C_PRI, |
|
dvander@27
|
531 |
OP_SHL_C_ALT, |
|
dvander@27
|
532 |
OP_SHR_C_PRI, |
|
dvander@27
|
533 |
OP_SHR_C_ALT, |
|
dvander@27
|
534 |
OP_SMUL, |
|
dvander@27
|
535 |
OP_SDIV, |
|
dvander@27
|
536 |
OP_SDIV_ALT, |
|
dvander@27
|
537 |
OP_UMUL, |
|
dvander@27
|
538 |
OP_UDIV, |
|
dvander@27
|
539 |
OP_UDIV_ALT, |
|
dvander@27
|
540 |
OP_ADD, |
|
dvander@27
|
541 |
OP_SUB, |
|
dvander@27
|
542 |
OP_SUB_ALT, |
|
dvander@27
|
543 |
OP_AND, |
|
dvander@27
|
544 |
OP_OR, |
|
dvander@27
|
545 |
OP_XOR, |
|
dvander@27
|
546 |
OP_NOT, |
|
dvander@27
|
547 |
OP_NEG, |
|
dvander@27
|
548 |
OP_INVERT, |
|
dvander@27
|
549 |
OP_ADD_C, |
|
dvander@27
|
550 |
OP_SMUL_C, |
|
dvander@27
|
551 |
OP_ZERO_PRI, |
|
dvander@27
|
552 |
OP_ZERO_ALT, |
|
dvander@27
|
553 |
OP_ZERO, |
|
dvander@27
|
554 |
OP_ZERO_S, |
|
dvander@27
|
555 |
OP_SIGN_PRI, |
|
dvander@27
|
556 |
OP_SIGN_ALT, |
|
dvander@27
|
557 |
OP_EQ, |
|
dvander@27
|
558 |
OP_NEQ, |
|
dvander@27
|
559 |
OP_LESS, |
|
dvander@27
|
560 |
OP_LEQ, |
|
dvander@27
|
561 |
OP_GRTR, |
|
dvander@27
|
562 |
OP_GEQ, |
|
dvander@27
|
563 |
OP_SLESS, |
|
dvander@27
|
564 |
OP_SLEQ, |
|
dvander@27
|
565 |
OP_SGRTR, |
|
dvander@27
|
566 |
OP_SGEQ, |
|
dvander@27
|
567 |
OP_EQ_C_PRI, |
|
dvander@27
|
568 |
OP_EQ_C_ALT, |
|
dvander@27
|
569 |
OP_INC_PRI, |
|
dvander@27
|
570 |
OP_INC_ALT, |
|
dvander@27
|
571 |
OP_INC, |
|
dvander@27
|
572 |
OP_INC_S, |
|
dvander@27
|
573 |
OP_INC_I, |
|
dvander@27
|
574 |
OP_DEC_PRI, |
|
dvander@27
|
575 |
OP_DEC_ALT, |
|
dvander@27
|
576 |
OP_DEC, |
|
dvander@27
|
577 |
OP_DEC_S, |
|
dvander@27
|
578 |
OP_DEC_I, |
|
dvander@27
|
579 |
OP_MOVS, |
|
dvander@27
|
580 |
OP_CMPS, |
|
dvander@27
|
581 |
OP_FILL, |
|
dvander@27
|
582 |
OP_HALT, |
|
dvander@27
|
583 |
OP_BOUNDS, |
|
dvander@27
|
584 |
OP_SYSREQ_PRI, |
|
dvander@27
|
585 |
OP_SYSREQ_C, |
|
dvander@27
|
586 |
OP_FILE, /* obsolete */ |
|
dvander@27
|
587 |
OP_LINE, /* obsolete */ |
|
dvander@27
|
588 |
OP_SYMBOL, /* obsolete */ |
|
dvander@27
|
589 |
OP_SRANGE, /* obsolete */ |
|
dvander@27
|
590 |
OP_JUMP_PRI, |
|
dvander@27
|
591 |
OP_SWITCH, |
|
dvander@27
|
592 |
OP_CASETBL, |
|
dvander@27
|
593 |
OP_SWAP_PRI, |
|
dvander@27
|
594 |
OP_SWAP_ALT, |
|
dvander@27
|
595 |
OP_PUSH_ADR, |
|
dvander@27
|
596 |
OP_NOP, |
|
dvander@27
|
597 |
OP_SYSREQ_N, |
|
dvander@27
|
598 |
OP_SYMTAG, /* obsolete */ |
|
dvander@27
|
599 |
OP_BREAK, |
|
dvander@27
|
600 |
OP_PUSH2_C, |
|
dvander@27
|
601 |
OP_PUSH2, |
|
dvander@27
|
602 |
OP_PUSH2_S, |
|
dvander@27
|
603 |
OP_PUSH2_ADR, |
|
dvander@27
|
604 |
OP_PUSH3_C, |
|
dvander@27
|
605 |
OP_PUSH3, |
|
dvander@27
|
606 |
OP_PUSH3_S, |
|
dvander@27
|
607 |
OP_PUSH3_ADR, |
|
dvander@27
|
608 |
OP_PUSH4_C, |
|
dvander@27
|
609 |
OP_PUSH4, |
|
dvander@27
|
610 |
OP_PUSH4_S, |
|
dvander@27
|
611 |
OP_PUSH4_ADR, |
|
dvander@27
|
612 |
OP_PUSH5_C, |
|
dvander@27
|
613 |
OP_PUSH5, |
|
dvander@27
|
614 |
OP_PUSH5_S, |
|
dvander@27
|
615 |
OP_PUSH5_ADR, |
|
dvander@27
|
616 |
OP_LOAD_BOTH, |
|
dvander@27
|
617 |
OP_LOAD_S_BOTH, |
|
dvander@27
|
618 |
OP_CONST, |
|
dvander@27
|
619 |
OP_CONST_S, |
|
dvander@27
|
620 |
/* ----- */ |
|
dvander@27
|
621 |
OP_SYSREQ_D, |
|
dvander@27
|
622 |
OP_SYSREQ_ND, |
|
dvander@27
|
623 |
/* ----- */ |
|
dvander@64
|
624 |
OP_HEAP_I, |
|
dvander@119
|
625 |
OP_PUSH_H_C, |
|
dvander@119
|
626 |
OP_GENARRAY, |
|
dvander@27
|
627 |
OP_NUM_OPCODES |
|
dvander@27
|
628 |
} OPCODE; |
|
dvander@27
|
629 |
|
|
dvander@27
|
630 |
#endif /* AMX_H_INCLUDED */ |