/* 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 15 10:38:27 PDT 1992 by rustan */ /* 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) */ /***************************************************************************/ /* KRML Note. This file uses setjmp/longjmp instead of _setjmp/_longjmp * used in the SRC M3Runtime.h. Moreover, setjmp/longjmp/jmp_buf are * prototyped/declared in this file rather than that setjmp.h would be * included. Note that longjmp does not take the second parameter it * normally does. Another machine specific change that has been made in this * file is changing the "misc. memory operations" definition at the * bottom of the file. */ #define NOT_TESTING #include "M3Machine.h" #ifdef NO_KRML #include #else typedef int jmp_buf[8]; int setjmp(); /* The longjmp prototype is not included here because it is not needed. Furthermore, if the parameters of setjmp or longjmp were explicitly mentioned here, they would clash with the calls to setjmp and longjmp aliasing the RTRegisters__Save and RTRegisters__Restore calls (see .mc files for details). The full setjmp and longjmp prototypes are: int setjmp( jmp_buf env ); void longjmp( jmp_buf env ); Note absense of longjmp's 'val' parameter. */ #endif /* NO_KRML */ /*---------------------------------------------------------- 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) /*------------------------------------------------------ exception support --*/ extern _ADDRESS ThreadF__currentHandlers; #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) #define _EXC_ARG_NONE ((_EXCEPTION)3) #define _EXC_ARG_WORD ((_EXCEPTION)4) #define _EXC_ARG_NETWORK ((_EXCEPTION)5) 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 **) &ThreadF__currentHandlers);\ handler.exception = _FALL_EXCEPTION; \ *((_TRY_HANDLER **) &ThreadF__currentHandlers) = (_TRY_HANDLER*)&handler;\ if (setjmp (handler.pc)) goto label; } #define _PUSH_TRY_ELSE(handler, label) {\ handler.class = _EXCEPT_ELSE_HC;\ handler.next = *((_TRY_HANDLER **) &ThreadF__currentHandlers);\ handler.exception = _FALL_EXCEPTION; \ *((_TRY_HANDLER **) &ThreadF__currentHandlers) = &handler;\ if (setjmp (handler.pc)) goto label; } #define _PUSH_RAISES(handler, raises) {\ handler.class = _RAISES_HC;\ handler.handles = raises;\ handler.next = *((_TRY_HANDLER **) &ThreadF__currentHandlers);\ *((_TRY_HANDLER **) &ThreadF__currentHandlers) = (_TRY_HANDLER*)&handler; } #define _PUSH_RAISES_NONE(handler) {\ handler.class = _RAISES_NONE_HC;\ handler.next = *((_TRY_HANDLER **) &ThreadF__currentHandlers);\ *((_TRY_HANDLER **) &ThreadF__currentHandlers) = (_TRY_HANDLER*)&handler; } #define _PUSH_FINALLY(handler, label) {\ handler.class = _FINALLY_HC; \ handler.next = *((_TRY_HANDLER **) &ThreadF__currentHandlers);\ handler.exception = _FALL_EXCEPTION; \ *((_TRY_HANDLER **) &ThreadF__currentHandlers) = (_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 **) &ThreadF__currentHandlers);\ handler.proc = (_PROC) f_proc;\ handler.frame = (_ADDRESS) f_arg;\ *((_TRY_HANDLER **) &ThreadF__currentHandlers) = (_TRY_HANDLER*)&handler; } #define _PUSH_LOCK(handler, mu) {\ handler.class = _LOCK_HC; \ handler.next = *((_TRY_HANDLER **) &ThreadF__currentHandlers);\ handler.mutex = (_ADDRESS) mu;\ *((_TRY_HANDLER **) &ThreadF__currentHandlers) = (_TRY_HANDLER*)&handler; } #define _CUT_TO_NEXT_HANDLER(handler) {\ *((_TRY_HANDLER **) &ThreadF__currentHandlers) = handler.next; } #define _RAISE(ex,arg) RTException__RaiseKRML (ex,arg) #define _RAISE_FOR_SURE(ex,arg) RTException__RaiseKRML (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; KRML */ /* struct _tc** selfLink; KRML */ /* _ADDRESS fpInfo; KRML */ /* unsigned char traced; KRML */ int dataOffset; int dataSize; /* int dataAlignment; KRML */ int methodOffset; /* int methodSize; KRML */ int nDimensions; int elementSize; _ADDRESS defaultMethods; _ADDRESS remoteMethods; /* new KRML */ /* _PROC setupProc; KRML */ /* _PROC mapProc; KRML */ int * tracedOffsets; /* new KRML */ _PROC initProc; /* _ADDRESS brand; KRML */ /* _ADDRESS name; KRML */ /* struct _tc** parentLink; KRML */ struct _tc* parent; /* struct _tc* children; KRML */ /* struct _tc* sibling; KRML */ } _TYPE; #define _NO_BRAND ((char*)-1) /*-------------------------------------------------- compilation unit data --*/ typedef struct { int id; int fp[2]; int *data; int d_len; int seq; int class; } _TYPE_INFO; typedef struct { /* new KRML */ _VOID *addr; int *tracedOffsets; } _GLOBAL_PAIR; typedef struct { _PROC init_proc; _GLOBAL_PAIR *globals; /* new KRML */ } _LINK_INFO; /*------------------------------------------------ builtin type operations --*/ typedef struct _header { int size; int typecode; int gcStatus; } _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 _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 */ /* LOCAL_CHECK evaluates its argument, which is of type _NETWORK, and generates a trap if it is not a local network object */ extern int System__procID; #define _LOCAL_CHECK( e ) \ { if ( ((_NETWORK)(e))->pid != System__procID ) \ asm("jsr _RTMisc__RemoteDerefFault,r7"); } /*---------------------------------------------------------- builtin typse --*/ typedef struct { _refHeader h; char* str; int len; } _TXT; typedef struct { char* method_suite; int pid; int refcount; } * _NETWORK; /*-------------------------------------------------------- runtime errors ---*/ #define _ASSERTFAULT(f,l) { asm("jsr _RTMisc__AssertFault,r7"); asm("$:");} #ifdef NOT_TESTING #define _RETURNFAULT(f,l) { asm("jsr _RTMisc__ReturnFault,r7"); asm("$:");} #define _CASEFAULT(f,l) { asm("jsr _RTMisc__CaseFault,r7"); asm("$:");} #define _TYPECASEFAULT(f,l) { asm("jsr _RTMisc__TypecaseFault,r7"); asm("$:");} #define _RANGEFAULT(f,l) { asm("jsr _RTMisc__RangeFault,r7"); asm("$:");} #define _NARROWFAULT(f,l) { asm("jsr _RTMisc__NarrowFault,r7"); asm("$:");} /* #define _CHECKSTACKOVERFLOW(f,l) { asm("jsr __M3__CheckStack,r0"); } */ #define _CHECKSTACKOVERFLOW(f,l) { _M3__CheckStack(); } #else #define _RETURNFAULT(f,l) {} #define _CASEFAULT(f,l) {} #define _TYPECASEFAULT(f,l) {} #define _RANGEFAULT(f,l) {} #define _NARROWFAULT(f,l) {} #define _CHECKSTACKOVERFLOW(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) #define _UNEW(t) RTHeap__Allocate(t) #define _TNEWOBJ(t) RTHeap__Allocate(t) #define _UNEWOBJ(t) RTHeap__Allocate(t) #define _NEWBINDINGS(t,p) RTHeap__AllocateBindings(t, p) #define _NEWREMOTE(p,t,b) RPC__RemoteNew(p, t, b) #define _TNEWA(t,s) RTHeap__AllocateOpenArray(t, s) #define _UNEWA(t,s) RTHeap__AllocateOpenArray(t, s) #define _TDISPOSE(ref) RTHeap__DisposeTraced(ref) #define _UDISPOSE(ref) RTHeap__DisposeUntraced(ref) #define _ODISPOSE(ref) RTHeap__DisposeUntraced(ref) /*------------------------------------------------ misc. memory operations --*/ /* _COPY copies len characters * _ZERO zeros len characters * _ZERO1B zeros 1 character * _ZERO1S zeros 2 characters * _ZERO1 zeros 4 characters * _ZERO2 zeros 8 characters * _ZERO3 zeros 12 characters * _ZERO4 zeros 16 characters * _ZERO5 zeros 20 characters * _ZERO6 zeros 24 characters * _ZERO7 zeros 28 characters * _ZERO8 zeros 32 characters */ #define _COPY(src,dest,len) memmove (dest, src, len) #define _ZERO(len,addr) bzero (addr, len) #define _ZERO1B(a) *(int*) (a) = 0 #define _ZERO1S(a) \ {register int *i =(int*)(a); i[0]=0; i[1]=0; } #define _ZERO1(a) \ {register int *i =(int*)(a); i[0]=0; i[1]=0; i[2]=0; i[3]=0;} #define _ZERO2(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;} #define _ZERO3(a) _ZERO(a,12) #define _ZERO4(a) _ZERO(a,16) #define _ZERO5(a) _ZERO(a,20) #define _ZERO6(a) _ZERO(a,24) #define _ZERO7(a) _ZERO(a,28) #define _ZERO8(a) _ZERO(a,32) /*--------------------------------------------------------- thread support --*/ #endif /* _M3RUNTIME_ */