comparison keiko/obx.h @ 0:bfdcc3820b32

Basis
author Mike Spivey <mike@cs.ox.ac.uk>
date Thu, 05 Oct 2017 08:04:15 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:bfdcc3820b32
1 /*
2 * obx.h
3 *
4 * This file is part of the Oxford Oberon-2 compiler
5 * Copyright (c) 2006--2016 J. M. Spivey
6 * All rights reserved
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef _OBX_H
32 #define _OBX_H 1
33
34 #ifdef TRACE
35 #define DEBUG 1
36 #endif
37
38 #include "config.h"
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <stdarg.h>
43 #ifdef HAVE_UNISTD_H
44 #include <unistd.h>
45 #endif
46 #include "obcommon.h"
47
48 #define SLIMIT 256 /* Min stack space space left (bytes) */
49
50 typedef union value value;
51
52 typedef void primitive(value *sp);
53
54 typedef uint32_t word;
55 typedef uintptr_t ptrtype;
56
57 union value {
58 int i;
59 float f;
60 word a;
61 };
62
63 #define valptr(v) ((value *) (ptrtype) ((v).a))
64 #define pointer(v) ((void *) (ptrtype) ((v).a))
65
66 #define address(p) ((word) (ptrtype) (p))
67 #define ptrcast(t, a) ((t *) (ptrtype) (a))
68
69 typedef struct _proc *proc;
70 typedef struct _module *module;
71 typedef struct _arc *arc;
72
73 #ifdef PROFILE
74 typedef uint64_t counter;
75 #endif
76
77 struct _proc {
78 const char *p_name; /* Procedure name */
79 value *p_addr; /* Address of descriptor in data space */
80 #ifdef PROFILE
81 int p_index; /* Position in listing */
82 unsigned p_calls; /* Call count */
83 unsigned p_rec; /* Call count for recursion */
84 counter p_self; /* Tick count for self */
85 counter p_child; /* Tick count for children */
86 arc p_parents; /* List of callers */
87 arc p_children; /* List of procs we call */
88 #endif
89 };
90
91 struct _module {
92 char *m_name; /* Layout must match proc */
93 uchar *m_addr;
94 int m_length;
95 #ifdef PROFILE
96 int m_nlines;
97 unsigned *m_lcount;
98 #endif
99 };
100
101
102 /* Global variables */
103 EXTERN uchar *imem, *dmem; /* Instruction and data memory arrays */
104 EXTERN uchar *stack; /* Program stack */
105 EXTERN int code_size; /* Size of program code */
106 EXTERN int stack_size; /* Size of main stack */
107 EXTERN char *libpath; /* Path to dynamic library */
108 EXTERN value *entry; /* Program entry point */
109 EXTERN value *gcmap; /* Global pointer map */
110 EXTERN word interpreter, dyntrap;
111 #ifdef USEFFI
112 EXTERN word dynstub;
113 #endif
114
115 #define interpreted(p) ((p)[CP_PRIM].a == interpreter)
116
117 #ifndef M64X32
118 #define primcall(p, sp) ((primitive *) p[CP_PRIM].a)(sp)
119 #else
120 #define primcall(p, sp) (*ptrcast(primitive *, p[CP_PRIM].a))(sp)
121 #endif
122
123 #define get1(p) ((int) ((signed char) (p)[0]))
124 #define get2(p) ((int) ((short) (((p)[1]<<8) + (p)[0])))
125
126 EXTERN int nmods, nprocs, nsyms;
127 EXTERN module *modtab;
128 EXTERN proc *proctab;
129
130 extern struct primdef {
131 char *p_name;
132 primitive *p_prim;
133 } primtab[];
134
135 #ifndef M64X32
136 EXTERN value _result[2]; /* Procedure result */
137 EXTERN value *statlink; /* Static link for procedure call */
138 #else
139 EXTERN value *_result;
140 EXTERN value **_stat;
141 #define statlink (*_stat)
142 #endif
143
144 #define ob_res _result[0]
145
146 EXTERN int level; /* Recursion level in bytecode interp. */
147 #ifdef OBXDEB
148 EXTERN value *prim_bp; /* Base pointer during primitive call */
149 #endif
150
151 EXTERN int dflag;
152 EXTERN mybool gflag;
153 #ifdef PROFILE
154 EXTERN mybool lflag;
155 #endif
156 #ifdef TRACE
157 EXTERN int qflag;
158 #endif
159 #ifdef OBXDEB
160 EXTERN char *debug_socket;
161 #endif
162
163 #define divop_decl(t) \
164 t t##_divop(t a, t b, int div) { \
165 t quo = a / b, rem = a % b; \
166 if (rem != 0 && (rem ^ b) < 0) { \
167 rem += b; quo--; \
168 } \
169 return (div ? quo : rem); \
170 }
171
172
173 /* profile.c */
174 #ifdef PROFILE
175 void prof_enter(value *p, counter ticks, int why);
176 void prof_exit(value *p, counter ticks);
177 void prof_init(void);
178 void prof_reset(proc p);
179 void profile(FILE *fp);
180
181 #define PROF_CALL 1
182 #define PROF_TAIL 2
183 #define PROF_PRIM 3
184 #endif
185
186 /* interp.c */
187 primitive interp, dltrap, dlstub;
188
189 /* xmain.c */
190 EXTERN int saved_argc;
191 EXTERN char **saved_argv;
192
193 int obgetc(FILE *fp);
194 void xmain_exit(int status);
195 void error_exit(int status);
196
197 /* support.c */
198 int ob_div(int a, int b);
199 int ob_mod(int a, int b);
200
201 void int_div(value *sp);
202 void int_mod(value *sp);
203
204 void long_add(value *sp);
205 void long_sub(value *sp);
206 void long_mul(value *sp);
207 void long_div(value *sp);
208 void long_mod(value *sp);
209 void long_neg(value *sp);
210 void long_cmp(value *sp);
211 void long_flo(value *sp);
212 void long_ext(value *sp);
213 void long_zcheck(value *sp);
214
215 word wrap_prim(primitive *prim);
216
217 /* dynlink.c */
218 void load_lib(char *fname);
219 void dltrap(value *sp);
220
221 /* load_file -- load a file of object code */
222 void load_file(FILE *bfp);
223
224 module make_module(char *name, uchar *addr, int chsum, int nlines);
225 proc make_proc(char *name, uchar *addr);
226 void make_symbol(const char *kind, char *name, uchar *addr);
227
228 void panic(const char *, ...);
229 void obcopy(char *dst, int dlen, const char *src, int slen, value *bp);
230
231 void error_stop(const char *msg, int line, value *bp, uchar *pc);
232 void runtime_error(int num, int line, value *bp, uchar *pc);
233 void rterror(int num, int line, value *bp);
234 void stkoflo(value *bp);
235 #define liberror(msg) error_stop(msg, 0, bp, NULL)
236
237 proc find_symbol(value *p, proc *table, int nelem);
238 #define find_proc(cp) find_symbol(cp, proctab, nprocs)
239 #define find_module(cp) ((module) find_symbol(cp, (proc *) modtab, nmods))
240
241 #ifdef TRACE
242 char *fmt_inst(uchar *pc);
243 void dump(void);
244 const char *prim_name(value *p);
245 #endif
246
247 #ifdef UNALIGNED_MEM
248 #define get_double(v) (* (double *) (v))
249 #define put_double(v, x) (* (double *) (v) = (x))
250 #define get_long(v) (* (longint *) (v))
251 #define put_long(v, x) (* (longint *) (v) = (x))
252 #else
253 double get_double(value *v);
254 void put_double(value *v, double x);
255 longint get_long(value *v);
256 void put_long(value *v, longint w);
257 #endif
258
259 double flo_conv(int);
260 double flo_convq(longint);
261
262 #ifdef SPECIALS
263 int pack(value *code, uchar *env);
264 value *getcode(int word);
265 uchar *getenvt(int word);
266 #endif
267
268 /* gc.c */
269
270 /* scratch_alloc -- allocate memory that will not be freed */
271 void *scratch_alloc(unsigned bytes);
272
273 /* gc_alloc -- allocate an object for the managed heap */
274 void *gc_alloc(value *desc, unsigned size, value *sp);
275
276 /* gc_collect -- run the garbage collector */
277 void gc_collect(value *xsp);
278
279 /* gc_alloc_size -- calculate allocated size of and object */
280 int gc_alloc_size(void *p);
281
282 /* gc_heap_size -- return size of heap */
283 int gc_heap_size(void);
284
285 extern mybool gcflag;
286 void gc_init(void);
287 void gc_debug(char *flags);
288 void gc_dump(void);
289
290 /* debug.c */
291 #ifdef OBXDEB
292 extern mybool one_shot;
293 extern mybool intflag;
294
295 void debug_init(void);
296 void debug_message(char *fmt, ...);
297 void debug_break(value *cp, value *bp, uchar *pc, char *fmt, ...);
298 #endif
299
300 /* jit.c */
301 #ifdef JIT
302 void jit_compile(value *cp);
303 void jit_trap(value *cp);
304 #endif
305
306 #ifdef __cplusplus
307 #define PRIMDEF extern "C"
308 #else
309 #define PRIMDEF
310 #endif
311
312 #ifdef NEED_FPINIT
313 /* On x86, each primitive re-initialises the FP unit, so that values
314 left behind in registers by the caller do not cause stack overflow. */
315 #define FPINIT asm ("fninit")
316 #else
317 #define FPINIT
318 #endif
319
320 #endif