/* Copyright (C) 1990, Digital Equipment Corporation. */ /* All rights reserved. */ /* See the file COPYRIGHT for a full description. */ /* Last modified on Wed Jul 18 21:31:46 1990 by muller */ /* for IBMRT */ /* This depends on the direction in which the stack grows */ IMPORT char* _ThreadSup__stackLimit; #define CHECKSTACKOVERFLOW \ { char foo; if (&foo <= _ThreadSup__stackLimit) \ _M3Runtime__Error ("stack overflow"); } /* IS_CLOSURE should return TRUE if p points to a closure, FALSE if it points to a C function */ /* 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. */ IMPORT etext; #define IS_CLOSURE(p) \ (p == 0 ? 0 : ((*((long unsigned *)p)) > ((unsigned long) &etext))) /* How to check for NIL pointers: NICHECKA and NILCHECKB must evaluate their argument e (a char*) and generate a trap if it is NIL (0). The compiler generates NILCHECKA when there is a future reference to e[0..1023]; otherwise NICHECKB. Thus, if referencing one of the first 1024 bytes of virtual memory causes a trap, NILCHECKA can just evaluate e; the future reference will generate the trap. */ volatile char nil_check_char; #define NILCHECKA(e) nil_check_char = ((char*)(e))[-1]; #define NILCHECKB(e) nil_check_char = ((char*)(e))[-1]; /* The garbage collector needs to know two things: - what is the alignment of pointers in the stacks ? - what is the alignment of objects ? */ /* The following definition expresses in bytes the amount by which the pointer sweeping the stacks to discover pointers to roots have to be advanced. */ #define STACK_INC 4 /* pointers in stacks are word-aligned */ /* The allocator aligns all the structures it allocates to satisify any possble alignment constraint, in the style of malloc. The quantity is expressed in words. */ #define ALIGNMENT 2 /* objects are word aligned */ /* The type 'signed_char' is 'signed char' in ANSI-C, but CC may not like that */ typedef signed char signed_char;