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