diff options
Diffstat (limited to 'libraries/embryo/src/lib/embryo_private.h')
-rw-r--r-- | libraries/embryo/src/lib/embryo_private.h | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/libraries/embryo/src/lib/embryo_private.h b/libraries/embryo/src/lib/embryo_private.h new file mode 100644 index 0000000..a4205e1 --- /dev/null +++ b/libraries/embryo/src/lib/embryo_private.h | |||
@@ -0,0 +1,298 @@ | |||
1 | #ifndef _EMBRYO_PRIVATE_H | ||
2 | #define _EMBRYO_PRIVATE_H | ||
3 | |||
4 | |||
5 | #ifdef __GNUC__ | ||
6 | # if __GNUC__ >= 4 | ||
7 | // BROKEN in gcc 4 on amd64 | ||
8 | //# pragma GCC visibility push(hidden) | ||
9 | # endif | ||
10 | #endif | ||
11 | |||
12 | typedef enum _Embryo_Opcode Embryo_Opcode; | ||
13 | |||
14 | enum _Embryo_Opcode | ||
15 | { | ||
16 | EMBRYO_OP_NONE, | ||
17 | EMBRYO_OP_LOAD_PRI, | ||
18 | EMBRYO_OP_LOAD_ALT, | ||
19 | EMBRYO_OP_LOAD_S_PRI, | ||
20 | EMBRYO_OP_LOAD_S_ALT, | ||
21 | EMBRYO_OP_LREF_PRI, | ||
22 | EMBRYO_OP_LREF_ALT, | ||
23 | EMBRYO_OP_LREF_S_PRI, | ||
24 | EMBRYO_OP_LREF_S_ALT, | ||
25 | EMBRYO_OP_LOAD_I, | ||
26 | EMBRYO_OP_LODB_I, | ||
27 | EMBRYO_OP_CONST_PRI, | ||
28 | EMBRYO_OP_CONST_ALT, | ||
29 | EMBRYO_OP_ADDR_PRI, | ||
30 | EMBRYO_OP_ADDR_ALT, | ||
31 | EMBRYO_OP_STOR_PRI, | ||
32 | EMBRYO_OP_STOR_ALT, | ||
33 | EMBRYO_OP_STOR_S_PRI, | ||
34 | EMBRYO_OP_STOR_S_ALT, | ||
35 | EMBRYO_OP_SREF_PRI, | ||
36 | EMBRYO_OP_SREF_ALT, | ||
37 | EMBRYO_OP_SREF_S_PRI, | ||
38 | EMBRYO_OP_SREF_S_ALT, | ||
39 | EMBRYO_OP_STOR_I, | ||
40 | EMBRYO_OP_STRB_I, | ||
41 | EMBRYO_OP_LIDX, | ||
42 | EMBRYO_OP_LIDX_B, | ||
43 | EMBRYO_OP_IDXADDR, | ||
44 | EMBRYO_OP_IDXADDR_B, | ||
45 | EMBRYO_OP_ALIGN_PRI, | ||
46 | EMBRYO_OP_ALIGN_ALT, | ||
47 | EMBRYO_OP_LCTRL, | ||
48 | EMBRYO_OP_SCTRL, | ||
49 | EMBRYO_OP_MOVE_PRI, | ||
50 | EMBRYO_OP_MOVE_ALT, | ||
51 | EMBRYO_OP_XCHG, | ||
52 | EMBRYO_OP_PUSH_PRI, | ||
53 | EMBRYO_OP_PUSH_ALT, | ||
54 | EMBRYO_OP_PUSH_R, | ||
55 | EMBRYO_OP_PUSH_C, | ||
56 | EMBRYO_OP_PUSH, | ||
57 | EMBRYO_OP_PUSH_S, | ||
58 | EMBRYO_OP_POP_PRI, | ||
59 | EMBRYO_OP_POP_ALT, | ||
60 | EMBRYO_OP_STACK, | ||
61 | EMBRYO_OP_HEAP, | ||
62 | EMBRYO_OP_PROC, | ||
63 | EMBRYO_OP_RET, | ||
64 | EMBRYO_OP_RETN, | ||
65 | EMBRYO_OP_CALL, | ||
66 | EMBRYO_OP_CALL_PRI, | ||
67 | EMBRYO_OP_JUMP, | ||
68 | EMBRYO_OP_JREL, | ||
69 | EMBRYO_OP_JZER, | ||
70 | EMBRYO_OP_JNZ, | ||
71 | EMBRYO_OP_JEQ, | ||
72 | EMBRYO_OP_JNEQ, | ||
73 | EMBRYO_OP_JLESS, | ||
74 | EMBRYO_OP_JLEQ, | ||
75 | EMBRYO_OP_JGRTR, | ||
76 | EMBRYO_OP_JGEQ, | ||
77 | EMBRYO_OP_JSLESS, | ||
78 | EMBRYO_OP_JSLEQ, | ||
79 | EMBRYO_OP_JSGRTR, | ||
80 | EMBRYO_OP_JSGEQ, | ||
81 | EMBRYO_OP_SHL, | ||
82 | EMBRYO_OP_SHR, | ||
83 | EMBRYO_OP_SSHR, | ||
84 | EMBRYO_OP_SHL_C_PRI, | ||
85 | EMBRYO_OP_SHL_C_ALT, | ||
86 | EMBRYO_OP_SHR_C_PRI, | ||
87 | EMBRYO_OP_SHR_C_ALT, | ||
88 | EMBRYO_OP_SMUL, | ||
89 | EMBRYO_OP_SDIV, | ||
90 | EMBRYO_OP_SDIV_ALT, | ||
91 | EMBRYO_OP_UMUL, | ||
92 | EMBRYO_OP_UDIV, | ||
93 | EMBRYO_OP_UDIV_ALT, | ||
94 | EMBRYO_OP_ADD, | ||
95 | EMBRYO_OP_SUB, | ||
96 | EMBRYO_OP_SUB_ALT, | ||
97 | EMBRYO_OP_AND, | ||
98 | EMBRYO_OP_OR, | ||
99 | EMBRYO_OP_XOR, | ||
100 | EMBRYO_OP_NOT, | ||
101 | EMBRYO_OP_NEG, | ||
102 | EMBRYO_OP_INVERT, | ||
103 | EMBRYO_OP_ADD_C, | ||
104 | EMBRYO_OP_SMUL_C, | ||
105 | EMBRYO_OP_ZERO_PRI, | ||
106 | EMBRYO_OP_ZERO_ALT, | ||
107 | EMBRYO_OP_ZERO, | ||
108 | EMBRYO_OP_ZERO_S, | ||
109 | EMBRYO_OP_SIGN_PRI, | ||
110 | EMBRYO_OP_SIGN_ALT, | ||
111 | EMBRYO_OP_EQ, | ||
112 | EMBRYO_OP_NEQ, | ||
113 | EMBRYO_OP_LESS, | ||
114 | EMBRYO_OP_LEQ, | ||
115 | EMBRYO_OP_GRTR, | ||
116 | EMBRYO_OP_GEQ, | ||
117 | EMBRYO_OP_SLESS, | ||
118 | EMBRYO_OP_SLEQ, | ||
119 | EMBRYO_OP_SGRTR, | ||
120 | EMBRYO_OP_SGEQ, | ||
121 | EMBRYO_OP_EQ_C_PRI, | ||
122 | EMBRYO_OP_EQ_C_ALT, | ||
123 | EMBRYO_OP_INC_PRI, | ||
124 | EMBRYO_OP_INC_ALT, | ||
125 | EMBRYO_OP_INC, | ||
126 | EMBRYO_OP_INC_S, | ||
127 | EMBRYO_OP_INC_I, | ||
128 | EMBRYO_OP_DEC_PRI, | ||
129 | EMBRYO_OP_DEC_ALT, | ||
130 | EMBRYO_OP_DEC, | ||
131 | EMBRYO_OP_DEC_S, | ||
132 | EMBRYO_OP_DEC_I, | ||
133 | EMBRYO_OP_MOVS, | ||
134 | EMBRYO_OP_CMPS, | ||
135 | EMBRYO_OP_FILL, | ||
136 | EMBRYO_OP_HALT, | ||
137 | EMBRYO_OP_BOUNDS, | ||
138 | EMBRYO_OP_SYSREQ_PRI, | ||
139 | EMBRYO_OP_SYSREQ_C, | ||
140 | EMBRYO_OP_FILE, | ||
141 | EMBRYO_OP_LINE, | ||
142 | EMBRYO_OP_SYMBOL, | ||
143 | EMBRYO_OP_SRANGE, | ||
144 | EMBRYO_OP_JUMP_PRI, | ||
145 | EMBRYO_OP_SWITCH, | ||
146 | EMBRYO_OP_CASETBL, | ||
147 | EMBRYO_OP_SWAP_PRI, | ||
148 | EMBRYO_OP_SWAP_ALT, | ||
149 | EMBRYO_OP_PUSHADDR, | ||
150 | EMBRYO_OP_NOP, | ||
151 | EMBRYO_OP_SYSREQ_D, | ||
152 | EMBRYO_OP_SYMTAG, | ||
153 | /* ----- */ | ||
154 | EMBRYO_OP_NUM_OPCODES | ||
155 | }; | ||
156 | |||
157 | #define NUMENTRIES(hdr, field, nextfield) \ | ||
158 | (int)(((hdr)->nextfield - (hdr)->field) / (hdr)->defsize) | ||
159 | #define GETENTRY(hdr, table, index) \ | ||
160 | (Embryo_Func_Stub *)((unsigned char*)(hdr) + \ | ||
161 | (int)(hdr)->table + index * (hdr)->defsize) | ||
162 | #ifdef WORDS_BIGENDIAN | ||
163 | static int __inline __entryswap32(int v) | ||
164 | {int vv; vv = v; embryo_swap_32((unsigned int *)&vv); return vv;} | ||
165 | # define GETENTRYNAME(hdr, entry) \ | ||
166 | (((hdr)->defsize == 2 * sizeof(unsigned int)) \ | ||
167 | ? (char *)((unsigned char*)(hdr) + \ | ||
168 | __entryswap32(*((unsigned int *)(entry) + 1))) \ | ||
169 | : (entry)->name) | ||
170 | #else | ||
171 | # define GETENTRYNAME(hdr, entry) \ | ||
172 | (((hdr)->defsize == 2 * sizeof(unsigned int)) \ | ||
173 | ? (char *)((unsigned char*)(hdr) + *((unsigned int *)(entry) + 1)) \ | ||
174 | : (entry)->name) | ||
175 | #endif | ||
176 | |||
177 | #define CUR_FILE_VERSION 7 /* current file version; also the current Embryo_Program version */ | ||
178 | #define MIN_FILE_VERSION 7 /* lowest supported file format version for the current Embryo_Program version */ | ||
179 | #define MIN_AMX_VERSION 7 /* minimum Embryo_Program version needed to support the current file format */ | ||
180 | #define sEXPMAX 19 /* maximum name length for file version <= 6 */ | ||
181 | #define sNAMEMAX 31 /* maximum name length of symbol name */ | ||
182 | #define EMBRYO_MAGIC 0xf1e0 /* magic byte pattern */ | ||
183 | #define EMBRYO_FLAG_COMPACT 0x04 /* compact encoding */ | ||
184 | #define EMBRYO_FLAG_RELOC 0x8000 /* jump/call addresses relocated */ | ||
185 | #define GETPARAM(v) (v = *(Embryo_Cell *)cip++) | ||
186 | #define PUSH(v) (stk -= sizeof(Embryo_Cell), *(Embryo_Cell *)(data + (int)stk) = v) | ||
187 | #define POP(v) (v = *(Embryo_Cell *)(data + (int)stk), stk += sizeof(Embryo_Cell)) | ||
188 | #define ABORT(ep,v) {(ep)->stk = reset_stk; (ep)->hea = reset_hea; (ep)->run_count--; ep->error = v; (ep)->max_run_cycles = max_run_cycles; return EMBRYO_PROGRAM_FAIL;} | ||
189 | #define OK(ep,v) {(ep)->stk = reset_stk; (ep)->hea = reset_hea; (ep)->run_count--; ep->error = v; (ep)->max_run_cycles = max_run_cycles; return EMBRYO_PROGRAM_OK;} | ||
190 | #define TOOLONG(ep) {(ep)->pri = pri; (ep)->cip = (Embryo_Cell)((unsigned char *)cip - code); (ep)->alt = alt; (ep)->frm = frm; (ep)->stk = stk; (ep)->hea = hea; (ep)->reset_stk = reset_stk; (ep)->reset_hea = reset_hea; (ep)->run_count--; (ep)->max_run_cycles = max_run_cycles; return EMBRYO_PROGRAM_TOOLONG;} | ||
191 | #define STKMARGIN ((Embryo_Cell)(16 * sizeof(Embryo_Cell))) | ||
192 | #define CHKMARGIN() if ((hea + STKMARGIN) > stk) {ep->error = EMBRYO_ERROR_STACKERR; return 0;} | ||
193 | #define CHKSTACK() if (stk > ep->stp) {ep->run_count--; ep->error = EMBRYO_ERROR_STACKLOW; return 0;} | ||
194 | #define CHKHEAP() if (hea < ep->hlw) {ep->run_count--; ep->error = EMBRYO_ERROR_HEAPLOW; return 0;} | ||
195 | #define CHKMEM(x) if ((((x) >= hea) && ((x) < stk)) || ((Embryo_UCell)(x) >= (Embryo_UCell)ep->stp)) ABORT(ep, EMBRYO_ERROR_MEMACCESS); | ||
196 | |||
197 | typedef struct _Embryo_Param Embryo_Param; | ||
198 | typedef struct _Embryo_Header Embryo_Header; | ||
199 | typedef struct _Embryo_Func_Stub Embryo_Func_Stub; | ||
200 | |||
201 | typedef Embryo_Cell (*Embryo_Native)(Embryo_Program *ep, Embryo_Cell *params); | ||
202 | |||
203 | struct _Embryo_Param | ||
204 | { | ||
205 | char *string; | ||
206 | Embryo_Cell *cell_array; | ||
207 | int cell_array_size; | ||
208 | Embryo_Cell cell; | ||
209 | }; | ||
210 | |||
211 | struct _Embryo_Program | ||
212 | { | ||
213 | unsigned char *base; /* points to the Embryo_Program header ("ephdr") plus the code, optionally also the data */ | ||
214 | int pushes; /* number of pushes - pops */ | ||
215 | /* for external functions a few registers must be accessible from the outside */ | ||
216 | Embryo_Cell cip; /* instruction pointer: relative to base + ephdr->cod */ | ||
217 | Embryo_Cell frm; /* stack frame base: relative to base + ephdr->dat */ | ||
218 | Embryo_Cell hea; /* top of the heap: relative to base + ephdr->dat */ | ||
219 | Embryo_Cell hlw; /* bottom of the heap: relative to base + ephdr->dat */ | ||
220 | Embryo_Cell stk; /* stack pointer: relative to base + ephdr->dat */ | ||
221 | Embryo_Cell stp; /* top of the stack: relative to base + ephdr->dat */ | ||
222 | int flags; /* current status */ | ||
223 | /* native functions can raise an error */ | ||
224 | int error; | ||
225 | /* the sleep opcode needs to store the full Embryo_Program status */ | ||
226 | Embryo_Cell pri; | ||
227 | Embryo_Cell alt; | ||
228 | Embryo_Cell reset_stk; | ||
229 | Embryo_Cell reset_hea; | ||
230 | Embryo_Cell *syscall_d; /* relocated value/address for the SYSCALL.D opcode */ | ||
231 | |||
232 | /* extended stuff */ | ||
233 | Embryo_Native *native_calls; | ||
234 | int native_calls_size; | ||
235 | int native_calls_alloc; | ||
236 | |||
237 | unsigned char *code; | ||
238 | unsigned char dont_free_code : 1; | ||
239 | Embryo_Cell retval; | ||
240 | |||
241 | Embryo_Param *params; | ||
242 | int params_size; | ||
243 | int params_alloc; | ||
244 | |||
245 | int run_count; | ||
246 | |||
247 | int max_run_cycles; | ||
248 | |||
249 | void *data; | ||
250 | }; | ||
251 | |||
252 | #if defined (_MSC_VER) || (defined (__SUNPRO_C) && __SUNPRO_C < 0x5100) | ||
253 | # pragma pack(1) | ||
254 | # define EMBRYO_STRUCT_PACKED | ||
255 | #elif defined (__GNUC__) || (defined (__SUNPRO_C) && __SUNPRO_C >= 0x5100) | ||
256 | # define EMBRYO_STRUCT_PACKED __attribute__((packed)) | ||
257 | #else | ||
258 | # define EMBRYO_STRUCT_PACKED | ||
259 | #endif | ||
260 | |||
261 | struct _Embryo_Func_Stub | ||
262 | { | ||
263 | int address; | ||
264 | char name[sEXPMAX+1]; | ||
265 | } EMBRYO_STRUCT_PACKED; | ||
266 | |||
267 | struct _Embryo_Header | ||
268 | { | ||
269 | unsigned int size; /* size of the "file" */ | ||
270 | unsigned short magic; /* signature */ | ||
271 | char file_version; /* file format version */ | ||
272 | char ep_version; /* required version of the Embryo_Program */ | ||
273 | short flags; | ||
274 | short defsize; /* size of a definition record */ | ||
275 | int cod; /* initial value of COD - code block */ | ||
276 | int dat; /* initial value of DAT - data block */ | ||
277 | int hea; /* initial value of HEA - start of the heap */ | ||
278 | int stp; /* initial value of STP - stack top */ | ||
279 | int cip; /* initial value of CIP - the instruction pointer */ | ||
280 | int publics; /* offset to the "public functions" table */ | ||
281 | int natives; /* offset to the "native functions" table */ | ||
282 | int libraries; /* offset to the table of libraries */ | ||
283 | int pubvars; /* the "public variables" table */ | ||
284 | int tags; /* the "public tagnames" table */ | ||
285 | int nametable; /* name table, file version 7 only */ | ||
286 | } EMBRYO_STRUCT_PACKED; | ||
287 | |||
288 | #if defined _MSC_VER || (defined (__SUNPRO_C) && __SUNPRO_C < 0x5100) | ||
289 | # pragma pack() | ||
290 | #endif | ||
291 | |||
292 | void _embryo_args_init(Embryo_Program *ep); | ||
293 | void _embryo_fp_init(Embryo_Program *ep); | ||
294 | void _embryo_rand_init(Embryo_Program *ep); | ||
295 | void _embryo_str_init(Embryo_Program *ep); | ||
296 | void _embryo_time_init(Embryo_Program *ep); | ||
297 | |||
298 | #endif | ||