/* Copyright (C) 1989, Digital Equipment Corporation */ /* All rights reserved. */ /* See the file COPYRIGHT for a full description. */ /* File: M3Runtime.h */ /* Last Modified On Tue Sep 8 11:49:32 PDT 1992 by jdd */ /* Modified On Thu Apr 16 09:05:52 PDT 1992 by kalsow */ /* Modified On Wed Mar 4 20:34:16 PST 1992 by muller */ #ifndef _M3RUNTIME_ #define _M3RUNTIME_ /*------------------------------------------------- machine dependent part --*/ /***************************************************************************/ /* Do not put any C code before the include of M3Machine.h. Some machines */ /* require special C code at the very beginning of the file and */ /* it is convenient to put this code in M3Machine.h (which is machine */ /* specific) */ /***************************************************************************/ #include "M3Machine.h" #include /*---------------------------------------------------------- builtin types --*/ #ifndef _ADDRESS #define _ADDRESS char* #endif /* _ADDRESS */ #ifndef _INTEGER #define _INTEGER int #endif /* _INTEGER */ #ifndef _CHAR #define _CHAR unsigned char #endif /* _CHAR */ #ifndef _REAL #define _REAL float #endif /* _REAL */ #ifndef _LONGREAL #define _LONGREAL double #endif /* _LONGREAL */ #ifndef _EXTENDED #define _EXTENDED double #endif /* _EXTENDED */ #ifndef _NIL #define _NIL 0 #endif /* _NIL */ #ifndef _VOID #define _VOID void #endif /* _VOID */ /*-------------------------------------------- procedure and closure types --*/ typedef _VOID (*_PROC)(); typedef struct { int marker; _PROC proc; _ADDRESS arg; } _CLOSURE; #define _CLOSURE_PROC(p) (((_CLOSURE*)p)->proc) #define _CLOSURE_FRAME(p) (((_CLOSURE*)p)->arg) /*------------------------------------ garbage collector "map proc" values --*/ typedef struct { int elt[1]; } _MAPPROC_MASK; #define _MASK_TRACED(x) ((x).elt[0] & 1) #define _MASK_UNTRACED(x) ((x).elt[0] & 2) #define _MASK_PROC(x) ((x).elt[0] & 4) #define _VAL_TRACED 0 #define _VAL_UNTRACED 1 #define _VAL_PROC 2 /*------------------------------------------------------ exception support --*/ extern _ADDRESS _M3__handlers; #define _EXCEPT_HC '\000' #define _EXCEPT_ELSE_HC '\001' #define _FINALLY_HC '\002' #define _RAISES_HC '\003' #define _RAISES_NONE_HC '\004' #define _FINALLY_PROC_HC '\005' #define _LOCK_HC '\006' typedef char* _EXCEPTION_NAME; typedef _EXCEPTION_NAME* _EXCEPTION; #define _raises_1 ((_EXCEPTION*) 0) #define _HANDLER struct _handler #define _FALL_EXCEPTION ((_EXCEPTION)0) #define _RETURN_EXCEPTION ((_EXCEPTION)1) #define _EXIT_EXCEPTION ((_EXCEPTION)2) typedef struct _raises_none_handler { _HANDLER *next; char class; } _RAISES_NONE_HANDLER; typedef struct _raises_handler { _HANDLER *next; char class; _EXCEPTION *handles; } _RAISES_HANDLER; typedef struct _lock_handler { _HANDLER *next; char class; _ADDRESS mutex; } _LOCK_HANDLER; typedef struct _finally_proc_handler { _HANDLER *next; char class; _PROC proc; _ADDRESS frame; } _FINALLY_PROC_HANDLER; typedef struct _handler { _HANDLER *next; char class; _EXCEPTION *handles; _EXCEPTION exception; _ADDRESS arg; jmp_buf pc; } _TRY_HANDLER; #define _PUSH_TRY(handler, excepts, label) {\ handler.class = _EXCEPT_HC;\ handler.handles = excepts;\ handler.next = *((_TRY_HANDLER **) &_M3__handlers);\ handler.exception = _FALL_EXCEPTION; \ *((_TRY_HANDLER **) &_M3__handlers) = (_TRY_HANDLER*)&handler;\ if (_setjmp (handler.pc)) goto label; } #define _PUSH_TRY_ELSE(handler, label) {\ handler.class = _EXCEPT_ELSE_HC;\ handler.next = *((_TRY_HANDLER **) &_M3__handlers);\ handler.exception = _FALL_EXCEPTION; \ *((_TRY_HANDLER **) &_M3__handlers) = &handler;\ if (_setjmp (handler.pc)) goto label; } #define _PUSH_RAISES(handler, raises) {\ handler.class = _RAISES_HC;\ handler.handles = raises;\ handler.next = *((_TRY_HANDLER **) &_M3__handlers);\ *((_TRY_HANDLER **) &_M3__handlers) = (_TRY_HANDLER*)&handler; } #define _PUSH_RAISES_NONE(handler) {\ handler.class = _RAISES_NONE_HC;\ handler.next = *((_TRY_HANDLER **) &_M3__handlers);\ *((_TRY_HANDLER **) &_M3__handlers) = (_TRY_HANDLER*)&handler; } #define _PUSH_FINALLY(handler, label) {\ handler.class = _FINALLY_HC; \ handler.next = *((_TRY_HANDLER **) &_M3__handlers);\ handler.exception = _FALL_EXCEPTION; \ *((_TRY_HANDLER **) &_M3__handlers) = (_TRY_HANDLER*)&handler;\ if (_setjmp(handler.pc)) goto label; } #define _PUSH_FINALLY_PROC(handler, f_proc, f_arg) {\ handler.class = _FINALLY_PROC_HC; \ handler.next = *((_TRY_HANDLER **) &_M3__handlers);\ handler.proc = (_PROC) f_proc;\ handler.frame = (_ADDRESS) f_arg;\ *((_TRY_HANDLER **) &_M3__handlers) = (_TRY_HANDLER*)&handler; } #define _PUSH_LOCK(handler, mu) {\ handler.class = _LOCK_HC; \ handler.next = *((_TRY_HANDLER **) &_M3__handlers);\ handler.mutex = (_ADDRESS) mu;\ *((_TRY_HANDLER **) &_M3__handlers) = (_TRY_HANDLER*)&handler; } #define _CUT_TO_NEXT_HANDLER(handler) {\ *((_TRY_HANDLER **) &_M3__handlers) = handler.next; } #define _RAISE(ex,arg) RTException__Raise (ex,arg) #define _RAISE_FOR_SURE(ex,arg) RTException__RaiseForSure (ex,arg) /*---------------------------------------------------- runtime type system --*/ /* type classes */ #define _TC_NONE 0 #define _TC_ARRAY 1 #define _TC_ENUM 2 #define _TC_OBJECT 3 #define _TC_OPAQUE 4 #define _TC_OPEN_ARRAY 5 #define _TC_PACKED 6 #define _TC_PROCEDURE 7 #define _TC_RECORD 8 #define _TC_REF 9 #define _TC_SET 10 #define _TC_SUBRANGE 11 typedef struct _tc { int typecode; int lastSubTypeTC; int selfID; struct _tc** selfLink; _ADDRESS fpInfo; unsigned char traced; int dataOffset; int dataSize; int dataAlignment; int methodOffset; int methodSize; int nDimensions; int elementSize; _ADDRESS defaultMethods; _PROC setupProc; _PROC mapProc; _PROC initProc; _ADDRESS brand; _ADDRESS name; struct _tc** parentLink; struct _tc* parent; struct _tc* children; struct _tc* sibling; } _TYPE; #define _NO_BRAND ((char*)-1) /*-------------------------------------------------- compilation unit data --*/ typedef struct { _TYPE** lhs; _TYPE** rhs; int lhs_id; int rhs_id; } _TYPE_PAIR; typedef struct { int id; int fp[2]; int *data; int d_len; int seq; int class; } _TYPE_INFO; typedef struct { _PROC proc; int type_id; char* name; int fp[2]; } _PROC_INFO; typedef struct { char* file; _TYPE_INFO *type_info; int *type_fp_data; _TYPE **type_cells; _TYPE_PAIR *exported_full_revelations; _TYPE_PAIR *exported_partial_revelations; _TYPE_PAIR *imported_full_revelations; _TYPE_PAIR *imported_partial_revelations; _PROC_INFO *proc_info; _PROC init_proc; _PROC map_proc; } _LINK_INFO; /*------------------------------------------------ builtin type operations --*/ unsigned char RTType__IsSubtype (); typedef struct _header { int forwarded : 1; int typecode : 20; int weak : 1; int marka : 1; int markb : 1; int spare : 8; } _refHeader; #define _TYPECODZ(ref) ((((_refHeader*) ref) - 1)->typecode) #define _TYPECODE(ref) (((ref)==0) ? 0 : _TYPECODZ(ref)) #define _ISTYPE(e,t) ((e==_NIL)||(((_refHeader*)e)-1)->typecode == t->typecode) /* #define _ISSUBTYPE(tc,t) (RTType__IsSubtype (tc, t->typecode)) */ #define _ISSUBTYPZ(tc,t) ((t->typecode <= tc) && (tc <= t->lastSubTypeTC)) #define _ISSUBTYPE(tc,t) ((tc==0) || _ISSUBTYPZ(tc,t)) /* Note: TYPECODZ and ISSUBTYPZ handle the non-NIL cases */ /*------------------------------------------------------ builtin text type --*/ typedef struct { _refHeader h; char* str; int len; } _TXT; /*-------------------------------------------------------- runtime errors ---*/ #define _ASSERTFAULT(f,l) RTMisc__AssertFault (f, l) #define _RETURNFAULT(f,l) RTMisc__ReturnFault (f, l) #define _CASEFAULT(f,l) RTMisc__CaseFault (f, l) #define _TYPECASEFAULT(f,l) RTMisc__TypecaseFault (f, l) #define _RANGEFAULT(f,l) RTMisc__RangeFault (f, l) #define _NARROWFAULT(f,l) RTMisc__NarrowFault (f, l) #ifdef _STACK_GROWS_DOWN #define _CHECKSTACKOVERFLOW(f,l) \ {char x; if ((_ADDRESS)(&x)<= _M3__stackLimit) _M3__StackOverflow(f, l); } #else #define _CHECKSTACKOVERFLOW(f,l) \ {char x; if ((_ADDRESS)(&x)>= _M3__stackLimit) _M3__StackOverflow(f, l); } #endif /*----------------------------------------- builtin arithmetic operations ---*/ #define _CVTIF(x) ((float) x) #define _CVTLF(x) ((float) x) #define _CVTEF(x) ((float) x) #define _CVTIL(x) ((double) x) #define _CVTFL(x) ((double) x) #define _CVTEL(x) (x) #define _CVTIE(x) ((double) x) #define _CVTFE(x) ((double) x) #define _CVTLE(x) (x) #define _CEILING(r) RTMath__Ceiling (r) #define _FLOOR(r) RTMath__Floor (r) #define _ROUND(r) RTMath__Round (r) #define _TRUNC(r) ((int) r) #define _INCL(s,a,b) RTMath__SetIncl (s,a,b) #define _IDIVXX(n,m) RTMath__IDiv (n,m) #define _IMODXX(n,m) RTMath__IMod (n,m) #define _IDIVXP(n,m) (((n) >= 0) ? (n)/(m) : - (((-(n))-1) / (m)) - 1) #define _IMODXP(n,m) (((n) >= 0) ? (n)%(m) : (m)-1-(((-(n))-1)%(m))) #define _IDIVXN(n,m) (((n) <= 0) ? (-(n))/(-(m)) : (m)+1+(((n)-1)%(-(m)))) #define _IMODXN(n,m) (((n) <= 0) ? -((-(n))%(-(m))) : (m)+1+(((n)-1)%(-(m)))) #define _IDIVPX(n,m) _IDIVXX(n,m) #define _IMODPX(n,m) _IMODXX(n,m) #define _IDIVPP(n,m) ((n)/(m)) #define _IMODPP(n,m) ((n)%(m)) #define _IDIVPN(n,m) ((n)==0 ? 0 : - (((n)-1)/(-(m))) - 1) #define _IMODPN(n,m) ((n)==0 ? 0 : (m)+1+(((n)-1)%(-(m)))) #define _IDIVNX(n,m) _IDIVXX(n,m) #define _IMODNX(n,m) _IMODXX(n,m) #define _IDIVNP(n,m) ((n)==0 ? 0 : - (((-(n))-1) / (m)) - 1) #define _IMODNP(n,m) ((n)==0 ? 0 : (m)-1-(((-(n))-1)%(m))) #define _IDIVNN(n,m) ((-(n))/(-(m))) #define _IMODNN(n,m) (-((-(n))%(-(m)))) /*------------------------------------------------------ allocator support --*/ #define _TNEW(t) RTHeap__Allocate (t->typecode) #define _UNEW(t) RTHeap__AllocateUntracedRef (t->typecode) #define _TNEWOBJ(t) RTHeap__Allocate (t->typecode) #define _UNEWOBJ(t) RTHeap__AllocateUntraced (t->typecode) #define _TNEWA(t,s) RTHeap__AllocateOpenArray (t->typecode, s) #define _UNEWA(t,s) RTHeapRep__AllocateUntracedOpenArrayDef (t, s) #define _TDISPOSE(ref) RTHeapRep__DisposeTraced (ref) #define _UDISPOSE(ref) RTHeapRep__DisposeUntraced (ref) #define _ODISPOSE(ref) RTHeapRep__DisposeUntracedObj (ref) /*------------------------------------------------ misc. memory operations --*/ #define _COPY(src,dest,len) bcopy (src, dest, len) #define _ZERO(len,addr) bzero (addr, len) #define _ZERO1B(addr) *(char*) (addr) = 0 #define _ZERO1S(addr) *(short*)(addr) = 0 #define _ZERO1(addr) *(int*) (addr) = 0 #define _ZERO2(a) \ {register int *i =(int*)(a); i[0]=0; i[1]=0; } #define _ZERO3(a) \ {register int *i =(int*)(a); i[0]=0; i[1]=0; i[2]=0;} #define _ZERO4(a) \ {register int *i =(int*)(a); i[0]=0; i[1]=0; i[2]=0; i[3]=0;} #define _ZERO5(a) \ {register int *i =(int*)(a); i[0]=0; i[1]=0; i[2]=0; i[3]=0; i[4]=0; } #define _ZERO6(a) \ {register int *i =(int*)(a); i[0]=0; i[1]=0; i[2]=0; i[3]=0; i[4]=0; \ i[5]=0; } #define _ZERO7(a) \ {register int *i =(int*)(a); i[0]=0; i[1]=0; i[2]=0; i[3]=0; i[4]=0; \ i[5]=0; i[6]=0; } #define _ZERO8(a) \ {register int *i =(int*)(a); i[0]=0; i[1]=0; i[2]=0; i[3]=0; i[4]=0; \ i[5]=0; i[6]=0; i[7]=0;} /*--------------------------------------------------------- thread support --*/ extern _ADDRESS _M3__stackLimit; #endif /* _M3RUNTIME_ */