annotate keiko/obx.h @ 1:b5139af1a420 tip basis

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