1 #ifndef _EMBRYO_PRIVATE_H
2 #define _EMBRYO_PRIVATE_H
7 // BROKEN in gcc 4 on amd64
8 //# pragma GCC visibility push(hidden)
12 typedef enum _Embryo_Opcode Embryo_Opcode;
138 EMBRYO_OP_SYSREQ_PRI,
154 EMBRYO_OP_NUM_OPCODES
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))) \
171 # define GETENTRYNAME(hdr, entry) \
172 (((hdr)->defsize == 2 * sizeof(unsigned int)) \
173 ? (char *)((unsigned char*)(hdr) + *((unsigned int *)(entry) + 1)) \
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);
197 typedef struct _Embryo_Param Embryo_Param;
198 typedef struct _Embryo_Header Embryo_Header;
199 typedef struct _Embryo_Func_Stub Embryo_Func_Stub;
201 typedef Embryo_Cell (*Embryo_Native)(Embryo_Program *ep, Embryo_Cell *params);
206 Embryo_Cell *cell_array;
211 struct _Embryo_Program
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 */
225 /* the sleep opcode needs to store the full Embryo_Program status */
228 Embryo_Cell reset_stk;
229 Embryo_Cell reset_hea;
230 Embryo_Cell *syscall_d; /* relocated value/address for the SYSCALL.D opcode */
233 Embryo_Native *native_calls;
234 int native_calls_size;
235 int native_calls_alloc;
238 unsigned char dont_free_code : 1;
241 Embryo_Param *params;
252 #if defined (_MSC_VER) || (defined (__SUNPRO_C) && __SUNPRO_C < 0x5100)
254 # define EMBRYO_STRUCT_PACKED
255 #elif defined (__GNUC__) || (defined (__SUNPRO_C) && __SUNPRO_C >= 0x5100)
256 # define EMBRYO_STRUCT_PACKED __attribute__((packed))
258 # define EMBRYO_STRUCT_PACKED
261 struct _Embryo_Func_Stub
264 char name[sEXPMAX+1];
265 } EMBRYO_STRUCT_PACKED;
267 struct _Embryo_Header
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 */
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;
288 #if defined _MSC_VER || (defined (__SUNPRO_C) && __SUNPRO_C < 0x5100)
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);