1 /* -*-C-*-
2 
3 Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
4     1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5     2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Massachusetts
6     Institute of Technology
7 
8 This file is part of MIT/GNU Scheme.
9 
10 MIT/GNU Scheme is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or (at
13 your option) any later version.
14 
15 MIT/GNU Scheme is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with MIT/GNU Scheme; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
23 USA.
24 
25 */
26 
27 /* Stack abstraction */
28 
29 #define SET_STACK_LIMITS(addr, n_words) do				\
30 {									\
31   stack_start = (addr);							\
32   stack_end = (stack_start + (n_words));				\
33 } while (0)
34 
35 #define STACK_BOTTOM stack_end
36 #define STACK_TOP stack_start
37 
38 #define INITIALIZE_STACK() do						\
39 {									\
40   stack_pointer = STACK_BOTTOM;						\
41   (*STACK_TOP) = (MAKE_BROKEN_HEART (STACK_TOP));			\
42   stack_guard = (STACK_TOP + STACK_GUARD_SIZE);				\
43   COMPILER_SETUP_INTERRUPT ();						\
44 } while (0)
45 
46 #define STACK_OVERFLOWED_P()						\
47   ((*STACK_TOP) != (MAKE_BROKEN_HEART (STACK_TOP)))
48 
49 #ifndef STACK_RESET
50 #  define STACK_RESET() do {} while (0)
51 #endif
52 
53 #define STACK_CHECK(n) do						\
54 {									\
55   if (!CAN_PUSH_P (n))							\
56     {									\
57       STACK_CHECK_FATAL ("STACK_CHECK");				\
58       REQUEST_INTERRUPT (INT_Stack_Overflow);				\
59     }									\
60 } while (0)
61 
62 #define STACK_CHECK_FATAL(s) do						\
63 {									\
64   if (STACK_OVERFLOWED_P ())						\
65     stack_death (s);							\
66 } while (false)
67 
68 #define CAN_PUSH_P(n) (SP_OK_P (STACK_LOC (- (n))))
69 #define SP_OK_P(sp) ((sp) >= stack_guard)
70 
71 #define STACK_LOCATIVE_DECREMENT(locative) (-- (locative))
72 #define STACK_LOCATIVE_INCREMENT(locative) ((locative) ++)
73 #define STACK_LOCATIVE_OFFSET(locative, offset) ((locative) + (offset))
74 #define STACK_LOCATIVE_REFERENCE(locative, offset) ((locative) [(offset)])
75 #define STACK_LOCATIVE_DIFFERENCE(newer, older) ((older) - (newer))
76 #define STACK_LOCATIVE_LESS_P(loc1, loc2) ((loc1) < (loc2))
77 
78 #define ADDRESS_IN_STACK_REGION_P(address, lower_limit, upper_limit)	\
79   (((address) >= (lower_limit)) && ((address) < (upper_limit)))
80 
81 #define STACK_N_PUSHED (stack_end - stack_pointer)
82 #define SP_TO_N_PUSHED(sp, start, end) ((end) - (sp))
83 #define N_PUSHED_TO_SP(np, start, end) ((end) - (np))
84 
85 #define STACK_LOCATIVE_PUSH(locative) (* (STACK_LOCATIVE_DECREMENT (locative)))
86 #define STACK_LOCATIVE_POP(locative) (* (STACK_LOCATIVE_INCREMENT (locative)))
87 
88 #define STACK_PUSH(object) (STACK_LOCATIVE_PUSH (stack_pointer)) = (object)
89 #define STACK_POP() (STACK_LOCATIVE_POP (stack_pointer))
90 #define STACK_LOC(offset) (STACK_LOCATIVE_OFFSET (stack_pointer, (offset)))
91 #define STACK_REF(offset) (STACK_LOCATIVE_REFERENCE (stack_pointer, (offset)))
92