0f9194632da504a2dabfb0ed227d66ca0d76d568
[cacao.git] / src / vm / jit / stack.h
1 /* vm/jit/stack.h - stack analysis header
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program 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 this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Christian Thalinger
28
29    Changes: Christian Ullrich
30                         Edwin Steiner
31
32    $Id: stack.h 5442 2006-09-09 14:45:55Z edwin $
33
34 */
35
36
37 #ifndef _STACK_H
38 #define _STACK_H
39
40 #include "config.h"
41
42 #include "vm/types.h"
43
44 #include "vm/exceptions.h"
45 #include "vm/global.h"
46 #include "vm/jit/jit.h"
47 #include "vm/jit/reg.h"
48
49
50 /* macros used internally by analyse_stack ************************************/
51
52 /* convenient abbreviations */
53 #define CURKIND    curstack->varkind
54 #define CURTYPE    curstack->type
55
56
57 /*--------------------------------------------------*/
58 /* STACK DEPTH CHECKING                             */
59 /*--------------------------------------------------*/
60
61 #if defined(ENABLE_VERIFIER)
62 #define CHECK_STACK_DEPTH(depthA,depthB)                             \
63     do {                                                             \
64         if ((depthA) != (depthB))                                    \
65             goto throw_stack_depth_error;                            \
66     } while (0)
67 #else /* !ENABLE_VERIFIER */
68 #define CHECK_STACK_DEPTH(depthA,depthB)
69 #endif /* ENABLE_VERIFIER */
70
71
72 /*--------------------------------------------------*/
73 /* BASIC TYPE CHECKING                              */
74 /*--------------------------------------------------*/
75
76 /* XXX would be nice if we did not have to pass the expected type */
77
78 #if defined(ENABLE_VERIFIER)
79 #define CHECK_BASIC_TYPE(expected,actual)                            \
80     do {                                                             \
81         if ((actual) != (expected)) {                                \
82             expectedtype = (expected);                               \
83             goto throw_stack_type_error;                             \
84         }                                                            \
85     } while (0)
86 #else /* !ENABLE_VERIFIER */
87 #define CHECK_BASIC_TYPE(expected,actual)
88 #endif /* ENABLE_VERIFIER */
89
90 /*--------------------------------------------------*/
91 /* STACK UNDERFLOW/OVERFLOW CHECKS                  */
92 /*--------------------------------------------------*/
93
94 /* underflow checks */
95
96 #if defined(ENABLE_VERIFIER)
97 #define REQUIRE(num)                                                 \
98     do {                                                             \
99         if (stackdepth < (num))                                      \
100             goto throw_stack_underflow;                              \
101     } while (0)
102 #else /* !ENABLE_VERIFIER */
103 #define REQUIRE(num)
104 #endif /* ENABLE_VERIFIER */
105
106
107 /* overflow check */
108 /* We allow ACONST instructions inserted as arguments to builtin
109  * functions to exceed the maximum stack depth.  Maybe we should check
110  * against maximum stack depth only at block boundaries?
111  */
112
113 /* XXX we should find a way to remove the opc/op1 check */
114 #if defined(ENABLE_VERIFIER)
115 #define CHECKOVERFLOW                                                \
116     do {                                                             \
117         if (stackdepth > m->maxstack)                                \
118             if ((iptr->opc != ICMD_ACONST) || INSTRUCTION_MUST_CHECK(iptr))\
119                 goto throw_stack_overflow;                           \
120     } while(0)
121 #else /* !ENABLE_VERIFIER */
122 #define CHECKOVERFLOW
123 #endif /* ENABLE_VERIFIER */
124
125 /*--------------------------------------------------*/
126 /* ALLOCATING STACK SLOTS                           */
127 /*--------------------------------------------------*/
128
129 #define NEWSTACK(s,v,n)                                              \
130     do {                                                             \
131         sd.new->prev = curstack;                                     \
132         sd.new->type = (s);                                          \
133         sd.new->flags = 0;                                           \
134         sd.new->varkind = (v);                                       \
135         sd.new->varnum = (n);                                        \
136         curstack = sd.new;                                           \
137         sd.var[(n)].type = (s);                                      \
138         sd.var[(n)].flags = 0;                                       \
139         sd.new++;                                                    \
140     } while (0)
141
142 /* Initialize regoff, so -sia can show regnames even before reg.inc */
143 /* regs[rd->intregargnum] has to be set for this                    */
144 /* new->regoff = (IS_FLT_DBL_TYPE(s))?-1:rd->intreg_argnum; }       */
145
146 #define NEWSTACKn(s,n)  NEWSTACK(s,UNDEFVAR,n)
147 #define NEWSTACK0(s)    NEWSTACK(s,UNDEFVAR,0)
148
149
150 /*--------------------------------------------------*/
151 /* MACROS FOR HANDLING BASIC BLOCKS                 */
152 /*--------------------------------------------------*/
153
154 /* COPYCURSTACK makes a copy of the current operand stack (curstack)
155  * and returns it in the variable copy.
156  *
157  * This macro is used to propagate the operand stack from one basic
158  * block to another. The destination block receives the copy as its
159  * input stack.
160  */
161 #define COPYCURSTACK(sd, copy) {                                     \
162     stackptr s;                                                      \
163     if (curstack) {                                                  \
164         s = curstack;                                                \
165         (sd).new += stackdepth;                                      \
166         copy = (sd).new;                                             \
167         while (s) {                                                  \
168                         GET_NEW_VAR(sd, new_index, s->type);                     \
169             copy--;                                                  \
170             copy->prev = copy-1;                                     \
171             copy->creator = NULL;                                    \
172             copy->type = s->type;                                    \
173             copy->flags = 0;                                         \
174             copy->varkind = STACKVAR;                                \
175             copy->varnum = new_index;                                \
176                         (sd).var[new_index].flags = OUTVAR;                      \
177             s = s->prev;                                             \
178         }                                                            \
179         copy->prev = NULL;                                           \
180         copy = (sd).new-1;                                           \
181     }                                                                \
182     else                                                             \
183         copy = NULL;                                                 \
184 }
185
186
187 /* external macros ************************************************************/
188
189 #define BLOCK_OF(index)                                              \
190     (jd->new_basicblocks + jd->new_basicblockindex[index])
191
192
193 /* function prototypes ********************************************************/
194
195 bool stack_init(void);
196
197 bool new_stack_analyse(jitdata *jd);
198
199 #endif /* _STACK_H */
200
201
202 /*
203  * These are local overrides for various environment variables in Emacs.
204  * Please do not remove this and leave it at the end of the file, where
205  * Emacs will automagically detect them.
206  * ---------------------------------------------------------------------
207  * Local variables:
208  * mode: c
209  * indent-tabs-mode: t
210  * c-basic-offset: 4
211  * tab-width: 4
212  * End:
213  * vim:noexpandtab:sw=4:ts=4:
214  */