1 /* ----------------------------------------------------------------------------
2 * $Id: ClosureMacros.h,v 1.30 2000/12/11 12:36:59 simonmar Exp $
4 * (c) The GHC Team, 1998-1999
6 * Macros for building and manipulating closures
8 * -------------------------------------------------------------------------- */
10 #ifndef CLOSUREMACROS_H
11 #define CLOSUREMACROS_H
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
18 #undef TEXT_BEFORE_HEAP
19 #ifndef mingw32_TARGET_OS
20 #define TEXT_BEFORE_HEAP 1
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.
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.
33 NOTES ABOUT MANGLED C VS. MINI-INTERPRETER:
35 A couple of definitions:
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.
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.
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,
54 c->header.info = xxx_info
56 makes absolute sense, whether mangling or not.
58 -------------------------------------------------------------------------- */
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))
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);
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) {
82 /* -----------------------------------------------------------------------------
83 Macros for building closures
84 -------------------------------------------------------------------------- */
87 #define SET_PROF_HDR(c,ccs_) (c)->header.prof.ccs = ccs_
88 #define SET_STATIC_PROF_HDR(ccs_) prof : { ccs : ccs_ },
90 #define SET_PROF_HDR(c,ccs)
91 #define SET_STATIC_PROF_HDR(ccs)
95 #define SET_GRAN_HDR(c,pe) (c)->header.gran.procs = pe
96 #define SET_STATIC_GRAN_HDR gran : { procs : Everywhere },
98 #define SET_GRAN_HDR(c,pe)
99 #define SET_STATIC_GRAN_HDR
103 #define SET_PAR_HDR(c,stuff)
104 #define SET_STATIC_PAR_HDR(stuff)
106 #define SET_PAR_HDR(c,stuff)
107 #define SET_STATIC_PAR_HDR(stuff)
111 #define SET_TICKY_HDR(c,stuff) /* old: (c)->header.ticky.updated = stuff */
112 #define SET_STATIC_TICKY_HDR(stuff) /* old: ticky : { updated : stuff } */
114 #define SET_TICKY_HDR(c,stuff)
115 #define SET_STATIC_TICKY_HDR(stuff)
117 #define SET_HDR(c,info,ccs) \
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); \
126 #define SET_ARR_HDR(c,info,costCentreStack,n_words) \
127 SET_HDR(c,info,costCentreStack); \
128 (c)->words = n_words;
130 /* -----------------------------------------------------------------------------
131 Static closures are defined as follows:
134 SET_STATIC_HDR(PrelBase_CZh_closure,PrelBase_CZh_info,costCentreStack,const);
136 The info argument must have type 'StgInfoTable' or
137 'StgSRTInfoTable', since we use '&' to get its address in the macro.
138 -------------------------------------------------------------------------- */
140 #define SET_STATIC_HDR(label,info,costCentreStack,closure_class,info_class) \
142 closure_class StgClosure label = { \
143 STATIC_HDR(info,costCentreStack)
145 #define STATIC_HDR(info,ccs) \
148 SET_STATIC_GRAN_HDR \
149 SET_STATIC_PAR_HDR(LOCAL_GA) \
150 SET_STATIC_PROF_HDR(ccs) \
151 SET_STATIC_TICKY_HDR(0) \
154 /* how to get hold of the static link field for a static closure.
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?
159 #define STATIC_LINK(info,p) \
160 (*(StgClosure**)(&((p)->payload[info->layout.payload.ptrs + \
161 info->layout.payload.nptrs])))
163 /* These macros are optimised versions of the above for certain
164 * closure types. They *must* be equivalent to the generic
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])
171 #define STATIC_LINK2(info,p) \
172 (*(StgClosure**)(&((p)->payload[info->layout.payload.ptrs + \
173 info->layout.payload.nptrs + 1])))
175 /* -----------------------------------------------------------------------------
176 INTLIKE and CHARLIKE closures.
177 -------------------------------------------------------------------------- */
179 #define CHARLIKE_CLOSURE(n) ((P_)&stg_CHARLIKE_closure[(n)-MIN_CHARLIKE])
180 #define INTLIKE_CLOSURE(n) ((P_)&stg_INTLIKE_closure[(n)-MIN_INTLIKE])
182 /* -----------------------------------------------------------------------------
183 Closure Tables (for enumerated data types)
184 -------------------------------------------------------------------------- */
186 #define CLOSURE_TBL(lbl) const StgClosure *lbl[] = {
188 /* -----------------------------------------------------------------------------
190 -------------------------------------------------------------------------- */
192 /* constructors don't have SRTs */
193 #define GET_TAG(info) (INFO_PTR_TO_STRUCT(info)->srt_len)
195 #endif /* CLOSUREMACROS_H */