aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/embryo/src/lib/embryo_private.h
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/embryo/src/lib/embryo_private.h')
-rw-r--r--libraries/embryo/src/lib/embryo_private.h298
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
12typedef enum _Embryo_Opcode Embryo_Opcode;
13
14enum _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
163static 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
197typedef struct _Embryo_Param Embryo_Param;
198typedef struct _Embryo_Header Embryo_Header;
199typedef struct _Embryo_Func_Stub Embryo_Func_Stub;
200
201typedef Embryo_Cell (*Embryo_Native)(Embryo_Program *ep, Embryo_Cell *params);
202
203struct _Embryo_Param
204{
205 char *string;
206 Embryo_Cell *cell_array;
207 int cell_array_size;
208 Embryo_Cell cell;
209};
210
211struct _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
261struct _Embryo_Func_Stub
262{
263 int address;
264 char name[sEXPMAX+1];
265} EMBRYO_STRUCT_PACKED;
266
267struct _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
292void _embryo_args_init(Embryo_Program *ep);
293void _embryo_fp_init(Embryo_Program *ep);
294void _embryo_rand_init(Embryo_Program *ep);
295void _embryo_str_init(Embryo_Program *ep);
296void _embryo_time_init(Embryo_Program *ep);
297
298#endif