StgMiscClosures.hc 26.4 KB
Newer Older
1
/* -----------------------------------------------------------------------------
sof's avatar
sof committed
2
 * $Id: StgMiscClosures.hc,v 1.24 1999/05/21 14:46:19 sof Exp $
3 4
 *
 * (c) The GHC Team, 1998-1999
5 6 7 8 9 10 11 12 13
 *
 * Entry code for various built-in closure types.
 *
 * ---------------------------------------------------------------------------*/

#include "Rts.h"
#include "RtsUtils.h"
#include "StgMiscClosures.h"
#include "HeapStackCheck.h"   /* for stg_gen_yield */
14 15
#include "Storage.h"
#include "StoragePriv.h"
16
#include "ProfRts.h"
17 18 19 20 21

#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif

sof's avatar
sof committed
22 23 24 25 26
/* ToDo: make the printing of panics more Win32-friendly, i.e.,
 *       pop up some lovely message boxes (as well).
 */
#define DUMP_ERRMSG(msg) STGCALL1(fflush,stdout); STGCALL2(fprintf,stderr,msg)

27 28 29 30 31 32
/* -----------------------------------------------------------------------------
   Entry code for an indirection.

   This code assumes R1 is in a register for now.
   -------------------------------------------------------------------------- */

33
INFO_TABLE(IND_info,IND_entry,1,0,IND,,EF_,0,0);
34 35 36 37 38 39 40
STGFUN(IND_entry)
{
    FB_
    TICK_ENT_IND(Node);	/* tick */

    R1.p = (P_) ((StgInd*)R1.p)->indirectee;
    TICK_ENT_VIA_NODE();
41
    JMP_(ENTRY_CODE(*R1.p));
42 43 44
    FE_
}

45
INFO_TABLE(IND_STATIC_info,IND_STATIC_entry,1,0,IND_STATIC,,EF_,0,0);
46 47 48 49 50 51 52
STGFUN(IND_STATIC_entry)
{
    FB_
    TICK_ENT_IND(Node);	/* tick */
  
    R1.p = (P_) ((StgIndStatic*)R1.p)->indirectee;
    TICK_ENT_VIA_NODE();
53
    JMP_(ENTRY_CODE(*R1.p));
54 55 56
    FE_
}

57
INFO_TABLE(IND_PERM_info,IND_PERM_entry,1,1,IND_PERM,,EF_,0,0);
58 59 60 61
STGFUN(IND_PERM_entry)
{
    FB_
    /* Don't add INDs to granularity cost */
62 63 64 65 66 67
    /* Dont: TICK_ENT_IND(Node); for ticky-ticky; this ind is here only to help profiling */

#if defined(TICKY_TICKY) && !defined(PROFILING)
    /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra  */
    TICK_ENT_PERM_IND(R1.p); /* tick */
#endif
68 69 70 71

    /* Enter PAP cost centre -- lexical scoping only */
    ENTER_CCS_PAP_CL(R1.cl);

72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
    /* For ticky-ticky, change the perm_ind to a normal ind on first
     * entry, so the number of ent_perm_inds is the number of *thunks*
     * entered again, not the number of subsequent entries.
     *
     * Since this screws up cost centres, we die if profiling and
     * ticky_ticky are on at the same time.  KSW 1999-01.
     */

#ifdef TICKY_TICKY
#  ifdef PROFILING
#    error Profiling and ticky-ticky do not mix at present!
#  endif  /* PROFILING */
    SET_INFO((StgInd*)R1.p,&IND_info);
#endif /* TICKY_TICKY */

87 88 89 90
    R1.p = (P_) ((StgInd*)R1.p)->indirectee;

    /* Dont: TICK_ENT_VIA_NODE(); for ticky-ticky; as above */

91 92 93 94
#if defined(TICKY_TICKY) && !defined(PROFILING)
    TICK_ENT_VIA_NODE();
#endif

95
    JMP_(ENTRY_CODE(*R1.p));
96 97 98
    FE_
}  

99
INFO_TABLE(IND_OLDGEN_info,IND_OLDGEN_entry,1,1,IND_OLDGEN,,EF_,0,0);
100 101 102 103 104 105 106
STGFUN(IND_OLDGEN_entry)
{
    FB_
    TICK_ENT_IND(Node);	/* tick */
  
    R1.p = (P_) ((StgInd*)R1.p)->indirectee;
    TICK_ENT_VIA_NODE();
107
    JMP_(ENTRY_CODE(*R1.p));
108 109 110
    FE_
}

111
INFO_TABLE(IND_OLDGEN_PERM_info,IND_OLDGEN_PERM_entry,1,1,IND_OLDGEN_PERM,,EF_,0,0);
112 113 114
STGFUN(IND_OLDGEN_PERM_entry)
{
    FB_
115
    /* Dont: TICK_ENT_IND(Node); for ticky-ticky; this ind is here only to help profiling */
116

117 118 119 120 121
#if defined(TICKY_TICKY) && !defined(PROFILING)
    /* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra  */
    TICK_ENT_PERM_IND(R1.p); /* tick */
#endif
  
122 123 124
    /* Enter PAP cost centre -- lexical scoping only */
    ENTER_CCS_PAP_CL(R1.cl);

125 126 127 128 129 130 131 132
    /* see comment in IND_PERM */
#ifdef TICKY_TICKY
#  ifdef PROFILING
#    error Profiling and ticky-ticky do not mix at present!
#  endif  /* PROFILING */
    SET_INFO((StgInd*)R1.p,&IND_OLDGEN_info);
#endif /* TICKY_TICKY */

133 134
    R1.p = (P_) ((StgInd*)R1.p)->indirectee;
    TICK_ENT_VIA_NODE();
135
    JMP_(ENTRY_CODE(*R1.p));
136 137 138 139 140 141 142 143 144
    FE_
}

/* -----------------------------------------------------------------------------
   Entry code for CAFs

   This code assumes R1 is in a register for now.
   -------------------------------------------------------------------------- */

145
INFO_TABLE(CAF_UNENTERED_info,CAF_UNENTERED_entry,1,3,CAF_UNENTERED,,EF_,0,0);
146 147 148 149 150 151 152 153 154 155
STGFUN(CAF_UNENTERED_entry)
{
    FB_
    /* ToDo: implement directly in GHC */
    Sp -= 1;
    Sp[0] = R1.w;
    JMP_(stg_yield_to_Hugs);
    FE_
}

156
/* 0,4 is entirely bogus; _do not_ rely on this info */
157
INFO_TABLE(CAF_ENTERED_info,CAF_ENTERED_entry,0,4,CAF_ENTERED,,EF_,0,0);
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
STGFUN(CAF_ENTERED_entry)
{
    FB_
    R1.p = (P_) ((StgCAF*)R1.p)->value; /* just a fancy indirection */
    TICK_ENT_VIA_NODE();
    JMP_(GET_ENTRY(R1.cl));
    FE_
}

/* -----------------------------------------------------------------------------
   Entry code for a black hole.

   Entering a black hole normally causes a cyclic data dependency, but
   in the concurrent world, black holes are synchronization points,
   and they are turned into blocking queues when there are threads
   waiting for the evaluation of the closure to finish.
   -------------------------------------------------------------------------- */

/* Note: a black hole must be big enough to be overwritten with an
177 178 179
 * indirection/evacuee/catch.  Thus we claim it has 1 non-pointer word of
 * payload (in addition to the pointer word for the blocking queue), which 
 * should be big enough for an old-generation indirection.  
180 181
 */

182
INFO_TABLE(BLACKHOLE_info, BLACKHOLE_entry,0,2,BLACKHOLE,,EF_,0,0);
183
STGFUN(BLACKHOLE_entry)
184 185
{
  FB_
186 187
    TICK_ENT_BH();

188
    /* Change the BLACKHOLE into a BLACKHOLE_BQ */
189
    ((StgBlockingQueue *)R1.p)->header.info = &BLACKHOLE_BQ_info;
190 191
    /* Put ourselves on the blocking queue for this black hole */
    CurrentTSO->link = (StgTSO *)&END_TSO_QUEUE_closure;
192
    ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
193
    CurrentTSO->blocked_on = R1.cl;
194
    recordMutable((StgMutClosure *)R1.cl);
195 196 197 198 199 200

    /* stg_gen_block is too heavyweight, use a specialised one */
    BLOCK_NP(1);
  FE_
}

201
INFO_TABLE(BLACKHOLE_BQ_info, BLACKHOLE_BQ_entry,1,1,BLACKHOLE_BQ,,EF_,0,0);
202
STGFUN(BLACKHOLE_BQ_entry)
203 204
{
  FB_
205 206
    TICK_ENT_BH();

207
    /* Put ourselves on the blocking queue for this black hole */
208
    CurrentTSO->blocked_on = R1.cl;
209 210
    CurrentTSO->link = ((StgBlockingQueue *)R1.p)->blocking_queue;
    ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
211 212 213 214 215 216 217

    /* stg_gen_block is too heavyweight, use a specialised one */
    BLOCK_NP(1);
  FE_
}

/* identical to BLACKHOLEs except for the infotag */
218
INFO_TABLE(CAF_BLACKHOLE_info, CAF_BLACKHOLE_entry,0,2,CAF_BLACKHOLE,,EF_,0,0);
219 220 221
STGFUN(CAF_BLACKHOLE_entry)
{
  FB_
222 223
    TICK_ENT_BH();

224
    /* Change the BLACKHOLE into a BLACKHOLE_BQ */
225
    ((StgBlockingQueue *)R1.p)->header.info = &BLACKHOLE_BQ_info;
226
    /* Put ourselves on the blocking queue for this black hole */
227
    CurrentTSO->link = (StgTSO *)&END_TSO_QUEUE_closure;
228
    ((StgBlockingQueue *)R1.p)->blocking_queue = CurrentTSO;
229
    CurrentTSO->blocked_on = R1.cl;
230
    recordMutable((StgMutClosure *)R1.cl);
231 232 233 234 235 236

    /* stg_gen_block is too heavyweight, use a specialised one */
    BLOCK_NP(1);
  FE_
}

237
#ifdef TICKY_TICKY
238
INFO_TABLE(SE_BLACKHOLE_info, SE_BLACKHOLE_entry,0,2,SE_BLACKHOLE,,EF_,0,0);
239 240 241 242 243 244 245 246 247 248
STGFUN(SE_BLACKHOLE_entry)
{
  FB_
    STGCALL1(fflush,stdout);						
    STGCALL3(fprintf,stderr,"SE_BLACKHOLE at %p entered!\n",R1.p);
    STGCALL1(raiseError, errorHandler);
    stg_exit(EXIT_FAILURE); /* not executed */
  FE_
}

249
INFO_TABLE(SE_CAF_BLACKHOLE_info, SE_CAF_BLACKHOLE_entry,0,2,SE_CAF_BLACKHOLE,,EF_,0,0);
250 251 252 253 254 255 256 257 258 259 260
STGFUN(SE_CAF_BLACKHOLE_entry)
{
  FB_
    STGCALL1(fflush,stdout);						
    STGCALL3(fprintf,stderr,"SE_CAF_BLACKHOLE at %p entered!\n",R1.p);
    STGCALL1(raiseError, errorHandler);
    stg_exit(EXIT_FAILURE); /* not executed */
  FE_
}
#endif

261 262 263
/* -----------------------------------------------------------------------------
   The code for a BCO returns to the scheduler
   -------------------------------------------------------------------------- */
264
INFO_TABLE(BCO_info,BCO_entry,0,0,BCO,,EF_,0,0);
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
EF_(BCO_entry) {				
  FB_	
    Sp -= 1;
    Sp[0] = R1.w;
    JMP_(stg_yield_to_Hugs);
  FE_								
}

/* -----------------------------------------------------------------------------
   Some static info tables for things that don't get entered, and
   therefore don't need entry code (i.e. boxed but unpointed objects)
   -------------------------------------------------------------------------- */

#define NON_ENTERABLE_ENTRY_CODE(type)					\
STGFUN(type##_entry)							\
{									\
  FB_									\
sof's avatar
sof committed
282
    DUMP_ERRMSG(#type " object entered!\n");                            \
283 284 285 286 287
    STGCALL1(raiseError, errorHandler);					\
    stg_exit(EXIT_FAILURE); /* not executed */				\
  FE_									\
}

288
INFO_TABLE(TSO_info, TSO_entry, 0,0,TSO,,EF_,0,0);
289 290 291 292 293 294 295
NON_ENTERABLE_ENTRY_CODE(TSO);

/* -----------------------------------------------------------------------------
   Evacuees are left behind by the garbage collector.  Any attempt to enter
   one is a real bug.
   -------------------------------------------------------------------------- */

296
INFO_TABLE(EVACUATED_info,EVACUATED_entry,1,0,EVACUATED,,EF_,0,0);
297 298 299 300 301 302 303 304 305 306
NON_ENTERABLE_ENTRY_CODE(EVACUATED);

/* -----------------------------------------------------------------------------
   Weak pointers

   Live weak pointers have a special closure type.  Dead ones are just
   nullary constructors (although they live on the heap - we overwrite
   live weak pointers with dead ones).
   -------------------------------------------------------------------------- */

307
INFO_TABLE(WEAK_info,WEAK_entry,0,4,WEAK,,EF_,0,0);
308 309
NON_ENTERABLE_ENTRY_CODE(WEAK);

310
INFO_TABLE_CONSTR(DEAD_WEAK_info,DEAD_WEAK_entry,0,1,0,CONSTR,,EF_,0,0);
311 312
NON_ENTERABLE_ENTRY_CODE(DEAD_WEAK);

313
/* -----------------------------------------------------------------------------
314
   NO_FINALIZER
315 316

   This is a static nullary constructor (like []) that we use to mark an empty
317
   finalizer in a weak pointer object.
318 319
   -------------------------------------------------------------------------- */

320
INFO_TABLE_CONSTR(NO_FINALIZER_info,NO_FINALIZER_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
321
NON_ENTERABLE_ENTRY_CODE(NO_FINALIZER);
322

323
SET_STATIC_HDR(NO_FINALIZER_closure,NO_FINALIZER_info,0/*CC*/,,EI_)
324 325
};

326 327 328 329
/* -----------------------------------------------------------------------------
   Foreign Objects are unlifted and therefore never entered.
   -------------------------------------------------------------------------- */

330
INFO_TABLE(FOREIGN_info,FOREIGN_entry,0,1,FOREIGN,,EF_,0,0);
331 332
NON_ENTERABLE_ENTRY_CODE(FOREIGN);

333 334 335 336
/* -----------------------------------------------------------------------------
   Stable Names are unlifted too.
   -------------------------------------------------------------------------- */

337
INFO_TABLE(STABLE_NAME_info,STABLE_NAME_entry,0,1,STABLE_NAME,,EF_,0,0);
338 339
NON_ENTERABLE_ENTRY_CODE(STABLE_NAME);

340 341 342 343 344 345 346
/* -----------------------------------------------------------------------------
   MVars

   There are two kinds of these: full and empty.  We need an info table
   and entry code for each type.
   -------------------------------------------------------------------------- */

347
INFO_TABLE(FULL_MVAR_info,FULL_MVAR_entry,4,0,MVAR,,EF_,0,0);
348 349
NON_ENTERABLE_ENTRY_CODE(FULL_MVAR);

350
INFO_TABLE(EMPTY_MVAR_info,EMPTY_MVAR_entry,4,0,MVAR,,EF_,0,0);
351 352 353 354 355 356 357 358 359
NON_ENTERABLE_ENTRY_CODE(EMPTY_MVAR);

/* -----------------------------------------------------------------------------
   END_TSO_QUEUE

   This is a static nullary constructor (like []) that we use to mark the
   end of a linked TSO queue.
   -------------------------------------------------------------------------- */

360
INFO_TABLE_CONSTR(END_TSO_QUEUE_info,END_TSO_QUEUE_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
361 362
NON_ENTERABLE_ENTRY_CODE(END_TSO_QUEUE);

363
SET_STATIC_HDR(END_TSO_QUEUE_closure,END_TSO_QUEUE_info,0/*CC*/,,EI_)
364 365
};

366 367 368 369 370 371 372 373
/* -----------------------------------------------------------------------------
   Mutable lists

   Mutable lists (used by the garbage collector) consist of a chain of
   StgMutClosures connected through their mut_link fields, ending in
   an END_MUT_LIST closure.
   -------------------------------------------------------------------------- */

374
INFO_TABLE_CONSTR(END_MUT_LIST_info,END_MUT_LIST_entry,0,0,0,CONSTR_NOCAF_STATIC,,EF_,0,0);
375 376
NON_ENTERABLE_ENTRY_CODE(END_MUT_LIST);

377
SET_STATIC_HDR(END_MUT_LIST_closure,END_MUT_LIST_info,0/*CC*/,,EI_)
378 379
};

380
INFO_TABLE(MUT_CONS_info, MUT_CONS_entry, 1, 1, MUT_VAR, , EF_, 0, 0);
381 382
NON_ENTERABLE_ENTRY_CODE(MUT_CONS);

383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
/* -----------------------------------------------------------------------------
   Arrays

   These come in two basic flavours: arrays of data (StgArrWords) and arrays of
   pointers (StgArrPtrs).  They all have a similar layout:

	___________________________
	| Info | No. of | data....
        |  Ptr | Words  |
	---------------------------

   These are *unpointed* objects: i.e. they cannot be entered.

   -------------------------------------------------------------------------- */

398
#define ArrayInfo(type)					\
399
INFO_TABLE(type##_info, type##_entry, 0, 0, type, , EF_,0,0);
400 401

ArrayInfo(ARR_WORDS);
402
NON_ENTERABLE_ENTRY_CODE(ARR_WORDS);
403
ArrayInfo(MUT_ARR_PTRS);
404
NON_ENTERABLE_ENTRY_CODE(MUT_ARR_PTRS);
405
ArrayInfo(MUT_ARR_PTRS_FROZEN);
406
NON_ENTERABLE_ENTRY_CODE(MUT_ARR_PTRS_FROZEN);
407 408 409 410 411 412 413

#undef ArrayInfo

/* -----------------------------------------------------------------------------
   Mutable Variables
   -------------------------------------------------------------------------- */

414
INFO_TABLE(MUT_VAR_info, MUT_VAR_entry, 1, 1, MUT_VAR, , EF_, 0, 0);
415 416 417 418 419 420 421 422 423 424 425 426
NON_ENTERABLE_ENTRY_CODE(MUT_VAR);

/* -----------------------------------------------------------------------------
   Standard Error Entry.

   This is used for filling in vector-table entries that can never happen,
   for instance.
   -------------------------------------------------------------------------- */

STGFUN(stg_error_entry)							\
{									\
  FB_									\
sof's avatar
sof committed
427
    DUMP_ERRMSG("fatal: stg_error_entry");                              \
428 429 430 431 432 433 434 435 436 437 438 439 440
    STGCALL1(raiseError, errorHandler);					\
    exit(EXIT_FAILURE); /* not executed */				\
  FE_									\
}

/* -----------------------------------------------------------------------------
   Dummy return closure
 
   Entering this closure will just return to the address on the top of the
   stack.  Useful for getting a thread in a canonical form where we can
   just enter the top stack word to start the thread.  (see deleteThread)
 * -------------------------------------------------------------------------- */

441
INFO_TABLE(dummy_ret_info, dummy_ret_entry, 0, 0, CONSTR_NOCAF_STATIC, , EF_, 0, 0);
442 443 444 445 446 447 448
FN_(dummy_ret_entry)
{
  W_ ret_addr;
  FB_
  ret_addr = Sp[0];
  Sp++;
  JMP_(ENTRY_CODE(ret_addr));
449
  FE_
450
}
451
SET_STATIC_HDR(dummy_ret_closure,dummy_ret_info,CCS_DONTZuCARE,,EI_)
452 453
};

sof's avatar
sof committed
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495
/* -----------------------------------------------------------------------------
    Strict IO application - performing an IO action and entering its result.
    
    rts_evalIO() lets you perform Haskell IO actions from outside of Haskell-land,
    returning back to you their result. Want this result to be evaluated to WHNF
    by that time, so that we can easily get at the int/char/whatever using the
    various get{Ty} functions provided by the RTS API.

    forceIO takes care of this, performing the IO action and entering the
    results that comes back.

 * -------------------------------------------------------------------------- */

INFO_TABLE_SRT_BITMAP(forceIO_ret_info,forceIO_ret_entry,0,0,0,0,RET_SMALL,,EF_,0,0);
FN_(forceIO_ret_entry)
{
  FB_
  Sp++;
  Sp -= sizeofW(StgSeqFrame);
  PUSH_SEQ_FRAME(Sp);
  JMP_(GET_ENTRY(R1.cl));
}


INFO_TABLE(forceIO_info,forceIO_entry,1,0,FUN,,EF_,0,0);
FN_(forceIO_entry)
{
  FB_
  /* Sp[0] contains the IO action we want to perform */
  R1.p  = (P_)Sp[0];
  /* Replace it with the return continuation that enters the result. */
  Sp[0] = (W_)&forceIO_ret_info;
  Sp--;
  /* Push the RealWorld# tag and enter */
  Sp[0] =(W_)REALWORLD_TAG;
  JMP_(GET_ENTRY(R1.cl));
  FE_
}
SET_STATIC_HDR(forceIO_closure,forceIO_info,CCS_DONTZuCARE,,EI_)
};


496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535
/* -----------------------------------------------------------------------------
   Standard Infotables (for use in interpreter)
   -------------------------------------------------------------------------- */

#ifdef INTERPRETER

STGFUN(Hugs_CONSTR_entry)
{
    Sp -= 1;
    ((StgPtr*)Sp)[0] = R1.p;
    /* vectored: JMP_(RET_VEC(((StgPtr*)Sp)[1],constrTag(?))); */
    JMP_(ENTRY_CODE(((StgPtr*)Sp)[1]));
}

#define RET_BCO_ENTRY_TEMPLATE(label) 	\
   IFN_(label)			        \
   {                                    \
      FB_				\
      Sp -= 1;				\
      ((StgPtr*)Sp)[0] = R1.p;		\
      JMP_(stg_yield_to_Hugs);          \
      FE_                               \
   }

RET_BCO_ENTRY_TEMPLATE(ret_bco_entry  );
RET_BCO_ENTRY_TEMPLATE(ret_bco_0_entry);
RET_BCO_ENTRY_TEMPLATE(ret_bco_1_entry);
RET_BCO_ENTRY_TEMPLATE(ret_bco_2_entry);
RET_BCO_ENTRY_TEMPLATE(ret_bco_3_entry);
RET_BCO_ENTRY_TEMPLATE(ret_bco_4_entry);
RET_BCO_ENTRY_TEMPLATE(ret_bco_5_entry);
RET_BCO_ENTRY_TEMPLATE(ret_bco_6_entry);
RET_BCO_ENTRY_TEMPLATE(ret_bco_7_entry);

VEC_POLY_INFO_TABLE(ret_bco,0, NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO);

#endif /* INTERPRETER */

#ifndef COMPILER

536 537 538 539 540 541 542 543
INFO_TABLE_CONSTR(Czh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgChar),0,CONSTR,,EF_,0,0);
INFO_TABLE_CONSTR(Izh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgInt),0,CONSTR,,EF_,0,0);
INFO_TABLE_CONSTR(I64zh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgInt64),0,CONSTR,,EF_,0,0);
INFO_TABLE_CONSTR(Fzh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgFloat),0,CONSTR,,EF_,0,0);
INFO_TABLE_CONSTR(Dzh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgDouble),0,CONSTR,,EF_,0,0);
INFO_TABLE_CONSTR(Azh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgAddr),0,CONSTR,,EF_,0,0);
INFO_TABLE_CONSTR(Wzh_con_info,Hugs_CONSTR_entry,0,sizeofW(StgWord),0,CONSTR,,EF_,0,0);
INFO_TABLE_CONSTR(StablePtr_con_info,Hugs_CONSTR_entry,0,sizeofW(StgStablePtr),0,CONSTR,,EF_,0,0);
544

545
/* These might seem redundant but {I,C}zh_static_info are used in
546 547
 * {INT,CHAR}LIKE and the rest are used in RtsAPI.c
 */
548 549 550 551 552 553 554 555
INFO_TABLE_CONSTR(Czh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgChar),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
INFO_TABLE_CONSTR(Izh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgInt),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
INFO_TABLE_CONSTR(I64zh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgInt64),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
INFO_TABLE_CONSTR(Fzh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgFloat),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
INFO_TABLE_CONSTR(Dzh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgDouble),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
INFO_TABLE_CONSTR(Azh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgAddr),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
INFO_TABLE_CONSTR(Wzh_static_info,Hugs_CONSTR_entry,0,sizeofW(StgWord),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
INFO_TABLE_CONSTR(StablePtr_static_info,Hugs_CONSTR_entry,0,sizeofW(StgStablePtr),0,CONSTR_NOCAF_STATIC,,EF_,0,0);
556 557 558 559 560 561 562 563 564 565 566

#endif /* !defined(COMPILER) */

/* -----------------------------------------------------------------------------
   CHARLIKE and INTLIKE closures.  

   These are static representations of Chars and small Ints, so that
   we can remove dynamic Chars and Ints during garbage collection and
   replace them with references to the static objects.
   -------------------------------------------------------------------------- */

sof's avatar
sof committed
567
#ifdef ENABLE_WIN32_DLL_SUPPORT
sof's avatar
sof committed
568 569 570 571 572 573
/*
 * When sticking the RTS in a DLL, we delay populating the
 * Charlike and Intlike tables until load-time, which is only
 * when we've got the real addresses to the C# and I# closures.
 *
 */
574 575
static INFO_TBL_CONST StgInfoTable czh_static_info;
static INFO_TBL_CONST StgInfoTable izh_static_info;
sof's avatar
sof committed
576 577 578 579 580 581 582
#define Char_hash_static_info czh_static_info
#define Int_hash_static_info izh_static_info
#else
#define Char_hash_static_info Czh_static_info
#define Int_hash_static_info Izh_static_info
#endif

583 584
#define CHARLIKE_HDR(n)						\
	{							\
sof's avatar
sof committed
585
	  STATIC_HDR(Char_hash_static_info, /* C# */   		\
586 587 588 589 590 591
			 CCS_DONTZuCARE),			\
          data : n						\
	}
					     
#define INTLIKE_HDR(n)						\
	{							\
sof's avatar
sof committed
592
	  STATIC_HDR(Int_hash_static_info,  /* I# */  		\
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896
			 CCS_DONTZuCARE),			\
          data : n						\
	}

/* put these in the *data* section, since the garbage collector relies
 * on the fact that static closures live in the data section.
 */

/* end the name with _closure, to convince the mangler this is a closure */

StgIntCharlikeClosure CHARLIKE_closure[] = {
    CHARLIKE_HDR(0),
    CHARLIKE_HDR(1),
    CHARLIKE_HDR(2),
    CHARLIKE_HDR(3),
    CHARLIKE_HDR(4),
    CHARLIKE_HDR(5),
    CHARLIKE_HDR(6),
    CHARLIKE_HDR(7),
    CHARLIKE_HDR(8),
    CHARLIKE_HDR(9),
    CHARLIKE_HDR(10),
    CHARLIKE_HDR(11),
    CHARLIKE_HDR(12),
    CHARLIKE_HDR(13),
    CHARLIKE_HDR(14),
    CHARLIKE_HDR(15),
    CHARLIKE_HDR(16),
    CHARLIKE_HDR(17),
    CHARLIKE_HDR(18),
    CHARLIKE_HDR(19),
    CHARLIKE_HDR(20),
    CHARLIKE_HDR(21),
    CHARLIKE_HDR(22),
    CHARLIKE_HDR(23),
    CHARLIKE_HDR(24),
    CHARLIKE_HDR(25),
    CHARLIKE_HDR(26),
    CHARLIKE_HDR(27),
    CHARLIKE_HDR(28),
    CHARLIKE_HDR(29),
    CHARLIKE_HDR(30),
    CHARLIKE_HDR(31),
    CHARLIKE_HDR(32),
    CHARLIKE_HDR(33),
    CHARLIKE_HDR(34),
    CHARLIKE_HDR(35),
    CHARLIKE_HDR(36),
    CHARLIKE_HDR(37),
    CHARLIKE_HDR(38),
    CHARLIKE_HDR(39),
    CHARLIKE_HDR(40),
    CHARLIKE_HDR(41),
    CHARLIKE_HDR(42),
    CHARLIKE_HDR(43),
    CHARLIKE_HDR(44),
    CHARLIKE_HDR(45),
    CHARLIKE_HDR(46),
    CHARLIKE_HDR(47),
    CHARLIKE_HDR(48),
    CHARLIKE_HDR(49),
    CHARLIKE_HDR(50),
    CHARLIKE_HDR(51),
    CHARLIKE_HDR(52),
    CHARLIKE_HDR(53),
    CHARLIKE_HDR(54),
    CHARLIKE_HDR(55),
    CHARLIKE_HDR(56),
    CHARLIKE_HDR(57),
    CHARLIKE_HDR(58),
    CHARLIKE_HDR(59),
    CHARLIKE_HDR(60),
    CHARLIKE_HDR(61),
    CHARLIKE_HDR(62),
    CHARLIKE_HDR(63),
    CHARLIKE_HDR(64),
    CHARLIKE_HDR(65),
    CHARLIKE_HDR(66),
    CHARLIKE_HDR(67),
    CHARLIKE_HDR(68),
    CHARLIKE_HDR(69),
    CHARLIKE_HDR(70),
    CHARLIKE_HDR(71),
    CHARLIKE_HDR(72),
    CHARLIKE_HDR(73),
    CHARLIKE_HDR(74),
    CHARLIKE_HDR(75),
    CHARLIKE_HDR(76),
    CHARLIKE_HDR(77),
    CHARLIKE_HDR(78),
    CHARLIKE_HDR(79),
    CHARLIKE_HDR(80),
    CHARLIKE_HDR(81),
    CHARLIKE_HDR(82),
    CHARLIKE_HDR(83),
    CHARLIKE_HDR(84),
    CHARLIKE_HDR(85),
    CHARLIKE_HDR(86),
    CHARLIKE_HDR(87),
    CHARLIKE_HDR(88),
    CHARLIKE_HDR(89),
    CHARLIKE_HDR(90),
    CHARLIKE_HDR(91),
    CHARLIKE_HDR(92),
    CHARLIKE_HDR(93),
    CHARLIKE_HDR(94),
    CHARLIKE_HDR(95),
    CHARLIKE_HDR(96),
    CHARLIKE_HDR(97),
    CHARLIKE_HDR(98),
    CHARLIKE_HDR(99),
    CHARLIKE_HDR(100),
    CHARLIKE_HDR(101),
    CHARLIKE_HDR(102),
    CHARLIKE_HDR(103),
    CHARLIKE_HDR(104),
    CHARLIKE_HDR(105),
    CHARLIKE_HDR(106),
    CHARLIKE_HDR(107),
    CHARLIKE_HDR(108),
    CHARLIKE_HDR(109),
    CHARLIKE_HDR(110),
    CHARLIKE_HDR(111),
    CHARLIKE_HDR(112),
    CHARLIKE_HDR(113),
    CHARLIKE_HDR(114),
    CHARLIKE_HDR(115),
    CHARLIKE_HDR(116),
    CHARLIKE_HDR(117),
    CHARLIKE_HDR(118),
    CHARLIKE_HDR(119),
    CHARLIKE_HDR(120),
    CHARLIKE_HDR(121),
    CHARLIKE_HDR(122),
    CHARLIKE_HDR(123),
    CHARLIKE_HDR(124),
    CHARLIKE_HDR(125),
    CHARLIKE_HDR(126),
    CHARLIKE_HDR(127),
    CHARLIKE_HDR(128),
    CHARLIKE_HDR(129),
    CHARLIKE_HDR(130),
    CHARLIKE_HDR(131),
    CHARLIKE_HDR(132),
    CHARLIKE_HDR(133),
    CHARLIKE_HDR(134),
    CHARLIKE_HDR(135),
    CHARLIKE_HDR(136),
    CHARLIKE_HDR(137),
    CHARLIKE_HDR(138),
    CHARLIKE_HDR(139),
    CHARLIKE_HDR(140),
    CHARLIKE_HDR(141),
    CHARLIKE_HDR(142),
    CHARLIKE_HDR(143),
    CHARLIKE_HDR(144),
    CHARLIKE_HDR(145),
    CHARLIKE_HDR(146),
    CHARLIKE_HDR(147),
    CHARLIKE_HDR(148),
    CHARLIKE_HDR(149),
    CHARLIKE_HDR(150),
    CHARLIKE_HDR(151),
    CHARLIKE_HDR(152),
    CHARLIKE_HDR(153),
    CHARLIKE_HDR(154),
    CHARLIKE_HDR(155),
    CHARLIKE_HDR(156),
    CHARLIKE_HDR(157),
    CHARLIKE_HDR(158),
    CHARLIKE_HDR(159),
    CHARLIKE_HDR(160),
    CHARLIKE_HDR(161),
    CHARLIKE_HDR(162),
    CHARLIKE_HDR(163),
    CHARLIKE_HDR(164),
    CHARLIKE_HDR(165),
    CHARLIKE_HDR(166),
    CHARLIKE_HDR(167),
    CHARLIKE_HDR(168),
    CHARLIKE_HDR(169),
    CHARLIKE_HDR(170),
    CHARLIKE_HDR(171),
    CHARLIKE_HDR(172),
    CHARLIKE_HDR(173),
    CHARLIKE_HDR(174),
    CHARLIKE_HDR(175),
    CHARLIKE_HDR(176),
    CHARLIKE_HDR(177),
    CHARLIKE_HDR(178),
    CHARLIKE_HDR(179),
    CHARLIKE_HDR(180),
    CHARLIKE_HDR(181),
    CHARLIKE_HDR(182),
    CHARLIKE_HDR(183),
    CHARLIKE_HDR(184),
    CHARLIKE_HDR(185),
    CHARLIKE_HDR(186),
    CHARLIKE_HDR(187),
    CHARLIKE_HDR(188),
    CHARLIKE_HDR(189),
    CHARLIKE_HDR(190),
    CHARLIKE_HDR(191),
    CHARLIKE_HDR(192),
    CHARLIKE_HDR(193),
    CHARLIKE_HDR(194),
    CHARLIKE_HDR(195),
    CHARLIKE_HDR(196),
    CHARLIKE_HDR(197),
    CHARLIKE_HDR(198),
    CHARLIKE_HDR(199),
    CHARLIKE_HDR(200),
    CHARLIKE_HDR(201),
    CHARLIKE_HDR(202),
    CHARLIKE_HDR(203),
    CHARLIKE_HDR(204),
    CHARLIKE_HDR(205),
    CHARLIKE_HDR(206),
    CHARLIKE_HDR(207),
    CHARLIKE_HDR(208),
    CHARLIKE_HDR(209),
    CHARLIKE_HDR(210),
    CHARLIKE_HDR(211),
    CHARLIKE_HDR(212),
    CHARLIKE_HDR(213),
    CHARLIKE_HDR(214),
    CHARLIKE_HDR(215),
    CHARLIKE_HDR(216),
    CHARLIKE_HDR(217),
    CHARLIKE_HDR(218),
    CHARLIKE_HDR(219),
    CHARLIKE_HDR(220),
    CHARLIKE_HDR(221),
    CHARLIKE_HDR(222),
    CHARLIKE_HDR(223),
    CHARLIKE_HDR(224),
    CHARLIKE_HDR(225),
    CHARLIKE_HDR(226),
    CHARLIKE_HDR(227),
    CHARLIKE_HDR(228),
    CHARLIKE_HDR(229),
    CHARLIKE_HDR(230),
    CHARLIKE_HDR(231),
    CHARLIKE_HDR(232),
    CHARLIKE_HDR(233),
    CHARLIKE_HDR(234),
    CHARLIKE_HDR(235),
    CHARLIKE_HDR(236),
    CHARLIKE_HDR(237),
    CHARLIKE_HDR(238),
    CHARLIKE_HDR(239),
    CHARLIKE_HDR(240),
    CHARLIKE_HDR(241),
    CHARLIKE_HDR(242),
    CHARLIKE_HDR(243),
    CHARLIKE_HDR(244),
    CHARLIKE_HDR(245),
    CHARLIKE_HDR(246),
    CHARLIKE_HDR(247),
    CHARLIKE_HDR(248),
    CHARLIKE_HDR(249),
    CHARLIKE_HDR(250),
    CHARLIKE_HDR(251),
    CHARLIKE_HDR(252),
    CHARLIKE_HDR(253),
    CHARLIKE_HDR(254),
    CHARLIKE_HDR(255)
};

StgIntCharlikeClosure INTLIKE_closure[] = {
    INTLIKE_HDR(-16),	/* MIN_INTLIKE == -16 */
    INTLIKE_HDR(-15),
    INTLIKE_HDR(-14),
    INTLIKE_HDR(-13),
    INTLIKE_HDR(-12),
    INTLIKE_HDR(-11),
    INTLIKE_HDR(-10),
    INTLIKE_HDR(-9),
    INTLIKE_HDR(-8),
    INTLIKE_HDR(-7),
    INTLIKE_HDR(-6),
    INTLIKE_HDR(-5),
    INTLIKE_HDR(-4),
    INTLIKE_HDR(-3),
    INTLIKE_HDR(-2),
    INTLIKE_HDR(-1),
    INTLIKE_HDR(0),
    INTLIKE_HDR(1),
    INTLIKE_HDR(2),
    INTLIKE_HDR(3),
    INTLIKE_HDR(4),
    INTLIKE_HDR(5),
    INTLIKE_HDR(6),
    INTLIKE_HDR(7),
    INTLIKE_HDR(8),
    INTLIKE_HDR(9),
    INTLIKE_HDR(10),
    INTLIKE_HDR(11),
    INTLIKE_HDR(12),
    INTLIKE_HDR(13),
    INTLIKE_HDR(14),
    INTLIKE_HDR(15),
    INTLIKE_HDR(16)	/* MAX_INTLIKE == 16 */
};