[project @ 2000-03-01 16:57:57 by sewardj]
[ghc-hetmet.git] / ghc / rts / StgMiscClosures.hc
1 /* -----------------------------------------------------------------------------
2  * $Id: StgMiscClosures.hc,v 1.36 2000/03/01 16:57:57 sewardj Exp $
3  *
4  * (c) The GHC Team, 1998-1999
5  *
6  * Entry code for various built-in closure types.
7  *
8  * ---------------------------------------------------------------------------*/
9
10 #include "Rts.h"
11 #include "RtsUtils.h"
12 #include "RtsFlags.h"
13 #include "StgMiscClosures.h"
14 #include "HeapStackCheck.h"   /* for stg_gen_yield */
15 #include "Storage.h"
16 #include "StoragePriv.h"
17 #include "ProfRts.h"
18 #include "SMP.h"
19 #if defined(GRAN) || defined(PAR)
20 # include "GranSimRts.h"      /* for DumpRawGranEvent */
21 # include "StgRun.h"    /* for StgReturn and register saving */
22 #endif
23
24 #ifdef HAVE_STDIO_H
25 #include <stdio.h>
26 #endif
27
28 /* ToDo: make the printing of panics more Win32-friendly, i.e.,
29  *       pop up some lovely message boxes (as well).
30  */
31 #define DUMP_ERRMSG(msg) STGCALL2(fprintf,stderr,msg)
32
33 /*
34   Template for the entry code of non-enterable closures.
35 */
36
37 #define NON_ENTERABLE_ENTRY_CODE(type)                                  \
38 STGFUN(type##_entry)                                                    \
39 {                                                                       \
40   FB_                                                                   \
41     DUMP_ERRMSG(#type " object entered!\n");                            \
42     STGCALL1(shutdownHaskellAndExit, EXIT_FAILURE);                     \
43   FE_                                                                   \
44 }
45
46 /* -----------------------------------------------------------------------------
47    Entry code for an indirection.
48
49    This code assumes R1 is in a register for now.
50    -------------------------------------------------------------------------- */
51
52 INFO_TABLE(IND_info,IND_entry,1,0,IND,,EF_,0,0);
53 STGFUN(IND_entry)
54 {
55     FB_
56     TICK_ENT_IND(Node); /* tick */
57
58     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
59     TICK_ENT_VIA_NODE();
60     JMP_(ENTRY_CODE(*R1.p));
61     FE_
62 }
63
64 INFO_TABLE(IND_STATIC_info,IND_STATIC_entry,1,0,IND_STATIC,,EF_,0,0);
65 STGFUN(IND_STATIC_entry)
66 {
67     FB_
68     TICK_ENT_IND(Node); /* tick */
69   
70     R1.p = (P_) ((StgIndStatic*)R1.p)->indirectee;
71     TICK_ENT_VIA_NODE();
72     JMP_(ENTRY_CODE(*R1.p));
73     FE_
74 }
75
76 INFO_TABLE(IND_PERM_info,IND_PERM_entry,1,1,IND_PERM,,EF_,0,0);
77 STGFUN(IND_PERM_entry)
78 {
79     FB_
80     /* Don't add INDs to granularity cost */
81     /* Dont: TICK_ENT_IND(Node); for ticky-ticky; this ind is here only to help profiling */
82
83 #if defined(TICKY_TICKY) && !defined(PROFILING)
84     /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra  */
85     TICK_ENT_PERM_IND(R1.p); /* tick */
86 #endif
87
88     /* Enter PAP cost centre -- lexical scoping only */
89     ENTER_CCS_PAP_CL(R1.cl);
90
91     /* For ticky-ticky, change the perm_ind to a normal ind on first
92      * entry, so the number of ent_perm_inds is the number of *thunks*
93      * entered again, not the number of subsequent entries.
94      *
95      * Since this screws up cost centres, we die if profiling and
96      * ticky_ticky are on at the same time.  KSW 1999-01.
97      */
98
99 #ifdef TICKY_TICKY
100 #  ifdef PROFILING
101 #    error Profiling and ticky-ticky do not mix at present!
102 #  endif  /* PROFILING */
103     SET_INFO((StgInd*)R1.p,&IND_info);
104 #endif /* TICKY_TICKY */
105
106     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
107
108     /* Dont: TICK_ENT_VIA_NODE(); for ticky-ticky; as above */
109
110 #if defined(TICKY_TICKY) && !defined(PROFILING)
111     TICK_ENT_VIA_NODE();
112 #endif
113
114     JMP_(ENTRY_CODE(*R1.p));
115     FE_
116 }  
117
118 INFO_TABLE(IND_OLDGEN_info,IND_OLDGEN_entry,1,1,IND_OLDGEN,,EF_,0,0);
119 STGFUN(IND_OLDGEN_entry)
120 {
121     FB_
122     TICK_ENT_IND(Node); /* tick */
123   
124     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
125     TICK_ENT_VIA_NODE();
126     JMP_(ENTRY_CODE(*R1.p));
127     FE_
128 }
129
130 INFO_TABLE(IND_OLDGEN_PERM_info,IND_OLDGEN_PERM_entry,1,1,IND_OLDGEN_PERM,,EF_,0,0);
131 STGFUN(IND_OLDGEN_PERM_entry)
132 {
133     FB_
134     /* Dont: TICK_ENT_IND(Node); for ticky-ticky; this ind is here only to help profiling */
135
136 #if defined(TICKY_TICKY) && !defined(PROFILING)
137     /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra  */
138     TICK_ENT_PERM_IND(R1.p); /* tick */
139 #endif
140   
141     /* Enter PAP cost centre -- lexical scoping only */
142     ENTER_CCS_PAP_CL(R1.cl);
143
144     /* see comment in IND_PERM */
145 #ifdef TICKY_TICKY
146 #  ifdef PROFILING
147 #    error Profiling and ticky-ticky do not mix at present!
148 #  endif  /* PROFILING */
149     SET_INFO((StgInd*)R1.p,&IND_OLDGEN_info);
150 #endif /* TICKY_TICKY */
151
152     R1.p = (P_) ((StgInd*)R1.p)->indirectee;
153     TICK_ENT_VIA_NODE();
154     JMP_(ENTRY_CODE(*R1.p));
155     FE_
156 }
157
158 /* -----------------------------------------------------------------------------
159    Entry code for CAFs
160
161    This code assumes R1 is in a register for now.
162    -------------------------------------------------------------------------- */
163
164 INFO_TABLE(CAF_UNENTERED_info,CAF_UNENTERED_entry,1,3,CAF_UNENTERED,,EF_,0,0);
165 STGFUN(CAF_UNENTERED_entry)
166 {
167     FB_
168     /* ToDo: implement directly in GHC */
169     Sp -= 1;
170     Sp[0] = R1.w;
171     JMP_(stg_yield_to_Hugs);
172     FE_
173 }
174
175 /* 0,4 is entirely bogus; _do not_ rely on this info */
176 INFO_TABLE(CAF_ENTERED_info,CAF_ENTERED_entry,0,4,CAF_ENTERED,,EF_,0,0);
177 STGFUN(CAF_ENTERED_entry)
178 {
179     FB_
180     R1.p = (P_) ((StgCAF*)R1.p)->value; /* just a fancy indirection */
181     TICK_ENT_VIA_NODE();
182     JMP_(GET_ENTRY(R1.cl));
183     FE_
184 }
185
186 /* -----------------------------------------------------------------------------
187    Entry code for a black hole.
188
189    Entering a black hole normally causes a cyclic data dependency, but
190    in the concurrent world, black holes are synchronization points,
191    and they are turned into blocking queues when there are threads
192    waiting for the evaluation of the closure to finish.
193    -------------------------------------------------------------------------- */
194
195 /* Note: a BLACKHOLE and BLACKHOLE_BQ must be big enough to be
196  * overwritten with an indirection/evacuee/catch.  Thus we claim it
197  * has 1 non-pointer word of payload (in addition to the pointer word
198  * for the blocking queue in a BQ), which should be big enough for an
199  * old-generation indirection. 
200  */
201
202 INFO_TABLE(BLACKHOLE_info, BLACKHOLE_entry,0,2,BLACKHOLE,,EF_,0,0);
203 STGFUN(BLACKHOLE_entry)
204 {
205   FB_
206 #if defined(GRAN)
207     /* Before overwriting TSO_LINK */
208     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
209 #endif
210
211 #ifdef SMP
212     {
213       bdescr *bd = Bdescr(R1.p);
214       if (bd->back != (bdescr *)BaseReg) {
215         if (bd->gen->no >= 1 || bd->step->no >= 1) {
216           CMPXCHG(R1.cl->header.info, &BLACKHOLE_info, &WHITEHOLE_info);
217         } else {
218           EXTFUN_RTS(stg_gc_enter_1_hponly);
219           JMP_(stg_gc_enter_1_hponly);
220         }
221       }
222     }
223 #endif
224     TICK_ENT_BH();
225
226     /* Put ourselves on the blocking queue for this black hole */
227 #if defined(GRAN) || defined(PAR)
228     /* in fact, only difference is the type of the end-of-queue marker! */
229     CurrentTSO->link = END_BQ_QUEUE;
230     ((StgBlockingQueue *)R1.p)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO;
231 #else
232     CurrentTSO->link = END_TSO_QUEUE;
233     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
234 #endif
235     /* jot down why and on what closure we are blocked */
236     CurrentTSO->why_blocked = BlockedOnBlackHole;
237     CurrentTSO->block_info.closure = R1.cl;
238     /* closure is mutable since something has just been added to its BQ */
239     recordMutable((StgMutClosure *)R1.cl);
240     /* Change the BLACKHOLE into a BLACKHOLE_BQ */
241     ((StgBlockingQueue *)R1.p)->header.info = &BLACKHOLE_BQ_info;
242
243 #if defined(PAR)
244     /* Save the Thread State here, before calling RTS routines below! */
245     SAVE_THREAD_STATE(1);
246
247     /* if collecting stats update the execution time etc */
248     if (RtsFlags.ParFlags.ParStats.Full) {
249       /* Note that CURRENT_TIME may perform an unsafe call */
250       //rtsTime now = CURRENT_TIME; /* Now */
251       CurrentTSO->par.exectime += CURRENT_TIME - CurrentTSO->par.blockedat;
252       CurrentTSO->par.blockcount++;
253       CurrentTSO->par.blockedat = CURRENT_TIME;
254       DumpRawGranEvent(CURRENT_PROC, thisPE,
255                        GR_BLOCK, CurrentTSO, (StgClosure *)R1.p, 0);
256     }
257
258     THREAD_RETURN(1);  /* back to the scheduler */  
259 #else
260     /* stg_gen_block is too heavyweight, use a specialised one */
261     BLOCK_NP(1);
262 #endif
263
264   FE_
265 }
266
267 INFO_TABLE(BLACKHOLE_BQ_info, BLACKHOLE_BQ_entry,1,1,BLACKHOLE_BQ,,EF_,0,0);
268 STGFUN(BLACKHOLE_BQ_entry)
269 {
270   FB_
271 #if defined(GRAN)
272     /* Before overwriting TSO_LINK */
273     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
274 #endif
275
276 #ifdef SMP
277     {
278       bdescr *bd = Bdescr(R1.p);
279       if (bd->back != (bdescr *)BaseReg) {
280         if (bd->gen->no >= 1 || bd->step->no >= 1) {
281           CMPXCHG(R1.cl->header.info, &BLACKHOLE_info, &WHITEHOLE_info);
282         } else {
283           EXTFUN_RTS(stg_gc_enter_1_hponly);
284           JMP_(stg_gc_enter_1_hponly);
285         }
286       }
287     }
288 #endif
289
290     TICK_ENT_BH();
291
292     /* Put ourselves on the blocking queue for this black hole */
293     CurrentTSO->link = ((StgBlockingQueue *)R1.p)->blocking_queue;
294     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
295     /* jot down why and on what closure we are blocked */
296     CurrentTSO->why_blocked = BlockedOnBlackHole;
297     CurrentTSO->block_info.closure = R1.cl;
298 #ifdef SMP
299     ((StgBlockingQueue *)R1.p)->header.info = &BLACKHOLE_BQ_info;
300 #endif
301
302 #if defined(PAR)
303     /* Save the Thread State here, before calling RTS routines below! */
304     SAVE_THREAD_STATE(1);
305
306     /* if collecting stats update the execution time etc */
307     if (RtsFlags.ParFlags.ParStats.Full) {
308       /* Note that CURRENT_TIME may perform an unsafe call */
309       //rtsTime now = CURRENT_TIME; /* Now */
310       CurrentTSO->par.exectime += CURRENT_TIME - CurrentTSO->par.blockedat;
311       CurrentTSO->par.blockcount++;
312       CurrentTSO->par.blockedat = CURRENT_TIME;
313       DumpRawGranEvent(CURRENT_PROC, thisPE,
314                        GR_BLOCK, CurrentTSO, (StgClosure *)R1.p, 0);
315     }
316
317     THREAD_RETURN(1);  /* back to the scheduler */  
318 #else
319     /* stg_gen_block is too heavyweight, use a specialised one */
320     BLOCK_NP(1);
321 #endif
322   FE_
323 }
324
325 /*
326    Revertible black holes are needed in the parallel world, to handle
327    negative acknowledgements of messages containing updatable closures.
328    The idea is that when the original message is transmitted, the closure
329    is turned into a revertible black hole...an object which acts like a
330    black hole when local threads try to enter it, but which can be reverted
331    back to the original closure if necessary.
332
333    It's actually a lot like a blocking queue (BQ) entry, because revertible
334    black holes are initially set up with an empty blocking queue.
335 */
336
337 #if defined(PAR) || defined(GRAN)
338
339 INFO_TABLE(RBH_info, RBH_entry,1,1,RBH,,EF_,0,0);
340 STGFUN(RBH_entry)
341 {
342   FB_
343 # if defined(GRAN)
344     /* mainly statistics gathering for GranSim simulation */
345     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
346 # endif
347
348     /* exactly the same as a BLACKHOLE_BQ_entry -- HWL */
349     /* Put ourselves on the blocking queue for this black hole */
350     CurrentTSO->link = ((StgBlockingQueue *)R1.p)->blocking_queue;
351     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
352     /* jot down why and on what closure we are blocked */
353     CurrentTSO->why_blocked = BlockedOnBlackHole;
354     CurrentTSO->block_info.closure = R1.cl;
355
356 #if defined(PAR)
357     /* Save the Thread State here, before calling RTS routines below! */
358     SAVE_THREAD_STATE(1);
359
360     /* if collecting stats update the execution time etc */
361     if (RtsFlags.ParFlags.ParStats.Full) {
362       /* Note that CURRENT_TIME may perform an unsafe call */
363       //rtsTime now = CURRENT_TIME; /* Now */
364       CurrentTSO->par.exectime += CURRENT_TIME - CurrentTSO->par.blockedat;
365       CurrentTSO->par.blockcount++;
366       CurrentTSO->par.blockedat = CURRENT_TIME;
367       DumpRawGranEvent(CURRENT_PROC, thisPE,
368                        GR_BLOCK, CurrentTSO, (StgClosure *)R1.p, 0);
369     }
370
371     THREAD_RETURN(1);  /* back to the scheduler */  
372 #else
373     /* saves thread state and leaves thread in ThreadEnterGHC state; */
374     /* stg_gen_block is too heavyweight, use a specialised one */
375     BLOCK_NP(1); 
376 #endif
377
378   FE_
379 }
380
381 INFO_TABLE(RBH_Save_0_info, RBH_Save_0_entry,0,2,CONSTR,,EF_,0,0);
382 NON_ENTERABLE_ENTRY_CODE(RBH_Save_0);
383
384 INFO_TABLE(RBH_Save_1_info, RBH_Save_1_entry,1,1,CONSTR,,EF_,0,0);
385 NON_ENTERABLE_ENTRY_CODE(RBH_Save_1);
386
387 INFO_TABLE(RBH_Save_2_info, RBH_Save_2_entry,2,0,CONSTR,,EF_,0,0);
388 NON_ENTERABLE_ENTRY_CODE(RBH_Save_2);
389 #endif /* defined(PAR) || defined(GRAN) */
390
391 /* identical to BLACKHOLEs except for the infotag */
392 INFO_TABLE(CAF_BLACKHOLE_info, CAF_BLACKHOLE_entry,0,2,CAF_BLACKHOLE,,EF_,0,0);
393 STGFUN(CAF_BLACKHOLE_entry)
394 {
395   FB_
396 #if defined(GRAN)
397     /* mainly statistics gathering for GranSim simulation */
398     STGCALL3(GranSimBlock,CurrentTSO,CurrentProc,(StgClosure *)R1.p /*Node*/);
399 #endif
400
401 #ifdef SMP
402     {
403       bdescr *bd = Bdescr(R1.p);
404       if (bd->back != (bdescr *)BaseReg) {
405         if (bd->gen->no >= 1 || bd->step->no >= 1) {
406           CMPXCHG(R1.cl->header.info, &CAF_BLACKHOLE_info, &WHITEHOLE_info);
407         } else {
408           EXTFUN_RTS(stg_gc_enter_1_hponly);
409           JMP_(stg_gc_enter_1_hponly);
410         }
411       }
412     }
413 #endif
414
415     TICK_ENT_BH();
416
417     /* Put ourselves on the blocking queue for this black hole */
418 #if defined(GRAN) || defined(PAR)
419     /* in fact, only difference is the type of the end-of-queue marker! */
420     CurrentTSO->link = END_BQ_QUEUE;
421     ((StgBlockingQueue *)R1.p)->blocking_queue = (StgBlockingQueueElement *)CurrentTSO;
422 #else
423     CurrentTSO->link = END_TSO_QUEUE;
424     ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
425 #endif
426     /* jot down why and on what closure we are blocked */
427     CurrentTSO->why_blocked = BlockedOnBlackHole;
428     CurrentTSO->block_info.closure = R1.cl;
429     /* closure is mutable since something has just been added to its BQ */
430     recordMutable((StgMutClosure *)R1.cl);
431     /* Change the CAF_BLACKHOLE into a BLACKHOLE_BQ */
432     ((StgBlockingQueue *)R1.p)->header.info = &BLACKHOLE_BQ_info;
433
434 #if defined(PAR)
435     /* Save the Thread State here, before calling RTS routines below! */
436     SAVE_THREAD_STATE(1);
437
438     /* if collecting stats update the execution time etc */
439     if (RtsFlags.ParFlags.ParStats.Full) {
440       /* Note that CURRENT_TIME may perform an unsafe call */
441       //rtsTime now = CURRENT_TIME; /* Now */
442       CurrentTSO->par.exectime += CURRENT_TIME - CurrentTSO->par.blockedat;
443       CurrentTSO->par.blockcount++;
444       CurrentTSO->par.blockedat = CURRENT_TIME;
445       DumpRawGranEvent(CURRENT_PROC, thisPE,
446                        GR_BLOCK, CurrentTSO, (StgClosure *)R1.p, 0);
447     }
448
449     THREAD_RETURN(1);  /* back to the scheduler */  
450 #else
451     /* stg_gen_block is too heavyweight, use a specialised one */
452     BLOCK_NP(1);
453 #endif
454
455   FE_
456 }
457
458 #ifdef TICKY_TICKY
459 INFO_TABLE(SE_BLACKHOLE_info, SE_BLACKHOLE_entry,0,2,SE_BLACKHOLE,,EF_,0,0);
460 STGFUN(SE_BLACKHOLE_entry)
461 {
462   FB_
463     STGCALL3(fprintf,stderr,"SE_BLACKHOLE at %p entered!\n",R1.p);
464     STGCALL1(shutdownHaskellAndExit,EXIT_FAILURE);
465   FE_
466 }
467
468 INFO_TABLE(SE_CAF_BLACKHOLE_info, SE_CAF_BLACKHOLE_entry,0,2,SE_CAF_BLACKHOLE,,EF_,0,0);
469 STGFUN(SE_CAF_BLACKHOLE_entry)
470 {
471   FB_
472     STGCALL3(fprintf,stderr,"SE_CAF_BLACKHOLE at %p entered!\n",R1.p);
473     STGCALL1(shutdownHaskellAndExit,EXIT_FAILURE);
474   FE_
475 }
476 #endif
477
478 #ifdef SMP
479 INFO_TABLE(WHITEHOLE_info, WHITEHOLE_entry,0,2,CONSTR_NOCAF_STATIC,,EF_,0,0);
480 STGFUN(WHITEHOLE_entry)
481 {
482   FB_
483      JMP_(GET_ENTRY(R1.cl));
484   FE_
485 }
486 #endif
487
488 /* -----------------------------------------------------------------------------
489    The code for a BCO returns to the scheduler
490    -------------------------------------------------------------------------- */
491 INFO_TABLE(BCO_info,BCO_entry,0,0,BCO,,EF_,0,0);
492 EF_(BCO_entry) {                                
493   FB_   
494     Sp -= 1;
495     Sp[0] = R1.w;
496     JMP_(stg_yield_to_Hugs);
497   FE_                                                           
498 }
499
500 /* -----------------------------------------------------------------------------
501    Some static info tables for things that don't get entered, and
502    therefore don't need entry code (i.e. boxed but unpointed objects)
503    NON_ENTERABLE_ENTRY_CODE now defined at the beginning of the file
504    -------------------------------------------------------------------------- */
505
506 INFO_TABLE(TSO_info, TSO_entry, 0,0,TSO,,EF_,0,0);
507 NON_ENTERABLE_ENTRY_CODE(TSO);
508
509 /* -----------------------------------------------------------------------------
510    Evacuees are left behind by the garbage collector.  Any attempt to enter
511    one is a real bug.
512    -------------------------------------------------------------------------- */
513
514 INFO_TABLE(EVACUATED_info,EVACUATED_entry,1,0,EVACUATED,,EF_,0,0);
515 NON_ENTERABLE_ENTRY_CODE(EVACUATED);
516
517 /* -----------------------------------------------------------------------------
518    Weak pointers
519
520    Live weak pointers have a special closure type.  Dead ones are just
521    nullary constructors (although they live on the heap - we overwrite
522    live weak pointers with dead ones).
523    -------------------------------------------------------------------------- */
524
525 INFO_TABLE(WEAK_info,WEAK_entry,0,4,WEAK,,EF_,0,0);
526 NON_ENTERABLE_ENTRY_CODE(WEAK);
527
528 INFO_TABLE_CONSTR(DEAD_WEAK_info,DEAD_WEAK_entry,0,1,0,CONSTR,,EF_,0,0);
529 NON_ENTERABLE_ENTRY_CODE(DEAD_WEAK);
530
531 /* -----------------------------------------------------------------------------
532    NO_FINALIZER
533
534    This is a static nullary constructor (like []) that we use to mark an empty
535    finalizer in a weak pointer object.
536    -------------------------------------------------------------------------- */
537
538 INFO_TABLE_CONSTR(NO_FINALIZER_info,NO_FINALIZER_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
539 NON_ENTERABLE_ENTRY_CODE(NO_FINALIZER);
540
541 SET_STATIC_HDR(NO_FINALIZER_closure,NO_FINALIZER_info,0/*CC*/,,EI_)
542 , /*payload*/{} };
543
544 /* -----------------------------------------------------------------------------
545    Foreign Objects are unlifted and therefore never entered.
546    -------------------------------------------------------------------------- */
547
548 INFO_TABLE(FOREIGN_info,FOREIGN_entry,0,1,FOREIGN,,EF_,0,0);
549 NON_ENTERABLE_ENTRY_CODE(FOREIGN);
550
551 /* -----------------------------------------------------------------------------
552    Stable Names are unlifted too.
553    -------------------------------------------------------------------------- */
554
555 INFO_TABLE(STABLE_NAME_info,STABLE_NAME_entry,0,1,STABLE_NAME,,EF_,0,0);
556 NON_ENTERABLE_ENTRY_CODE(STABLE_NAME);
557
558 /* -----------------------------------------------------------------------------
559    MVars
560
561    There are two kinds of these: full and empty.  We need an info table
562    and entry code for each type.
563    -------------------------------------------------------------------------- */
564
565 INFO_TABLE(FULL_MVAR_info,FULL_MVAR_entry,4,0,MVAR,,EF_,0,0);
566 NON_ENTERABLE_ENTRY_CODE(FULL_MVAR);
567
568 INFO_TABLE(EMPTY_MVAR_info,EMPTY_MVAR_entry,4,0,MVAR,,EF_,0,0);
569 NON_ENTERABLE_ENTRY_CODE(EMPTY_MVAR);
570
571 /* -----------------------------------------------------------------------------
572    END_TSO_QUEUE
573
574    This is a static nullary constructor (like []) that we use to mark the
575    end of a linked TSO queue.
576    -------------------------------------------------------------------------- */
577
578 INFO_TABLE_CONSTR(END_TSO_QUEUE_info,END_TSO_QUEUE_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
579 NON_ENTERABLE_ENTRY_CODE(END_TSO_QUEUE);
580
581 SET_STATIC_HDR(END_TSO_QUEUE_closure,END_TSO_QUEUE_info,0/*CC*/,,EI_)
582 , /*payload*/{} };
583
584 /* -----------------------------------------------------------------------------
585    Mutable lists
586
587    Mutable lists (used by the garbage collector) consist of a chain of
588    StgMutClosures connected through their mut_link fields, ending in
589    an END_MUT_LIST closure.
590    -------------------------------------------------------------------------- */
591
592 INFO_TABLE_CONSTR(END_MUT_LIST_info,END_MUT_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
593 NON_ENTERABLE_ENTRY_CODE(END_MUT_LIST);
594
595 SET_STATIC_HDR(END_MUT_LIST_closure,END_MUT_LIST_info,0/*CC*/,,EI_)
596 , /*payload*/{} };
597
598 INFO_TABLE(MUT_CONS_info, MUT_CONS_entry, 1, 1, MUT_VAR, , EF_, 0, 0);
599 NON_ENTERABLE_ENTRY_CODE(MUT_CONS);
600
601 /* -----------------------------------------------------------------------------
602    Exception lists
603    -------------------------------------------------------------------------- */
604
605 INFO_TABLE_CONSTR(END_EXCEPTION_LIST_info,END_EXCEPTION_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
606 NON_ENTERABLE_ENTRY_CODE(END_EXCEPTION_LIST);
607
608 SET_STATIC_HDR(END_EXCEPTION_LIST_closure,END_EXCEPTION_LIST_info,0/*CC*/,,EI_)
609 , /*payload*/{} };
610
611 INFO_TABLE(EXCEPTION_CONS_info, EXCEPTION_CONS_entry, 1, 1, CONSTR, , EF_, 0, 0);
612 NON_ENTERABLE_ENTRY_CODE(EXCEPTION_CONS);
613
614 /* -----------------------------------------------------------------------------
615    Arrays
616
617    These come in two basic flavours: arrays of data (StgArrWords) and arrays of
618    pointers (StgArrPtrs).  They all have a similar layout:
619
620         ___________________________
621         | Info | No. of | data....
622         |  Ptr | Words  |
623         ---------------------------
624
625    These are *unpointed* objects: i.e. they cannot be entered.
626
627    -------------------------------------------------------------------------- */
628
629 #define ArrayInfo(type)                                 \
630 INFO_TABLE(type##_info, type##_entry, 0, 0, type, , EF_,0,0);
631
632 ArrayInfo(ARR_WORDS);
633 NON_ENTERABLE_ENTRY_CODE(ARR_WORDS);
634 ArrayInfo(MUT_ARR_PTRS);
635 NON_ENTERABLE_ENTRY_CODE(MUT_ARR_PTRS);
636 ArrayInfo(MUT_ARR_PTRS_FROZEN);
637 NON_ENTERABLE_ENTRY_CODE(MUT_ARR_PTRS_FROZEN);
638
639 #undef ArrayInfo
640
641 /* -----------------------------------------------------------------------------
642    Mutable Variables
643    -------------------------------------------------------------------------- */
644
645 INFO_TABLE(MUT_VAR_info, MUT_VAR_entry, 1, 1, MUT_VAR, , EF_, 0, 0);
646 NON_ENTERABLE_ENTRY_CODE(MUT_VAR);
647
648 /* -----------------------------------------------------------------------------
649    Standard Error Entry.
650
651    This is used for filling in vector-table entries that can never happen,
652    for instance.
653    -------------------------------------------------------------------------- */
654
655 STGFUN(stg_error_entry)                                                 \
656 {                                                                       \
657   FB_                                                                   \
658     DUMP_ERRMSG("fatal: stg_error_entry");                              \
659     STGCALL1(shutdownHaskellAndExit, EXIT_FAILURE);                     \
660   FE_                                                                   \
661 }
662
663 /* -----------------------------------------------------------------------------
664    Dummy return closure
665  
666    Entering this closure will just return to the address on the top of the
667    stack.  Useful for getting a thread in a canonical form where we can
668    just enter the top stack word to start the thread.  (see deleteThread)
669  * -------------------------------------------------------------------------- */
670
671 INFO_TABLE(dummy_ret_info, dummy_ret_entry, 0, 0, CONSTR_NOCAF_STATIC, , EF_, 0, 0);
672 FN_(dummy_ret_entry)
673 {
674   W_ ret_addr;
675   FB_
676   ret_addr = Sp[0];
677   Sp++;
678   JMP_(ENTRY_CODE(ret_addr));
679   FE_
680 }
681 SET_STATIC_HDR(dummy_ret_closure,dummy_ret_info,CCS_DONTZuCARE,,EI_)
682 , /*payload*/{} };
683
684 /* -----------------------------------------------------------------------------
685     Strict IO application - performing an IO action and entering its result.
686     
687     rts_evalIO() lets you perform Haskell IO actions from outside of Haskell-land,
688     returning back to you their result. Want this result to be evaluated to WHNF
689     by that time, so that we can easily get at the int/char/whatever using the
690     various get{Ty} functions provided by the RTS API.
691
692     forceIO takes care of this, performing the IO action and entering the
693     results that comes back.
694
695  * -------------------------------------------------------------------------- */
696
697 #ifdef REG_R1
698 INFO_TABLE_SRT_BITMAP(forceIO_ret_info,forceIO_ret_entry,0,0,0,0,RET_SMALL,,EF_,0,0);
699 FN_(forceIO_ret_entry)
700 {
701   FB_
702   Sp++;
703   Sp -= sizeofW(StgSeqFrame);
704   PUSH_SEQ_FRAME(Sp);
705   JMP_(GET_ENTRY(R1.cl));
706 }
707 #else
708 INFO_TABLE_SRT_BITMAP(forceIO_ret_info,forceIO_ret_entry,0,0,0,0,RET_SMALL,,EF_,0,0);
709 FN_(forceIO_ret_entry)
710 {
711   StgClosure *rval;
712   FB_
713   rval = (StgClosure *)Sp[0];
714   Sp += 2;
715   Sp -= sizeofW(StgSeqFrame);
716   PUSH_SEQ_FRAME(Sp);
717   R1.cl = rval;
718   JMP_(GET_ENTRY(R1.cl));
719 }
720 #endif
721
722 INFO_TABLE(forceIO_info,forceIO_entry,1,0,FUN_STATIC,,EF_,0,0);
723 FN_(forceIO_entry)
724 {
725   FB_
726   /* Sp[0] contains the IO action we want to perform */
727   R1.p  = (P_)Sp[0];
728   /* Replace it with the return continuation that enters the result. */
729   Sp[0] = (W_)&forceIO_ret_info;
730   Sp--;
731   /* Push the RealWorld# tag and enter */
732   Sp[0] =(W_)REALWORLD_TAG;
733   JMP_(GET_ENTRY(R1.cl));
734   FE_
735 }
736 SET_STATIC_HDR(forceIO_closure,forceIO_info,CCS_DONTZuCARE,,EI_)
737 , /*payload*/{} };
738
739
740 /* -----------------------------------------------------------------------------
741    Standard Infotables (for use in interpreter)
742    -------------------------------------------------------------------------- */
743
744 #ifdef INTERPRETER
745
746 STGFUN(Hugs_CONSTR_entry)
747 {
748     /* R1 points at the constructor */
749     JMP_(ENTRY_CODE(((StgPtr*)Sp)[0]));
750 }
751
752 #define RET_BCO_ENTRY_TEMPLATE(label)   \
753    IFN_(label)                          \
754    {                                    \
755       FB_                               \
756       Sp -= 1;                          \
757       ((StgPtr*)Sp)[0] = R1.p;          \
758       JMP_(stg_yield_to_Hugs);          \
759       FE_                               \
760    }
761
762 RET_BCO_ENTRY_TEMPLATE(ret_bco_entry  );
763 RET_BCO_ENTRY_TEMPLATE(ret_bco_0_entry);
764 RET_BCO_ENTRY_TEMPLATE(ret_bco_1_entry);
765 RET_BCO_ENTRY_TEMPLATE(ret_bco_2_entry);
766 RET_BCO_ENTRY_TEMPLATE(ret_bco_3_entry);
767 RET_BCO_ENTRY_TEMPLATE(ret_bco_4_entry);
768 RET_BCO_ENTRY_TEMPLATE(ret_bco_5_entry);
769 RET_BCO_ENTRY_TEMPLATE(ret_bco_6_entry);
770 RET_BCO_ENTRY_TEMPLATE(ret_bco_7_entry);
771
772 VEC_POLY_INFO_TABLE(ret_bco,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, EF_);
773
774 #endif /* INTERPRETER */
775
776 #ifndef COMPILER
777
778 INFO_TABLE_CONSTR(Czh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgChar),0,CONSTR,,EF_,0,0);
779 INFO_TABLE_CONSTR(Izh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgInt),0,CONSTR,,EF_,0,0);
780 INFO_TABLE_CONSTR(I64zh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgInt64),0,CONSTR,,EF_,0,0);
781 INFO_TABLE_CONSTR(Fzh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgFloat),0,CONSTR,,EF_,0,0);
782 INFO_TABLE_CONSTR(Dzh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgDouble),0,CONSTR,,EF_,0,0);
783 INFO_TABLE_CONSTR(Azh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgAddr),0,CONSTR,,EF_,0,0);
784 INFO_TABLE_CONSTR(Wzh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgWord),0,CONSTR,,EF_,0,0);
785 INFO_TABLE_CONSTR(StablePtr_con_info,Hugs_CONSTR_entry,0,sizeofW(StgStablePtr),0,CONSTR,,EF_,0,0);
786
787 /* These might seem redundant but {I,C}zh_static_info are used in
788  * {INT,CHAR}LIKE and the rest are used in RtsAPI.c
789  */
790 INFO_TABLE_CONSTR(Czh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgChar),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
791 INFO_TABLE_CONSTR(Izh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgInt),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
792 INFO_TABLE_CONSTR(I64zh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgInt64),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
793 INFO_TABLE_CONSTR(Fzh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgFloat),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
794 INFO_TABLE_CONSTR(Dzh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgDouble),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
795 INFO_TABLE_CONSTR(Azh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgAddr),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
796 INFO_TABLE_CONSTR(Wzh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgWord),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
797 INFO_TABLE_CONSTR(StablePtr_static_info,Hugs_CONSTR_entry,0,sizeofW(StgStablePtr),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
798
799 #endif /* !defined(COMPILER) */
800
801 /* -----------------------------------------------------------------------------
802    CHARLIKE and INTLIKE closures.  
803
804    These are static representations of Chars and small Ints, so that
805    we can remove dynamic Chars and Ints during garbage collection and
806    replace them with references to the static objects.
807    -------------------------------------------------------------------------- */
808
809 #ifdef ENABLE_WIN32_DLL_SUPPORT
810 /*
811  * When sticking the RTS in a DLL, we delay populating the
812  * Charlike and Intlike tables until load-time, which is only
813  * when we've got the real addresses to the C# and I# closures.
814  *
815  */
816 static INFO_TBL_CONST StgInfoTable czh_static_info;
817 static INFO_TBL_CONST StgInfoTable izh_static_info;
818 #define Char_hash_static_info czh_static_info
819 #define Int_hash_static_info izh_static_info
820 #else
821 #define Char_hash_static_info Czh_static_info
822 #define Int_hash_static_info Izh_static_info
823 #endif
824
825 #define CHARLIKE_HDR(n)                                         \
826         {                                                       \
827           STATIC_HDR(Char_hash_static_info, /* C# */            \
828                          CCS_DONTZuCARE),                       \
829           data : n                                              \
830         }
831                                              
832 #define INTLIKE_HDR(n)                                          \
833         {                                                       \
834           STATIC_HDR(Int_hash_static_info,  /* I# */            \
835                          CCS_DONTZuCARE),                       \
836           data : n                                              \
837         }
838
839 /* put these in the *data* section, since the garbage collector relies
840  * on the fact that static closures live in the data section.
841  */
842
843 /* end the name with _closure, to convince the mangler this is a closure */
844
845 StgIntCharlikeClosure CHARLIKE_closure[] = {
846     CHARLIKE_HDR(0),
847     CHARLIKE_HDR(1),
848     CHARLIKE_HDR(2),
849     CHARLIKE_HDR(3),
850     CHARLIKE_HDR(4),
851     CHARLIKE_HDR(5),
852     CHARLIKE_HDR(6),
853     CHARLIKE_HDR(7),
854     CHARLIKE_HDR(8),
855     CHARLIKE_HDR(9),
856     CHARLIKE_HDR(10),
857     CHARLIKE_HDR(11),
858     CHARLIKE_HDR(12),
859     CHARLIKE_HDR(13),
860     CHARLIKE_HDR(14),
861     CHARLIKE_HDR(15),
862     CHARLIKE_HDR(16),
863     CHARLIKE_HDR(17),
864     CHARLIKE_HDR(18),
865     CHARLIKE_HDR(19),
866     CHARLIKE_HDR(20),
867     CHARLIKE_HDR(21),
868     CHARLIKE_HDR(22),
869     CHARLIKE_HDR(23),
870     CHARLIKE_HDR(24),
871     CHARLIKE_HDR(25),
872     CHARLIKE_HDR(26),
873     CHARLIKE_HDR(27),
874     CHARLIKE_HDR(28),
875     CHARLIKE_HDR(29),
876     CHARLIKE_HDR(30),
877     CHARLIKE_HDR(31),
878     CHARLIKE_HDR(32),
879     CHARLIKE_HDR(33),
880     CHARLIKE_HDR(34),
881     CHARLIKE_HDR(35),
882     CHARLIKE_HDR(36),
883     CHARLIKE_HDR(37),
884     CHARLIKE_HDR(38),
885     CHARLIKE_HDR(39),
886     CHARLIKE_HDR(40),
887     CHARLIKE_HDR(41),
888     CHARLIKE_HDR(42),
889     CHARLIKE_HDR(43),
890     CHARLIKE_HDR(44),
891     CHARLIKE_HDR(45),
892     CHARLIKE_HDR(46),
893     CHARLIKE_HDR(47),
894     CHARLIKE_HDR(48),
895     CHARLIKE_HDR(49),
896     CHARLIKE_HDR(50),
897     CHARLIKE_HDR(51),
898     CHARLIKE_HDR(52),
899     CHARLIKE_HDR(53),
900     CHARLIKE_HDR(54),
901     CHARLIKE_HDR(55),
902     CHARLIKE_HDR(56),
903     CHARLIKE_HDR(57),
904     CHARLIKE_HDR(58),
905     CHARLIKE_HDR(59),
906     CHARLIKE_HDR(60),
907     CHARLIKE_HDR(61),
908     CHARLIKE_HDR(62),
909     CHARLIKE_HDR(63),
910     CHARLIKE_HDR(64),
911     CHARLIKE_HDR(65),
912     CHARLIKE_HDR(66),
913     CHARLIKE_HDR(67),
914     CHARLIKE_HDR(68),
915     CHARLIKE_HDR(69),
916     CHARLIKE_HDR(70),
917     CHARLIKE_HDR(71),
918     CHARLIKE_HDR(72),
919     CHARLIKE_HDR(73),
920     CHARLIKE_HDR(74),
921     CHARLIKE_HDR(75),
922     CHARLIKE_HDR(76),
923     CHARLIKE_HDR(77),
924     CHARLIKE_HDR(78),
925     CHARLIKE_HDR(79),
926     CHARLIKE_HDR(80),
927     CHARLIKE_HDR(81),
928     CHARLIKE_HDR(82),
929     CHARLIKE_HDR(83),
930     CHARLIKE_HDR(84),
931     CHARLIKE_HDR(85),
932     CHARLIKE_HDR(86),
933     CHARLIKE_HDR(87),
934     CHARLIKE_HDR(88),
935     CHARLIKE_HDR(89),
936     CHARLIKE_HDR(90),
937     CHARLIKE_HDR(91),
938     CHARLIKE_HDR(92),
939     CHARLIKE_HDR(93),
940     CHARLIKE_HDR(94),
941     CHARLIKE_HDR(95),
942     CHARLIKE_HDR(96),
943     CHARLIKE_HDR(97),
944     CHARLIKE_HDR(98),
945     CHARLIKE_HDR(99),
946     CHARLIKE_HDR(100),
947     CHARLIKE_HDR(101),
948     CHARLIKE_HDR(102),
949     CHARLIKE_HDR(103),
950     CHARLIKE_HDR(104),
951     CHARLIKE_HDR(105),
952     CHARLIKE_HDR(106),
953     CHARLIKE_HDR(107),
954     CHARLIKE_HDR(108),
955     CHARLIKE_HDR(109),
956     CHARLIKE_HDR(110),
957     CHARLIKE_HDR(111),
958     CHARLIKE_HDR(112),
959     CHARLIKE_HDR(113),
960     CHARLIKE_HDR(114),
961     CHARLIKE_HDR(115),
962     CHARLIKE_HDR(116),
963     CHARLIKE_HDR(117),
964     CHARLIKE_HDR(118),
965     CHARLIKE_HDR(119),
966     CHARLIKE_HDR(120),
967     CHARLIKE_HDR(121),
968     CHARLIKE_HDR(122),
969     CHARLIKE_HDR(123),
970     CHARLIKE_HDR(124),
971     CHARLIKE_HDR(125),
972     CHARLIKE_HDR(126),
973     CHARLIKE_HDR(127),
974     CHARLIKE_HDR(128),
975     CHARLIKE_HDR(129),
976     CHARLIKE_HDR(130),
977     CHARLIKE_HDR(131),
978     CHARLIKE_HDR(132),
979     CHARLIKE_HDR(133),
980     CHARLIKE_HDR(134),
981     CHARLIKE_HDR(135),
982     CHARLIKE_HDR(136),
983     CHARLIKE_HDR(137),
984     CHARLIKE_HDR(138),
985     CHARLIKE_HDR(139),
986     CHARLIKE_HDR(140),
987     CHARLIKE_HDR(141),
988     CHARLIKE_HDR(142),
989     CHARLIKE_HDR(143),
990     CHARLIKE_HDR(144),
991     CHARLIKE_HDR(145),
992     CHARLIKE_HDR(146),
993     CHARLIKE_HDR(147),
994     CHARLIKE_HDR(148),
995     CHARLIKE_HDR(149),
996     CHARLIKE_HDR(150),
997     CHARLIKE_HDR(151),
998     CHARLIKE_HDR(152),
999     CHARLIKE_HDR(153),
1000     CHARLIKE_HDR(154),
1001     CHARLIKE_HDR(155),
1002     CHARLIKE_HDR(156),
1003     CHARLIKE_HDR(157),
1004     CHARLIKE_HDR(158),
1005     CHARLIKE_HDR(159),
1006     CHARLIKE_HDR(160),
1007     CHARLIKE_HDR(161),
1008     CHARLIKE_HDR(162),
1009     CHARLIKE_HDR(163),
1010     CHARLIKE_HDR(164),
1011     CHARLIKE_HDR(165),
1012     CHARLIKE_HDR(166),
1013     CHARLIKE_HDR(167),
1014     CHARLIKE_HDR(168),
1015     CHARLIKE_HDR(169),
1016     CHARLIKE_HDR(170),
1017     CHARLIKE_HDR(171),
1018     CHARLIKE_HDR(172),
1019     CHARLIKE_HDR(173),
1020     CHARLIKE_HDR(174),
1021     CHARLIKE_HDR(175),
1022     CHARLIKE_HDR(176),
1023     CHARLIKE_HDR(177),
1024     CHARLIKE_HDR(178),
1025     CHARLIKE_HDR(179),
1026     CHARLIKE_HDR(180),
1027     CHARLIKE_HDR(181),
1028     CHARLIKE_HDR(182),
1029     CHARLIKE_HDR(183),
1030     CHARLIKE_HDR(184),
1031     CHARLIKE_HDR(185),
1032     CHARLIKE_HDR(186),
1033     CHARLIKE_HDR(187),
1034     CHARLIKE_HDR(188),
1035     CHARLIKE_HDR(189),
1036     CHARLIKE_HDR(190),
1037     CHARLIKE_HDR(191),
1038     CHARLIKE_HDR(192),
1039     CHARLIKE_HDR(193),
1040     CHARLIKE_HDR(194),
1041     CHARLIKE_HDR(195),
1042     CHARLIKE_HDR(196),
1043     CHARLIKE_HDR(197),
1044     CHARLIKE_HDR(198),
1045     CHARLIKE_HDR(199),
1046     CHARLIKE_HDR(200),
1047     CHARLIKE_HDR(201),
1048     CHARLIKE_HDR(202),
1049     CHARLIKE_HDR(203),
1050     CHARLIKE_HDR(204),
1051     CHARLIKE_HDR(205),
1052     CHARLIKE_HDR(206),
1053     CHARLIKE_HDR(207),
1054     CHARLIKE_HDR(208),
1055     CHARLIKE_HDR(209),
1056     CHARLIKE_HDR(210),
1057     CHARLIKE_HDR(211),
1058     CHARLIKE_HDR(212),
1059     CHARLIKE_HDR(213),
1060     CHARLIKE_HDR(214),
1061     CHARLIKE_HDR(215),
1062     CHARLIKE_HDR(216),
1063     CHARLIKE_HDR(217),
1064     CHARLIKE_HDR(218),
1065     CHARLIKE_HDR(219),
1066     CHARLIKE_HDR(220),
1067     CHARLIKE_HDR(221),
1068     CHARLIKE_HDR(222),
1069     CHARLIKE_HDR(223),
1070     CHARLIKE_HDR(224),
1071     CHARLIKE_HDR(225),
1072     CHARLIKE_HDR(226),
1073     CHARLIKE_HDR(227),
1074     CHARLIKE_HDR(228),
1075     CHARLIKE_HDR(229),
1076     CHARLIKE_HDR(230),
1077     CHARLIKE_HDR(231),
1078     CHARLIKE_HDR(232),
1079     CHARLIKE_HDR(233),
1080     CHARLIKE_HDR(234),
1081     CHARLIKE_HDR(235),
1082     CHARLIKE_HDR(236),
1083     CHARLIKE_HDR(237),
1084     CHARLIKE_HDR(238),
1085     CHARLIKE_HDR(239),
1086     CHARLIKE_HDR(240),
1087     CHARLIKE_HDR(241),
1088     CHARLIKE_HDR(242),
1089     CHARLIKE_HDR(243),
1090     CHARLIKE_HDR(244),
1091     CHARLIKE_HDR(245),
1092     CHARLIKE_HDR(246),
1093     CHARLIKE_HDR(247),
1094     CHARLIKE_HDR(248),
1095     CHARLIKE_HDR(249),
1096     CHARLIKE_HDR(250),
1097     CHARLIKE_HDR(251),
1098     CHARLIKE_HDR(252),
1099     CHARLIKE_HDR(253),
1100     CHARLIKE_HDR(254),
1101     CHARLIKE_HDR(255)
1102 };
1103
1104 StgIntCharlikeClosure INTLIKE_closure[] = {
1105     INTLIKE_HDR(-16),   /* MIN_INTLIKE == -16 */
1106     INTLIKE_HDR(-15),
1107     INTLIKE_HDR(-14),
1108     INTLIKE_HDR(-13),
1109     INTLIKE_HDR(-12),
1110     INTLIKE_HDR(-11),
1111     INTLIKE_HDR(-10),
1112     INTLIKE_HDR(-9),
1113     INTLIKE_HDR(-8),
1114     INTLIKE_HDR(-7),
1115     INTLIKE_HDR(-6),
1116     INTLIKE_HDR(-5),
1117     INTLIKE_HDR(-4),
1118     INTLIKE_HDR(-3),
1119     INTLIKE_HDR(-2),
1120     INTLIKE_HDR(-1),
1121     INTLIKE_HDR(0),
1122     INTLIKE_HDR(1),
1123     INTLIKE_HDR(2),
1124     INTLIKE_HDR(3),
1125     INTLIKE_HDR(4),
1126     INTLIKE_HDR(5),
1127     INTLIKE_HDR(6),
1128     INTLIKE_HDR(7),
1129     INTLIKE_HDR(8),
1130     INTLIKE_HDR(9),
1131     INTLIKE_HDR(10),
1132     INTLIKE_HDR(11),
1133     INTLIKE_HDR(12),
1134     INTLIKE_HDR(13),
1135     INTLIKE_HDR(14),
1136     INTLIKE_HDR(15),
1137     INTLIKE_HDR(16)     /* MAX_INTLIKE == 16 */
1138 };