[project @ 1999-06-25 09:13:37 by simonmar]
[ghc-hetmet.git] / ghc / includes / ClosureMacros.h
index db7970c..34b08c3 100644 (file)
@@ -1,5 +1,5 @@
 /* ----------------------------------------------------------------------------
- * $Id: ClosureMacros.h,v 1.5 1999/03/02 19:44:08 sof Exp $
+ * $Id: ClosureMacros.h,v 1.17 1999/06/25 09:13:37 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
 #define SET_INFO(c,i) ((c)->header.info = (i))
 #define GET_INFO(c)   ((c)->header.info)
 
-#if USE_MINIINTERPRETER
+#ifdef TABLES_NEXT_TO_CODE
+#define INIT_ENTRY(e)    code : {}
+#define GET_ENTRY(c)     ((StgFunPtr)((c)->header.info))
+#define ENTRY_CODE(info) (info)
+#define INFO_PTR_TO_STRUCT(info) ((StgInfoTable *)(info) - 1)
+#define get_itbl(c)      (((c)->header.info) - 1)
+static __inline__ StgFunPtr get_entry(const StgInfoTable *itbl) {
+    return (StgFunPtr)(itbl+1);
+}
+#else
 #define INIT_ENTRY(e)    entry : (F_)(e)
 #define GET_ENTRY(c)     ((c)->header.info->entry)
-#define ENTRY_CODE(info) (stgCast(StgInfoTable*,info)->entry)
-#define INFO_PTR_TO_STRUCT(info) (info)
+#define ENTRY_CODE(info) (((StgInfoTable *)info)->entry)
+#define INFO_PTR_TO_STRUCT(info) ((StgInfoTable *)info)
 #define get_itbl(c)      ((c)->header.info)
 static __inline__ StgFunPtr get_entry(const StgInfoTable *itbl) {
     return itbl->entry;
 }
-#else
-#define INIT_ENTRY(e)    code : {}
-#define GET_ENTRY(c)     stgCast(StgFunPtr,((c)->header.info))
-#define ENTRY_CODE(info) (info)
-#define INFO_PTR_TO_STRUCT(info) (stgCast(StgInfoTable*,info) - 1)
-#define get_itbl(c)      (stgCast(StgInfoTable*,(c)->header.info) -1)
-static __inline__ StgFunPtr get_entry(const StgInfoTable *itbl) {
-    return stgCast(StgFunPtr,itbl+1);
-}
 #endif
 
 /* -----------------------------------------------------------------------------
@@ -98,32 +98,46 @@ static __inline__ StgFunPtr get_entry(const StgInfoTable *itbl) {
  * _end } end of read-write data space 
  */
 extern StgFun start;
-extern StgFun TEXT_SECTION_END_MARKER_DECL;
-extern StgFun DATA_SECTION_END_MARKER_DECL;
+
+extern void* TEXT_SECTION_END_MARKER_DECL;
+extern void* DATA_SECTION_END_MARKER_DECL;
 
 #define IS_CODE_PTR(p) ((P_)(p) < (P_)&TEXT_SECTION_END_MARKER)
 #define IS_DATA_PTR(p) ((P_)(p) >= (P_)&TEXT_SECTION_END_MARKER && (P_)(p) < (P_)&DATA_SECTION_END_MARKER)
 #define IS_USER_PTR(p) ((P_)(p) >= (P_)&DATA_SECTION_END_MARKER)
 
 #ifdef HAVE_WIN32_DLL_SUPPORT
-/* ToDo: clean up */
-extern char* base_non_committed;
-#define HEAP_ALLOCED(x)  (((char*)(x) >= base_non_committed) && ((char*)(x) <= (base_non_committed + 128 * 1024 * 1024)))
+extern int is_heap_alloced(const void* x);
+# define HEAP_ALLOCED(x)  (is_heap_alloced(x))
+#else
+# define HEAP_ALLOCED(x)  IS_USER_PTR(x)
 #endif
 
-#ifndef HAVE_WIN32_DLL_SUPPORT
-#define LOOKS_LIKE_STATIC(r) IS_DATA_PTR(r)
-#else
-/* Static closures are 'identified' by being prefixed with a zero. This is
-   so that they can be distinguished from pointers to info tables. Relies
-   on the fact that info tables are reversed.
+/* When working with Win32 DLLs, static closures are identified by
+   being prefixed with a zero word. This is needed so that we can
+   distinguish between pointers to static closures and (reversed!)
+   info tables.
+
+   This 'scheme' breaks down for closure tables such as CHARLIKE,
+   so we catch these separately.
    
-   LOOKS_LIKE_STATIC_CLOSURE() - discriminates between static closures and info tbls
-                                 (needed by LOOKS_LIKE_GHC_INFO() below - [Win32 DLLs only.])
-   LOOKS_LIKE_STATIC() - distinguishes between static and heap allocated data.
+   LOOKS_LIKE_STATIC_CLOSURE() 
+       - discriminates between static closures and info tbls
+         (needed by LOOKS_LIKE_GHC_INFO() below - [Win32 DLLs only.])
+   LOOKS_LIKE_STATIC() 
+       - distinguishes between static and heap allocated data.
  */
+#ifdef HAVE_WIN32_DLL_SUPPORT
 #define LOOKS_LIKE_STATIC(r) (!(HEAP_ALLOCED(r)))
-#define LOOKS_LIKE_STATIC_CLOSURE(r) ((*(((unsigned long *)(r))-1)) == 0)
+
+/* Tiresome predicates needed to check for pointers into the closure tables */
+#define IS_CHARLIKE_CLOSURE(p)  ( (P_)(p) >= (P_)CHARLIKE_closure && (char*)(p) <= ((char*)CHARLIKE_closure + 255 * sizeof(StgIntCharlikeClosure)) )
+#define IS_INTLIKE_CLOSURE(p)  ( (P_)(p) >= (P_)INTLIKE_closure && (char*)(p) <= ((char*)INTLIKE_closure + 32 * sizeof(StgIntCharlikeClosure)) )
+
+#define LOOKS_LIKE_STATIC_CLOSURE(r) (((*(((unsigned long *)(r))-1)) == 0) || IS_CHARLIKE_CLOSURE(r) || IS_INTLIKE_CLOSURE(r))
+#else
+#define LOOKS_LIKE_STATIC(r) IS_DATA_PTR(r)
+#define LOOKS_LIKE_STATIC_CLOSURE(r) IS_DATA_PTR(r)
 #endif
 
 
@@ -139,23 +153,21 @@ extern char* base_non_committed;
    approximations.  This absolutely has to be fixed.
    -------------------------------------------------------------------------- */
 
+#ifdef INTERPRETER
 #ifdef USE_MINIINTERPRETER
 /* yoiks: one of the dreaded pointer equality tests */
-#define IS_HUGS_CONSTR_INFO(info) (stgCast(StgInfoTable*,info)->entry == stgCast(StgFunPtr,&Hugs_CONSTR_entry))
+#define IS_HUGS_CONSTR_INFO(info) (((StgInfoTable *)(info))->entry == (StgFunPtr)&Hugs_CONSTR_entry)
+#else
+#define IS_HUGS_CONSTR_INFO(info) 0 /* ToDo: more than mildly bogus */
+#endif
 #else
 #define IS_HUGS_CONSTR_INFO(info) 0 /* ToDo: more than mildly bogus */
 #endif
 
-#ifdef USE_MINIINTERPRETER
-/* in the mininterpreter, we put infotables on closures */
-#define LOOKS_LIKE_GHC_INFO(info) IS_CODE_PTR(info)
+#ifdef HAVE_WIN32_DLL_SUPPORT
+# define LOOKS_LIKE_GHC_INFO(info) (!HEAP_ALLOCED(info) && !LOOKS_LIKE_STATIC_CLOSURE(info))
 #else
-/* otherwise we have entry pointers on closures */
-# ifdef HAVE_WIN32_DLL_SUPPORT
-#  define LOOKS_LIKE_GHC_INFO(info) (!HEAP_ALLOCED(info) && !LOOKS_LIKE_STATIC_CLOSURE(info))
-# else
-#  define LOOKS_LIKE_GHC_INFO(info) IS_CODE_PTR(info)
-# endif
+# define LOOKS_LIKE_GHC_INFO(info) IS_CODE_PTR(info)
 #endif
 
 /* -----------------------------------------------------------------------------
@@ -251,9 +263,9 @@ static __inline__ StgWord tso_sizeW ( StgTSO *tso )
 #define SET_STATIC_PAR_HDR(stuff)
 #endif
 
-#ifdef TICKY
-#define SET_TICKY_HDR(c,stuff)         (c)->header.ticky.updated = stuff
-#define SET_STATIC_TICKY_HDR(stuff)    ticky : { updated : stuff }
+#ifdef TICKY_TICKY
+#define SET_TICKY_HDR(c,stuff)         /* old: (c)->header.ticky.updated = stuff */
+#define SET_STATIC_TICKY_HDR(stuff)    /* old: ticky : { updated : stuff } */
 #else
 #define SET_TICKY_HDR(c,stuff)
 #define SET_STATIC_TICKY_HDR(stuff)
@@ -303,6 +315,14 @@ SET_STATIC_HDR(PrelBase_CZh_closure,PrelBase_CZh_info,costCentreStack,const);
 #define STATIC_LINK(info,p) \
    (*stgCast(StgClosure**,&((p)->payload[info->layout.payload.ptrs + \
                                        info->layout.payload.nptrs])))
+/* These macros are optimised versions of the above for certain
+ * closure types.  They *must* be equivalent to the generic
+ * STATIC_LINK.
+ */
+#define FUN_STATIC_LINK(p)   ((p)->payload[0])
+#define THUNK_STATIC_LINK(p) ((p)->payload[2])
+#define IND_STATIC_LINK(p)   ((p)->payload[1])
+
 #define STATIC_LINK2(info,p) \
    (*stgCast(StgClosure**,&((p)->payload[info->layout.payload.ptrs + \
                                        info->layout.payload.nptrs + 1])))
@@ -315,6 +335,12 @@ SET_STATIC_HDR(PrelBase_CZh_closure,PrelBase_CZh_info,costCentreStack,const);
 #define INTLIKE_CLOSURE(n)  ((P_)&INTLIKE_closure[(n)-MIN_INTLIKE])
 
 /* -----------------------------------------------------------------------------
+   Closure Tables (for enumerated data types)
+   -------------------------------------------------------------------------- */
+
+#define CLOSURE_TBL(lbl) const StgClosure *lbl[] = {
+
+/* -----------------------------------------------------------------------------
    Payload access
    -------------------------------------------------------------------------- */
 
@@ -344,5 +370,7 @@ SET_STATIC_HDR(PrelBase_CZh_closure,PrelBase_CZh_info,costCentreStack,const);
 #define bcoConstFloat( bco, i )  (PK_FLT(stgCast(StgWord*,(bco)->payload+(bco)->n_ptrs+i)))
 #define bcoConstDouble( bco, i ) (PK_DBL(stgCast(StgWord*,(bco)->payload+(bco)->n_ptrs+i)))
 #define bcoInstr( bco, i )       (stgCast(StgWord8*,      ((bco)->payload+(bco)->n_ptrs+(bco)->n_words))[i])
+static __inline__ StgInt bcoInstr16 ( StgBCO* bco, unsigned int i )
+{ StgInt x = (bcoInstr(bco,i) << 8) + bcoInstr(bco,i+1); return x; }
 
 #endif /* CLOSUREMACROS_H */