[project @ 2001-02-06 11:41:04 by rrt]
[ghc-hetmet.git] / ghc / includes / ClosureMacros.h
1 /* ----------------------------------------------------------------------------
2  * $Id: ClosureMacros.h,v 1.32 2001/02/06 11:41:04 rrt Exp $
3  *
4  * (c) The GHC Team, 1998-1999
5  *
6  * Macros for building and manipulating closures
7  *
8  * -------------------------------------------------------------------------- */
9
10 #ifndef CLOSUREMACROS_H
11 #define CLOSUREMACROS_H
12
13 /* Say whether the code comes before the heap; on mingwin this may not be the
14    case, not because of another random MS pathology, but because the static
15    program may reside in a DLL
16 */
17
18 /* -----------------------------------------------------------------------------
19    Info tables are slammed up against the entry code, and the label
20    for the info table is at the *end* of the table itself.  This
21    inline function adjusts an info pointer to point to the beginning
22    of the table, so we can use standard C structure indexing on it.
23
24    Note: this works for SRT info tables as long as you don't want to
25    access the SRT, since they are laid out the same with the SRT
26    pointer as the first word in the table.
27
28    NOTES ABOUT MANGLED C VS. MINI-INTERPRETER:
29
30    A couple of definitions:
31
32        "info pointer"    The first word of the closure.  Might point
33                          to either the end or the beginning of the
34                          info table, depending on whether we're using
35                          the mini interpretter or not.  GET_INFO(c)
36                          retrieves the info pointer of a closure.
37
38        "info table"      The info table structure associated with a
39                          closure.  This is always a pointer to the
40                          beginning of the structure, so we can
41                          use standard C structure indexing to pull out
42                          the fields.  get_itbl(c) returns a pointer to
43                          the info table for closure c.
44
45    An address of the form xxxx_info points to the end of the info
46    table or the beginning of the info table depending on whether we're
47    mangling or not respectively.  So, 
48
49          c->header.info = xxx_info 
50
51    makes absolute sense, whether mangling or not.
52  
53    -------------------------------------------------------------------------- */
54
55 #define INIT_INFO(i)  info : &(i)
56 #define SET_INFO(c,i) ((c)->header.info = (i))
57 #define GET_INFO(c)   ((c)->header.info)
58 #define GET_ENTRY(c)  (ENTRY_CODE(GET_INFO(c)))
59 #define get_itbl(c)   (INFO_PTR_TO_STRUCT((c)->header.info))
60
61 #ifdef TABLES_NEXT_TO_CODE
62 #define INIT_ENTRY(e)    code : {}
63 #define ENTRY_CODE(info) (info)
64 #define INFO_PTR_TO_STRUCT(info) ((StgInfoTable *)(info) - 1)
65 static __inline__ StgFunPtr get_entry(const StgInfoTable *itbl) {
66     return (StgFunPtr)(itbl+1);
67 }
68 #else
69 #define INIT_ENTRY(e)    entry : (F_)(e)
70 #define ENTRY_CODE(info) (((StgInfoTable *)info)->entry)
71 #define INFO_PTR_TO_STRUCT(info) ((StgInfoTable *)info)
72 static __inline__ StgFunPtr get_entry(const StgInfoTable *itbl) {
73     return itbl->entry;
74 }
75 #endif
76
77 /* -----------------------------------------------------------------------------
78    Macros for building closures
79    -------------------------------------------------------------------------- */
80
81 #ifdef PROFILING
82 #define SET_PROF_HDR(c,ccs_)            (c)->header.prof.ccs = ccs_
83 #define SET_STATIC_PROF_HDR(ccs_)       prof : { ccs : ccs_ },
84 #else
85 #define SET_PROF_HDR(c,ccs)
86 #define SET_STATIC_PROF_HDR(ccs)
87 #endif
88
89 #ifdef GRAN
90 #define SET_GRAN_HDR(c,pe)              (c)->header.gran.procs = pe
91 #define SET_STATIC_GRAN_HDR             gran : { procs : Everywhere },
92 #else
93 #define SET_GRAN_HDR(c,pe)
94 #define SET_STATIC_GRAN_HDR
95 #endif
96
97 #ifdef PAR
98 #define SET_PAR_HDR(c,stuff)
99 #define SET_STATIC_PAR_HDR(stuff)
100 #else
101 #define SET_PAR_HDR(c,stuff)
102 #define SET_STATIC_PAR_HDR(stuff)
103 #endif
104
105 #ifdef TICKY_TICKY
106 #define SET_TICKY_HDR(c,stuff)       /* old: (c)->header.ticky.updated = stuff */
107 #define SET_STATIC_TICKY_HDR(stuff)  /* old: ticky : { updated : stuff } */
108 #else
109 #define SET_TICKY_HDR(c,stuff)
110 #define SET_STATIC_TICKY_HDR(stuff)
111 #endif
112 #define SET_HDR(c,info,ccs)                             \
113    {                                                    \
114         SET_INFO(c,info);                               \
115         SET_GRAN_HDR((StgClosure *)(c),ThisPE);         \
116         SET_PAR_HDR((StgClosure *)(c),LOCAL_GA);        \
117         SET_PROF_HDR((StgClosure *)(c),ccs);            \
118         SET_TICKY_HDR((StgClosure *)(c),0);             \
119    }
120
121 #define SET_ARR_HDR(c,info,costCentreStack,n_words)     \
122    SET_HDR(c,info,costCentreStack);                     \
123    (c)->words = n_words;
124
125 /* -----------------------------------------------------------------------------
126    Static closures are defined as follows:
127
128
129    SET_STATIC_HDR(PrelBase_CZh_closure,PrelBase_CZh_info,costCentreStack,closure_class,info_class);
130
131    The info argument must have type 'StgInfoTable' or
132    'StgSRTInfoTable', since we use '&' to get its address in the macro.
133    -------------------------------------------------------------------------- */
134
135 #define SET_STATIC_HDR(label,info,costCentreStack,closure_class,info_class)     \
136    info_class info;                                                             \
137    closure_class StgClosure label = {                                           \
138    STATIC_HDR(info,costCentreStack)
139
140 #define STATIC_HDR(info,ccs)                    \
141         header : {                              \
142                 INIT_INFO(info),                \
143                 SET_STATIC_GRAN_HDR             \
144                 SET_STATIC_PAR_HDR(LOCAL_GA)    \
145                 SET_STATIC_PROF_HDR(ccs)        \
146                 SET_STATIC_TICKY_HDR(0)         \
147         }
148
149 /* how to get hold of the static link field for a static closure.
150  *
151  * Note that we have to use (*cast(T*,&e)) instead of cast(T,e)
152  * because C won't let us take the address of a casted expression. Huh?
153  */
154 #define STATIC_LINK(info,p)                                             \
155    (*(StgClosure**)(&((p)->payload[info->layout.payload.ptrs +          \
156                                         info->layout.payload.nptrs])))
157
158 /* These macros are optimised versions of the above for certain
159  * closure types.  They *must* be equivalent to the generic
160  * STATIC_LINK.
161  */
162 #define FUN_STATIC_LINK(p)   ((p)->payload[0])
163 #define THUNK_STATIC_LINK(p) ((p)->payload[2])
164 #define IND_STATIC_LINK(p)   ((p)->payload[1])
165
166 #define STATIC_LINK2(info,p)                                                    \
167    (*(StgClosure**)(&((p)->payload[info->layout.payload.ptrs +                  \
168                                         info->layout.payload.nptrs + 1])))
169
170 /* -----------------------------------------------------------------------------
171    INTLIKE and CHARLIKE closures.
172    -------------------------------------------------------------------------- */
173
174 #define CHARLIKE_CLOSURE(n) ((P_)&stg_CHARLIKE_closure[(n)-MIN_CHARLIKE])
175 #define INTLIKE_CLOSURE(n)  ((P_)&stg_INTLIKE_closure[(n)-MIN_INTLIKE])
176
177 /* -----------------------------------------------------------------------------
178    Closure Tables (for enumerated data types)
179    -------------------------------------------------------------------------- */
180
181 #define CLOSURE_TBL(lbl) const StgClosure *lbl[] = {
182
183 /* -----------------------------------------------------------------------------
184    CONSTRs.
185    -------------------------------------------------------------------------- */
186
187 /* constructors don't have SRTs */
188 #define GET_TAG(info) (INFO_PTR_TO_STRUCT(info)->srt_len)
189
190 #endif /* CLOSUREMACROS_H */