/* Copyright (C) 1990, Digital Equipment Corporation. */ /* All rights reserved. */ /* See the file COPYRIGHT for a full description. */ /* Last modified on Thu Nov 12 10:43:25 PST 1992 by muller */ /* modified on Tue Oct 13 08:33:41 PDT 1992 by kalsow */ /* for IBMR2 */ /* * There used to be a pragma for alloca here. Beware that if you * put it back in, you will trash the thread package. The affect * of this pragma is to tell the compiler to generate code that * does not trust the stack pointer. RTThread.UpdateStateForNewSP * must know how to alter the registers to relocate the procedure * Thread.DetermineContext onto a thread stack. The alloca pragma * causes the compiler to keep a copy of the stack pointer instead * of using the real thing. This copy is hard to update since the * compiler chooses which register to put it in and is not * deterministic over -g, -O, etc. */ /* These are the storage classes and type qualifiers */ #define _VOLATILE volatile #define _PRIVATE static #define _IMPORT extern #define _EXPORT #define _LOCAL_PROC static #define _LOCAL auto #define _STACK_GROWS_DOWN /* comment this out if stacks grow up (toward increasing addresses) */ /* Dick Orgass says: This rather strange definition comes from the following obscure property of the C Compiler/ld for this system. If a function, say foo, is declared in a C source file, there are two entries in the symbol table: .foo (note the leading dot) is in the text segment and foo (without the dot) is in the data segment. Therefore, if one executes the assigment x = foo;, the value of x is in the data segment. Moreover, *foo == foo but *(unsigned long *)foo == .foo and is in the text segment. This means that the proc field of a CLOSURE always points to the data segment and *(unsigned long *)(CLOSURE *) remains in the data segment. I have no idea why this is the case. */ /* A Modula-3 procedure value can be either a C function pointer or a pointer to a CLOSURE struct. The first field of CLOSURE structs "marker", is always equal to CLOSURE_MARKER. To test if a procedure value is a closure or not, we assume is it one and look at the marker field. If we don't find CLOSURE_MARKER, we have a C function pointer. Since a C function pointer is the address of the first instruction, we chose the value of CLOSURE_MARKER to be different from any instruction that may start a procedure. */ #define _CLOSURE_MARKER (-1) /* illegal opcode */ #define _IS_CLOSURE(p) ((p != 0) && ((_CLOSURE *)p)->marker == _CLOSURE_MARKER) /* NILCHECKB must evaluate its argument 'e' (a char*) and generate a trap if it is NIL (0). */ #define _NILCHKCHAR volatile char _IMPORT _NILCHKCHAR _M3__nil_check_char; #define _NILCHECKB(e) _M3__nil_check_char = ((char*)(e))[-1]; /* The type 'signed_char' is 'signed char' in ANSI-C, but CC may not like that. Same for 'signed_int'. */ typedef signed char signed_char; typedef signed int signed_int; /* builtin types */ #define _ADDRESS _VOLATILE char*