1 /* -----------------------------------------------------------------------------
2 * $Id: StgMiscClosures.hc,v 1.29 1999/11/02 17:17:47 simonmar Exp $
4 * (c) The GHC Team, 1998-1999
6 * Entry code for various built-in closure types.
8 * ---------------------------------------------------------------------------*/
12 #include "StgMiscClosures.h"
13 #include "HeapStackCheck.h" /* for stg_gen_yield */
15 #include "StoragePriv.h"
23 /* ToDo: make the printing of panics more Win32-friendly, i.e.,
24 * pop up some lovely message boxes (as well).
26 #define DUMP_ERRMSG(msg) STGCALL2(fprintf,stderr,msg)
28 /* -----------------------------------------------------------------------------
29 Entry code for an indirection.
31 This code assumes R1 is in a register for now.
32 -------------------------------------------------------------------------- */
34 INFO_TABLE(IND_info,IND_entry,1,0,IND,,EF_,0,0);
38 TICK_ENT_IND(Node); /* tick */
40 R1.p = (P_) ((StgInd*)R1.p)->indirectee;
42 JMP_(ENTRY_CODE(*R1.p));
46 INFO_TABLE(IND_STATIC_info,IND_STATIC_entry,1,0,IND_STATIC,,EF_,0,0);
47 STGFUN(IND_STATIC_entry)
50 TICK_ENT_IND(Node); /* tick */
52 R1.p = (P_) ((StgIndStatic*)R1.p)->indirectee;
54 JMP_(ENTRY_CODE(*R1.p));
58 INFO_TABLE(IND_PERM_info,IND_PERM_entry,1,1,IND_PERM,,EF_,0,0);
59 STGFUN(IND_PERM_entry)
62 /* Don't add INDs to granularity cost */
63 /* Dont: TICK_ENT_IND(Node); for ticky-ticky; this ind is here only to help profiling */
65 #if defined(TICKY_TICKY) && !defined(PROFILING)
66 /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra */
67 TICK_ENT_PERM_IND(R1.p); /* tick */
70 /* Enter PAP cost centre -- lexical scoping only */
71 ENTER_CCS_PAP_CL(R1.cl);
73 /* For ticky-ticky, change the perm_ind to a normal ind on first
74 * entry, so the number of ent_perm_inds is the number of *thunks*
75 * entered again, not the number of subsequent entries.
77 * Since this screws up cost centres, we die if profiling and
78 * ticky_ticky are on at the same time. KSW 1999-01.
83 # error Profiling and ticky-ticky do not mix at present!
84 # endif /* PROFILING */
85 SET_INFO((StgInd*)R1.p,&IND_info);
86 #endif /* TICKY_TICKY */
88 R1.p = (P_) ((StgInd*)R1.p)->indirectee;
90 /* Dont: TICK_ENT_VIA_NODE(); for ticky-ticky; as above */
92 #if defined(TICKY_TICKY) && !defined(PROFILING)
96 JMP_(ENTRY_CODE(*R1.p));
100 INFO_TABLE(IND_OLDGEN_info,IND_OLDGEN_entry,1,1,IND_OLDGEN,,EF_,0,0);
101 STGFUN(IND_OLDGEN_entry)
104 TICK_ENT_IND(Node); /* tick */
106 R1.p = (P_) ((StgInd*)R1.p)->indirectee;
108 JMP_(ENTRY_CODE(*R1.p));
112 INFO_TABLE(IND_OLDGEN_PERM_info,IND_OLDGEN_PERM_entry,1,1,IND_OLDGEN_PERM,,EF_,0,0);
113 STGFUN(IND_OLDGEN_PERM_entry)
116 /* Dont: TICK_ENT_IND(Node); for ticky-ticky; this ind is here only to help profiling */
118 #if defined(TICKY_TICKY) && !defined(PROFILING)
119 /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra */
120 TICK_ENT_PERM_IND(R1.p); /* tick */
123 /* Enter PAP cost centre -- lexical scoping only */
124 ENTER_CCS_PAP_CL(R1.cl);
126 /* see comment in IND_PERM */
129 # error Profiling and ticky-ticky do not mix at present!
130 # endif /* PROFILING */
131 SET_INFO((StgInd*)R1.p,&IND_OLDGEN_info);
132 #endif /* TICKY_TICKY */
134 R1.p = (P_) ((StgInd*)R1.p)->indirectee;
136 JMP_(ENTRY_CODE(*R1.p));
140 /* -----------------------------------------------------------------------------
143 This code assumes R1 is in a register for now.
144 -------------------------------------------------------------------------- */
146 INFO_TABLE(CAF_UNENTERED_info,CAF_UNENTERED_entry,1,3,CAF_UNENTERED,,EF_,0,0);
147 STGFUN(CAF_UNENTERED_entry)
150 /* ToDo: implement directly in GHC */
153 JMP_(stg_yield_to_Hugs);
157 /* 0,4 is entirely bogus; _do not_ rely on this info */
158 INFO_TABLE(CAF_ENTERED_info,CAF_ENTERED_entry,0,4,CAF_ENTERED,,EF_,0,0);
159 STGFUN(CAF_ENTERED_entry)
162 R1.p = (P_) ((StgCAF*)R1.p)->value; /* just a fancy indirection */
164 JMP_(GET_ENTRY(R1.cl));
168 /* -----------------------------------------------------------------------------
169 Entry code for a black hole.
171 Entering a black hole normally causes a cyclic data dependency, but
172 in the concurrent world, black holes are synchronization points,
173 and they are turned into blocking queues when there are threads
174 waiting for the evaluation of the closure to finish.
175 -------------------------------------------------------------------------- */
177 /* Note: a BLACKHOLE and BLACKHOLE_BQ must be big enough to be
178 * overwritten with an indirection/evacuee/catch. Thus we claim it
179 * has 1 non-pointer word of payload (in addition to the pointer word
180 * for the blocking queue in a BQ), which should be big enough for an
181 * old-generation indirection.
184 INFO_TABLE(BLACKHOLE_info, BLACKHOLE_entry,0,2,BLACKHOLE,,EF_,0,0);
185 STGFUN(BLACKHOLE_entry)
189 CMPXCHG(R1.cl->header.info, &BLACKHOLE_info, &WHITEHOLE_info);
194 /* Put ourselves on the blocking queue for this black hole */
195 CurrentTSO->link = (StgTSO *)&END_TSO_QUEUE_closure;
196 ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
197 CurrentTSO->why_blocked = BlockedOnBlackHole;
198 CurrentTSO->block_info.closure = R1.cl;
199 recordMutable((StgMutClosure *)R1.cl);
200 /* Change the BLACKHOLE into a BLACKHOLE_BQ */
201 ((StgBlockingQueue *)R1.p)->header.info = &BLACKHOLE_BQ_info;
202 /* stg_gen_block is too heavyweight, use a specialised one */
207 INFO_TABLE(BLACKHOLE_BQ_info, BLACKHOLE_BQ_entry,1,1,BLACKHOLE_BQ,,EF_,0,0);
208 STGFUN(BLACKHOLE_BQ_entry)
212 CMPXCHG(R1.cl->header.info, &BLACKHOLE_BQ_info, &WHITEHOLE_info);
217 /* Put ourselves on the blocking queue for this black hole */
218 CurrentTSO->why_blocked = BlockedOnBlackHole;
219 CurrentTSO->block_info.closure = R1.cl;
220 CurrentTSO->link = ((StgBlockingQueue *)R1.p)->blocking_queue;
221 ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
223 ((StgBlockingQueue *)R1.p)->header.info = &BLACKHOLE_BQ_info;
226 /* stg_gen_block is too heavyweight, use a specialised one */
231 /* identical to BLACKHOLEs except for the infotag */
232 INFO_TABLE(CAF_BLACKHOLE_info, CAF_BLACKHOLE_entry,0,2,CAF_BLACKHOLE,,EF_,0,0);
233 STGFUN(CAF_BLACKHOLE_entry)
237 CMPXCHG(R1.cl->header.info, &CAF_BLACKHOLE_info, &WHITEHOLE_info);
241 /* Put ourselves on the blocking queue for this black hole */
242 CurrentTSO->link = (StgTSO *)&END_TSO_QUEUE_closure;
243 ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
244 CurrentTSO->why_blocked = BlockedOnBlackHole;
245 CurrentTSO->block_info.closure = R1.cl;
246 recordMutable((StgMutClosure *)R1.cl);
247 /* Change the CAF_BLACKHOLE into a BLACKHOLE_BQ */
248 ((StgBlockingQueue *)R1.p)->header.info = &BLACKHOLE_BQ_info;
249 /* stg_gen_block is too heavyweight, use a specialised one */
253 JMP_(BLACKHOLE_entry);
260 INFO_TABLE(SE_BLACKHOLE_info, SE_BLACKHOLE_entry,0,2,SE_BLACKHOLE,,EF_,0,0);
261 STGFUN(SE_BLACKHOLE_entry)
264 STGCALL3(fprintf,stderr,"SE_BLACKHOLE at %p entered!\n",R1.p);
265 STGCALL1(shutdownHaskellAndExit,EXIT_FAILURE);
269 INFO_TABLE(SE_CAF_BLACKHOLE_info, SE_CAF_BLACKHOLE_entry,0,2,SE_CAF_BLACKHOLE,,EF_,0,0);
270 STGFUN(SE_CAF_BLACKHOLE_entry)
273 STGCALL3(fprintf,stderr,"SE_CAF_BLACKHOLE at %p entered!\n",R1.p);
274 STGCALL1(shutdownHaskellAndExit,EXIT_FAILURE);
280 INFO_TABLE(WHITEHOLE_info, WHITEHOLE_entry,0,2,CONSTR_NOCAF_STATIC,,EF_,0,0);
281 STGFUN(WHITEHOLE_entry)
284 JMP_(GET_ENTRY(R1.cl));
289 /* -----------------------------------------------------------------------------
290 The code for a BCO returns to the scheduler
291 -------------------------------------------------------------------------- */
292 INFO_TABLE(BCO_info,BCO_entry,0,0,BCO,,EF_,0,0);
297 JMP_(stg_yield_to_Hugs);
301 /* -----------------------------------------------------------------------------
302 Some static info tables for things that don't get entered, and
303 therefore don't need entry code (i.e. boxed but unpointed objects)
304 -------------------------------------------------------------------------- */
306 #define NON_ENTERABLE_ENTRY_CODE(type) \
307 STGFUN(type##_entry) \
310 DUMP_ERRMSG(#type " object entered!\n"); \
311 STGCALL1(shutdownHaskellAndExit, EXIT_FAILURE); \
315 INFO_TABLE(TSO_info, TSO_entry, 0,0,TSO,,EF_,0,0);
316 NON_ENTERABLE_ENTRY_CODE(TSO);
318 /* -----------------------------------------------------------------------------
319 Evacuees are left behind by the garbage collector. Any attempt to enter
321 -------------------------------------------------------------------------- */
323 INFO_TABLE(EVACUATED_info,EVACUATED_entry,1,0,EVACUATED,,EF_,0,0);
324 NON_ENTERABLE_ENTRY_CODE(EVACUATED);
326 /* -----------------------------------------------------------------------------
329 Live weak pointers have a special closure type. Dead ones are just
330 nullary constructors (although they live on the heap - we overwrite
331 live weak pointers with dead ones).
332 -------------------------------------------------------------------------- */
334 INFO_TABLE(WEAK_info,WEAK_entry,0,4,WEAK,,EF_,0,0);
335 NON_ENTERABLE_ENTRY_CODE(WEAK);
337 INFO_TABLE_CONSTR(DEAD_WEAK_info,DEAD_WEAK_entry,0,1,0,CONSTR,,EF_,0,0);
338 NON_ENTERABLE_ENTRY_CODE(DEAD_WEAK);
340 /* -----------------------------------------------------------------------------
343 This is a static nullary constructor (like []) that we use to mark an empty
344 finalizer in a weak pointer object.
345 -------------------------------------------------------------------------- */
347 INFO_TABLE_CONSTR(NO_FINALIZER_info,NO_FINALIZER_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
348 NON_ENTERABLE_ENTRY_CODE(NO_FINALIZER);
350 SET_STATIC_HDR(NO_FINALIZER_closure,NO_FINALIZER_info,0/*CC*/,,EI_)
353 /* -----------------------------------------------------------------------------
354 Foreign Objects are unlifted and therefore never entered.
355 -------------------------------------------------------------------------- */
357 INFO_TABLE(FOREIGN_info,FOREIGN_entry,0,1,FOREIGN,,EF_,0,0);
358 NON_ENTERABLE_ENTRY_CODE(FOREIGN);
360 /* -----------------------------------------------------------------------------
361 Stable Names are unlifted too.
362 -------------------------------------------------------------------------- */
364 INFO_TABLE(STABLE_NAME_info,STABLE_NAME_entry,0,1,STABLE_NAME,,EF_,0,0);
365 NON_ENTERABLE_ENTRY_CODE(STABLE_NAME);
367 /* -----------------------------------------------------------------------------
370 There are two kinds of these: full and empty. We need an info table
371 and entry code for each type.
372 -------------------------------------------------------------------------- */
374 INFO_TABLE(FULL_MVAR_info,FULL_MVAR_entry,4,0,MVAR,,EF_,0,0);
375 NON_ENTERABLE_ENTRY_CODE(FULL_MVAR);
377 INFO_TABLE(EMPTY_MVAR_info,EMPTY_MVAR_entry,4,0,MVAR,,EF_,0,0);
378 NON_ENTERABLE_ENTRY_CODE(EMPTY_MVAR);
380 /* -----------------------------------------------------------------------------
383 This is a static nullary constructor (like []) that we use to mark the
384 end of a linked TSO queue.
385 -------------------------------------------------------------------------- */
387 INFO_TABLE_CONSTR(END_TSO_QUEUE_info,END_TSO_QUEUE_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
388 NON_ENTERABLE_ENTRY_CODE(END_TSO_QUEUE);
390 SET_STATIC_HDR(END_TSO_QUEUE_closure,END_TSO_QUEUE_info,0/*CC*/,,EI_)
393 /* -----------------------------------------------------------------------------
396 Mutable lists (used by the garbage collector) consist of a chain of
397 StgMutClosures connected through their mut_link fields, ending in
398 an END_MUT_LIST closure.
399 -------------------------------------------------------------------------- */
401 INFO_TABLE_CONSTR(END_MUT_LIST_info,END_MUT_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
402 NON_ENTERABLE_ENTRY_CODE(END_MUT_LIST);
404 SET_STATIC_HDR(END_MUT_LIST_closure,END_MUT_LIST_info,0/*CC*/,,EI_)
407 INFO_TABLE(MUT_CONS_info, MUT_CONS_entry, 1, 1, MUT_VAR, , EF_, 0, 0);
408 NON_ENTERABLE_ENTRY_CODE(MUT_CONS);
410 /* -----------------------------------------------------------------------------
412 -------------------------------------------------------------------------- */
414 INFO_TABLE_CONSTR(END_EXCEPTION_LIST_info,END_EXCEPTION_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
415 NON_ENTERABLE_ENTRY_CODE(END_EXCEPTION_LIST);
417 SET_STATIC_HDR(END_EXCEPTION_LIST_closure,END_EXCEPTION_LIST_info,0/*CC*/,,EI_)
420 INFO_TABLE(EXCEPTION_CONS_info, EXCEPTION_CONS_entry, 1, 1, CONSTR, , EF_, 0, 0);
421 NON_ENTERABLE_ENTRY_CODE(EXCEPTION_CONS);
423 /* -----------------------------------------------------------------------------
426 These come in two basic flavours: arrays of data (StgArrWords) and arrays of
427 pointers (StgArrPtrs). They all have a similar layout:
429 ___________________________
430 | Info | No. of | data....
432 ---------------------------
434 These are *unpointed* objects: i.e. they cannot be entered.
436 -------------------------------------------------------------------------- */
438 #define ArrayInfo(type) \
439 INFO_TABLE(type##_info, type##_entry, 0, 0, type, , EF_,0,0);
441 ArrayInfo(ARR_WORDS);
442 NON_ENTERABLE_ENTRY_CODE(ARR_WORDS);
443 ArrayInfo(MUT_ARR_PTRS);
444 NON_ENTERABLE_ENTRY_CODE(MUT_ARR_PTRS);
445 ArrayInfo(MUT_ARR_PTRS_FROZEN);
446 NON_ENTERABLE_ENTRY_CODE(MUT_ARR_PTRS_FROZEN);
450 /* -----------------------------------------------------------------------------
452 -------------------------------------------------------------------------- */
454 INFO_TABLE(MUT_VAR_info, MUT_VAR_entry, 1, 1, MUT_VAR, , EF_, 0, 0);
455 NON_ENTERABLE_ENTRY_CODE(MUT_VAR);
457 /* -----------------------------------------------------------------------------
458 Standard Error Entry.
460 This is used for filling in vector-table entries that can never happen,
462 -------------------------------------------------------------------------- */
464 STGFUN(stg_error_entry) \
467 DUMP_ERRMSG("fatal: stg_error_entry"); \
468 STGCALL1(shutdownHaskellAndExit, EXIT_FAILURE); \
472 /* -----------------------------------------------------------------------------
475 Entering this closure will just return to the address on the top of the
476 stack. Useful for getting a thread in a canonical form where we can
477 just enter the top stack word to start the thread. (see deleteThread)
478 * -------------------------------------------------------------------------- */
480 INFO_TABLE(dummy_ret_info, dummy_ret_entry, 0, 0, CONSTR_NOCAF_STATIC, , EF_, 0, 0);
487 JMP_(ENTRY_CODE(ret_addr));
490 SET_STATIC_HDR(dummy_ret_closure,dummy_ret_info,CCS_DONTZuCARE,,EI_)
493 /* -----------------------------------------------------------------------------
494 Strict IO application - performing an IO action and entering its result.
496 rts_evalIO() lets you perform Haskell IO actions from outside of Haskell-land,
497 returning back to you their result. Want this result to be evaluated to WHNF
498 by that time, so that we can easily get at the int/char/whatever using the
499 various get{Ty} functions provided by the RTS API.
501 forceIO takes care of this, performing the IO action and entering the
502 results that comes back.
504 * -------------------------------------------------------------------------- */
506 INFO_TABLE_SRT_BITMAP(forceIO_ret_info,forceIO_ret_entry,0,0,0,0,RET_SMALL,,EF_,0,0);
507 FN_(forceIO_ret_entry)
511 Sp -= sizeofW(StgSeqFrame);
513 JMP_(GET_ENTRY(R1.cl));
517 INFO_TABLE(forceIO_info,forceIO_entry,1,0,FUN,,EF_,0,0);
521 /* Sp[0] contains the IO action we want to perform */
523 /* Replace it with the return continuation that enters the result. */
524 Sp[0] = (W_)&forceIO_ret_info;
526 /* Push the RealWorld# tag and enter */
527 Sp[0] =(W_)REALWORLD_TAG;
528 JMP_(GET_ENTRY(R1.cl));
531 SET_STATIC_HDR(forceIO_closure,forceIO_info,CCS_DONTZuCARE,,EI_)
535 /* -----------------------------------------------------------------------------
536 Standard Infotables (for use in interpreter)
537 -------------------------------------------------------------------------- */
541 STGFUN(Hugs_CONSTR_entry)
543 /* R1 points at the constructor */
544 JMP_(ENTRY_CODE(((StgPtr*)Sp)[0]));
547 #define RET_BCO_ENTRY_TEMPLATE(label) \
552 ((StgPtr*)Sp)[0] = R1.p; \
553 JMP_(stg_yield_to_Hugs); \
557 RET_BCO_ENTRY_TEMPLATE(ret_bco_entry );
558 RET_BCO_ENTRY_TEMPLATE(ret_bco_0_entry);
559 RET_BCO_ENTRY_TEMPLATE(ret_bco_1_entry);
560 RET_BCO_ENTRY_TEMPLATE(ret_bco_2_entry);
561 RET_BCO_ENTRY_TEMPLATE(ret_bco_3_entry);
562 RET_BCO_ENTRY_TEMPLATE(ret_bco_4_entry);
563 RET_BCO_ENTRY_TEMPLATE(ret_bco_5_entry);
564 RET_BCO_ENTRY_TEMPLATE(ret_bco_6_entry);
565 RET_BCO_ENTRY_TEMPLATE(ret_bco_7_entry);
567 VEC_POLY_INFO_TABLE(ret_bco,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_);
569 #endif /* INTERPRETER */
573 INFO_TABLE_CONSTR(Czh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgChar),0,CONSTR,,EF_,0,0);
574 INFO_TABLE_CONSTR(Izh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgInt),0,CONSTR,,EF_,0,0);
575 INFO_TABLE_CONSTR(I64zh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgInt64),0,CONSTR,,EF_,0,0);
576 INFO_TABLE_CONSTR(Fzh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgFloat),0,CONSTR,,EF_,0,0);
577 INFO_TABLE_CONSTR(Dzh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgDouble),0,CONSTR,,EF_,0,0);
578 INFO_TABLE_CONSTR(Azh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgAddr),0,CONSTR,,EF_,0,0);
579 INFO_TABLE_CONSTR(Wzh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgWord),0,CONSTR,,EF_,0,0);
580 INFO_TABLE_CONSTR(StablePtr_con_info,Hugs_CONSTR_entry,0,sizeofW(StgStablePtr),0,CONSTR,,EF_,0,0);
582 /* These might seem redundant but {I,C}zh_static_info are used in
583 * {INT,CHAR}LIKE and the rest are used in RtsAPI.c
585 INFO_TABLE_CONSTR(Czh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgChar),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
586 INFO_TABLE_CONSTR(Izh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgInt),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
587 INFO_TABLE_CONSTR(I64zh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgInt64),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
588 INFO_TABLE_CONSTR(Fzh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgFloat),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
589 INFO_TABLE_CONSTR(Dzh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgDouble),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
590 INFO_TABLE_CONSTR(Azh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgAddr),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
591 INFO_TABLE_CONSTR(Wzh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgWord),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
592 INFO_TABLE_CONSTR(StablePtr_static_info,Hugs_CONSTR_entry,0,sizeofW(StgStablePtr),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
594 #endif /* !defined(COMPILER) */
596 /* -----------------------------------------------------------------------------
597 CHARLIKE and INTLIKE closures.
599 These are static representations of Chars and small Ints, so that
600 we can remove dynamic Chars and Ints during garbage collection and
601 replace them with references to the static objects.
602 -------------------------------------------------------------------------- */
604 #ifdef ENABLE_WIN32_DLL_SUPPORT
606 * When sticking the RTS in a DLL, we delay populating the
607 * Charlike and Intlike tables until load-time, which is only
608 * when we've got the real addresses to the C# and I# closures.
611 static INFO_TBL_CONST StgInfoTable czh_static_info;
612 static INFO_TBL_CONST StgInfoTable izh_static_info;
613 #define Char_hash_static_info czh_static_info
614 #define Int_hash_static_info izh_static_info
616 #define Char_hash_static_info Czh_static_info
617 #define Int_hash_static_info Izh_static_info
620 #define CHARLIKE_HDR(n) \
622 STATIC_HDR(Char_hash_static_info, /* C# */ \
627 #define INTLIKE_HDR(n) \
629 STATIC_HDR(Int_hash_static_info, /* I# */ \
634 /* put these in the *data* section, since the garbage collector relies
635 * on the fact that static closures live in the data section.
638 /* end the name with _closure, to convince the mangler this is a closure */
640 StgIntCharlikeClosure CHARLIKE_closure[] = {
899 StgIntCharlikeClosure INTLIKE_closure[] = {
900 INTLIKE_HDR(-16), /* MIN_INTLIKE == -16 */
932 INTLIKE_HDR(16) /* MAX_INTLIKE == 16 */