[project @ 2000-02-24 14:09:14 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / storage.c
index b052bc3..39d969f 100644 (file)
@@ -2,14 +2,15 @@
 /* --------------------------------------------------------------------------
  * Primitives for manipulating global data structures
  *
- * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
- * Haskell Group 1994-99, and is distributed as Open Source software
- * under the Artistic License; see the file "Artistic" that is included
- * in the distribution for details.
+ * The Hugs 98 system is Copyright (c) Mark P Jones, Alastair Reid, the
+ * Yale Haskell Group, and the Oregon Graduate Institute of Science and
+ * Technology, 1994-1999, All rights reserved.  It is distributed as
+ * free software under the license in the file "License", which is
+ * included in the distribution.
  *
  * $RCSfile: storage.c,v $
- * $Revision: 1.5 $
- * $Date: 1999/03/09 14:51:13 $
+ * $Revision: 1.44 $
+ * $Date: 2000/02/24 14:05:55 $
  * ------------------------------------------------------------------------*/
 
 #include "prelude.h"
@@ -17,6 +18,7 @@
 #include "backend.h"
 #include "connect.h"
 #include "errors.h"
+#include "object.h"
 #include <setjmp.h>
 
 /*#define DEBUG_SHOWUSE*/
@@ -27,9 +29,7 @@
 
 static Int  local hash                  Args((String));
 static Int  local saveText              Args((Text));
-#if !IGNORE_MODULES
 static Module local findQualifier       Args((Text));
-#endif
 static Void local hashTycon             Args((Tycon));
 static List local insertTycon           Args((Tycon,List));
 static Void local hashName              Args((Name));
@@ -41,17 +41,8 @@ static Cell local markCell              Args((Cell));
 static Void local markSnd               Args((Cell));
 static Cell local lowLevelLastIn        Args((Cell));
 static Cell local lowLevelLastOut       Args((Cell));
-/* from STG */
        Module local moduleOfScript      Args((Script));
        Script local scriptThisFile      Args((Text));
-/* from 98 */
-#if IO_HANDLES
-static Void local freeHandle            Args((Int));
-#endif
-#if GC_STABLEPTRS
-static Void local resetStablePtrs       Args((Void));
-#endif
-/* end */
 
 /* --------------------------------------------------------------------------
  * Text storage:
@@ -145,6 +136,28 @@ Text t; {                               /* generated internally            */
     return (t<0 || t>=NUM_TEXT);
 }
 
+#define MAX_FIXLIT 100
+Text fixLitText(t)                /* fix literal text that might include \ */
+Text t; {
+    String   s = textToStr(t);
+    char     p[MAX_FIXLIT];
+    Int      i;
+    for(i = 0;i < MAX_FIXLIT-2 && *s;s++) {
+      p[i++] = *s;
+      if (*s == '\\') {
+       p[i++] = '\\';
+      } 
+    }
+    if (i < MAX_FIXLIT-2) {
+      p[i] = 0;
+    } else {
+       ERRMSG(0) "storage space exhausted for internal literal string"
+       EEND;
+    }
+    return (findText(p));
+}
+#undef MAX_FIXLIT
+
 static Int local hash(s)                /* Simple hash function on strings */
 String s; {
     int v, j = 3;
@@ -218,6 +231,196 @@ Text t; {                               /* at top of text table            */
 }
 
 
+static int fromHexDigit ( char c )
+{
+   switch (c) {
+      case '0': case '1': case '2': case '3': case '4':
+      case '5': case '6': case '7': case '8': case '9':
+         return c - '0';
+      case 'a': case 'A': return 10;
+      case 'b': case 'B': return 11;
+      case 'c': case 'C': return 12;
+      case 'd': case 'D': return 13;
+      case 'e': case 'E': return 14;
+      case 'f': case 'F': return 15;
+      default: return -1;
+   }
+}
+
+
+/* returns findText (unZencode s) */
+Text unZcodeThenFindText ( String s )
+{
+   unsigned char* p;
+   Int            n, nn, i;
+   Text           t;
+
+   assert(s);
+   nn = 100 + 10 * strlen(s);
+   p = malloc ( nn );
+   if (!p) internal ("unZcodeThenFindText: malloc failed");
+   n = 0;
+
+   while (1) {
+      if (!(*s)) break;
+      if (n > nn-90) internal ("unZcodeThenFindText: result is too big");
+      if (*s != 'z' && *s != 'Z') {
+         p[n] = *s; n++; s++; 
+         continue;
+      }
+      s++;
+      if (!(*s)) goto parse_error;
+      switch (*s++) {
+         case 'Z': p[n++] = 'Z'; break;
+         case 'C': p[n++] = ':'; break;
+         case 'L': p[n++] = '('; break;
+         case 'R': p[n++] = ')'; break;
+         case 'M': p[n++] = '['; break;
+         case 'N': p[n++] = ']'; break;
+         case 'z': p[n++] = 'z'; break;
+         case 'a': p[n++] = '&'; break;
+         case 'b': p[n++] = '|'; break;
+         case 'd': p[n++] = '$'; break;
+         case 'e': p[n++] = '='; break;
+         case 'g': p[n++] = '>'; break;
+         case 'h': p[n++] = '#'; break;
+         case 'i': p[n++] = '.'; break;
+         case 'l': p[n++] = '<'; break;
+         case 'm': p[n++] = '-'; break;
+         case 'n': p[n++] = '!'; break;
+         case 'p': p[n++] = '+'; break;
+         case 'q': p[n++] = '\\'; break;
+         case 'r': p[n++] = '\''; break;
+         case 's': p[n++] = '/'; break;
+         case 't': p[n++] = '*'; break;
+         case 'u': p[n++] = '^'; break;
+         case 'v': p[n++] = '%'; break;
+         case 'x':
+            if (!s[0] || !s[1]) goto parse_error;
+            if (fromHexDigit(s[0]) < 0 || fromHexDigit(s[1]) < 0) goto parse_error;
+            p[n++] = 16 * fromHexDigit(s[0]) + fromHexDigit(s[1]);
+            p += 2; s += 2;
+            break;
+         case '0': case '1': case '2': case '3': case '4':
+         case '5': case '6': case '7': case '8': case '9':
+            i = 0;
+            s--;
+            while (*s && isdigit((int)(*s))) {
+               i = 10 * i + (*s - '0');
+               s++;
+            }
+            if (*s != 'T') goto parse_error;
+            s++;
+            p[n++] = '(';
+            while (i > 0) { p[n++] = ','; i--; };
+            p[n++] = ')';
+            break;
+         default: 
+            goto parse_error;
+      }      
+   }
+   p[n] = 0;
+   t = findText(p);
+   free(p);
+   return t;
+
+  parse_error:
+   free(p);
+   fprintf ( stderr, "\nstring = `%s'\n", s );
+   internal ( "unZcodeThenFindText: parse error on above string");
+   return NIL; /*notreached*/
+}
+
+
+Text enZcodeThenFindText ( String s )
+{
+   unsigned char* p;
+   Int            n, nn;
+   Text           t;
+   char toHex[16] = "0123456789ABCDEF";
+
+   assert(s);
+   nn = 100 + 10 * strlen(s);
+   p = malloc ( nn );
+   if (!p) internal ("enZcodeThenFindText: malloc failed");
+   n = 0;
+   while (1) {
+      if (!(*s)) break;
+      if (n > nn-90) internal ("enZcodeThenFindText: result is too big");
+      if (*s != 'z' 
+          && *s != 'Z'
+          && (isalnum((int)(*s)) || *s == '_')) { 
+         p[n] = *s; n++; s++;
+         continue;
+      }
+      if (*s == '(') {
+         int tup = 0;
+         char num[12];
+         s++;
+         while (*s && *s==',') { s++; tup++; };
+         if (*s != ')') internal("enZcodeThenFindText: invalid tuple type");
+         s++;
+         p[n++] = 'Z';
+         sprintf(num,"%d",tup);
+         p[n] = 0; strcat ( &(p[n]), num ); n += strlen(num);
+         p[n++] = 'T';
+         continue;         
+      }
+      switch (*s++) {
+         case '(': p[n++] = 'Z'; p[n++] = 'L'; break;
+         case ')': p[n++] = 'Z'; p[n++] = 'R'; break;
+         case '[': p[n++] = 'Z'; p[n++] = 'M'; break;
+         case ']': p[n++] = 'Z'; p[n++] = 'N'; break;
+         case ':': p[n++] = 'Z'; p[n++] = 'C'; break;
+         case 'Z': p[n++] = 'Z'; p[n++] = 'Z'; break;
+         case 'z': p[n++] = 'z'; p[n++] = 'z'; break;
+         case '&': p[n++] = 'z'; p[n++] = 'a'; break;
+         case '|': p[n++] = 'z'; p[n++] = 'b'; break;
+         case '$': p[n++] = 'z'; p[n++] = 'd'; break;
+         case '=': p[n++] = 'z'; p[n++] = 'e'; break;
+         case '>': p[n++] = 'z'; p[n++] = 'g'; break;
+         case '#': p[n++] = 'z'; p[n++] = 'h'; break;
+         case '.': p[n++] = 'z'; p[n++] = 'i'; break;
+         case '<': p[n++] = 'z'; p[n++] = 'l'; break;
+         case '-': p[n++] = 'z'; p[n++] = 'm'; break;
+         case '!': p[n++] = 'z'; p[n++] = 'n'; break;
+         case '+': p[n++] = 'z'; p[n++] = 'p'; break;
+         case '\'': p[n++] = 'z'; p[n++] = 'q'; break;
+         case '\\': p[n++] = 'z'; p[n++] = 'r'; break;
+         case '/': p[n++] = 'z'; p[n++] = 's'; break;
+         case '*': p[n++] = 'z'; p[n++] = 't'; break;
+         case '^': p[n++] = 'z'; p[n++] = 'u'; break;
+         case '%': p[n++] = 'z'; p[n++] = 'v'; break;
+         default: s--; p[n++] = 'z'; p[n++] = 'x';
+                       p[n++] = toHex[(int)(*s)/16];
+                       p[n++] = toHex[(int)(*s)%16];
+                  s++; break;
+      }
+   }
+   p[n] = 0;
+   t = findText(p);
+   free(p);
+   return t;
+}
+
+
+Text textOf ( Cell c )
+{
+   Bool ok = 
+          (whatIs(c)==VARIDCELL
+           || whatIs(c)==CONIDCELL
+           || whatIs(c)==VAROPCELL
+           || whatIs(c)==CONOPCELL
+           || whatIs(c)==STRCELL
+           || whatIs(c)==DICTVAR
+          );
+   if (!ok) {
+      fprintf(stderr, "\ntextOf: bad tag %d\n",whatIs(c) );
+      internal("textOf: bad tag");
+   }
+   return snd(c);
+}
+
 /* --------------------------------------------------------------------------
  * Ext storage:
  *
@@ -277,10 +480,10 @@ Text t; {
     tycon(tyconHw).what          = NIL;
     tycon(tyconHw).conToTag      = NIL;
     tycon(tyconHw).tagToCon      = NIL;
-#if !IGNORE_MODULES
+    tycon(tyconHw).tuple         = -1;
     tycon(tyconHw).mod           = currentModule;
+    tycon(tyconHw).itbl          = NULL;
     module(currentModule).tycons = cons(tyconHw,module(currentModule).tycons);
-#endif
     tycon(tyconHw).nextTyconHash = tyconHash[h];
     tyconHash[h]                 = tyconHw;
 
@@ -298,12 +501,12 @@ Text t; {
 
 Tycon addTycon(tc)  /* Insert Tycon in tycon table - if no clash is caused */
 Tycon tc; {
-    Tycon oldtc = findTycon(tycon(tc).text);
+    Tycon oldtc; 
+    assert(whatIs(tc)==TYCON || whatIs(tc)==TUPLE);
+    oldtc = findTycon(tycon(tc).text);
     if (isNull(oldtc)) {
         hashTycon(tc);
-#if !IGNORE_MODULES
         module(currentModule).tycons=cons(tc,module(currentModule).tycons);
-#endif
         return tc;
     } else
         return oldtc;
@@ -311,10 +514,16 @@ Tycon tc; {
 
 static Void local hashTycon(tc)         /* Insert Tycon into hash table    */
 Tycon tc; {
-    Text  t = tycon(tc).text;
-    Int   h = tHash(t);
-    tycon(tc).nextTyconHash = tyconHash[h];
-    tyconHash[h]            = tc;
+  if (!(isTycon(tc) || isTuple(tc))) {
+    printf("\nbad stuff: " ); print(tc,10); printf("\n");
+      assert(isTycon(tc) || isTuple(tc));
+  }
+   if (1) {
+     Text  t = tycon(tc).text;
+     Int   h = tHash(t);
+     tycon(tc).nextTyconHash = tyconHash[h];
+     tyconHash[h]            = tc;
+   }
 }
 
 Tycon findQualTycon(id) /*locate (possibly qualified) Tycon in tycon table */
@@ -325,9 +534,6 @@ Cell id; {
         case CONOPCELL :
             return findTycon(textOf(id));
         case QUALIDENT : {
-#if IGNORE_MODULES
-            return findTycon(qtextOf(id));
-#else /* !IGNORE_MODULES */
             Text   t  = qtextOf(id);
             Module m  = findQualifier(qmodOf(id));
             List   es = NIL;
@@ -338,11 +544,10 @@ Cell id; {
                     return fst(e);
             }
             return NIL;
-#endif /* !IGNORE_MODULES */
         }
         default : internal("findQualTycon2");
     }
-    return 0; /* NOTREACHED */
+    return NIL; /* NOTREACHED */
 }
 
 Tycon addPrimTycon(t,kind,ar,what,defn) /* add new primitive type constr   */
@@ -392,6 +597,40 @@ List   ts; {                            /* Null pattern matches every tycon*/
     return ts;
 }
 
+Text ghcTupleText_n ( Int n )
+{
+    Int i;
+    Int x = 0; 
+    char buf[104];
+    if (n < 0 || n >= 100) internal("ghcTupleText_n");
+    if (n == 1) internal("ghcTupleText_n==1");
+    buf[x++] = '(';
+    for (i = 1; i <= n-1; i++) buf[x++] = ',';
+    buf[x++] = ')';
+    buf[x++] = 0;
+    return findText(buf);
+}
+
+Text ghcTupleText(tup)
+Tycon tup; {
+    if (!isTuple(tup)) {
+       assert(isTuple(tup));
+    }
+    return ghcTupleText_n ( tupleOf(tup) );
+}
+
+
+Tycon mkTuple ( Int n )
+{
+   Int i;
+   if (n >= NUM_TUPLES)
+      internal("mkTuple: request for tuple of unsupported size");
+   for (i = TYCMIN; i < tyconHw; i++)
+      if (tycon(i).tuple == n) return i;
+   internal("mkTuple: request for non-existent tuple");
+}
+
+
 /* --------------------------------------------------------------------------
  * Name storage:
  *
@@ -427,13 +666,14 @@ Cell parent; {
     name(nameHw).number       = EXECNAME;
     name(nameHw).defn         = NIL;
     name(nameHw).stgVar       = NIL;
+    name(nameHw).callconv     = NIL;
     name(nameHw).type         = NIL;
     name(nameHw).primop       = 0;
     name(nameHw).mod          = currentModule;
+    name(nameHw).itbl         = NULL;
     module(currentModule).names=cons(nameHw,module(currentModule).names);
     name(nameHw).nextNameHash = nameHash[h];
     nameHash[h]               = nameHw;
-assert ( name(nameHw).nextNameHash != nameHash[h] );
     return nameHw++;
 }
 
@@ -448,12 +688,12 @@ Text t; {
 
 Name addName(nm)                        /* Insert Name in name table - if  */
 Name nm; {                              /* no clash is caused              */
-    Name oldnm = findName(name(nm).text);
+    Name oldnm; 
+    assert(whatIs(nm)==NAME);
+    oldnm = findName(name(nm).text);
     if (isNull(oldnm)) {
         hashName(nm);
-#if !IGNORE_MODULES
         module(currentModule).names=cons(nm,module(currentModule).names);
-#endif
         return nm;
     } else
         return oldnm;
@@ -461,8 +701,11 @@ Name nm; {                              /* no clash is caused              */
 
 static Void local hashName(nm)          /* Insert Name into hash table    */
 Name nm; {
-    Text t               = name(nm).text;
-    Int  h               = nHash(t);
+    Text t;
+    Int  h;
+    assert(isName(nm));
+    t = name(nm).text;
+    h = nHash(t);
     name(nm).nextNameHash = nameHash[h];
     nameHash[h]           = nm;
 }
@@ -478,9 +721,6 @@ Cell id; {                         /* in name table                   */
         case CONOPCELL :
             return findName(textOf(id));
         case QUALIDENT : {
-#if IGNORE_MODULES
-            return findName(qtextOf(id));
-#else /* !IGNORE_MODULES */
             Text   t  = qtextOf(id);
             Module m  = findQualifier(qmodOf(id));
             List   es = NIL;
@@ -506,17 +746,138 @@ Cell id; {                         /* in name table                   */
                 }
             }
             return NIL;
-#endif /* !IGNORE_MODULES */
         }
         default : internal("findQualName2");
     }
     return 0; /* NOTREACHED */
 }
 
+
+Name nameFromStgVar ( StgVar v )
+{
+   Int n;
+   for (n = NAMEMIN; n < nameHw; n++)
+      if (name(n).stgVar == v) return n;
+   return NIL;
+}
+
+void* getHugs_AsmObject_for ( char* s )
+{
+   StgVar v;
+   Text   t = findText(s);
+   Name   n = NIL;
+   for (n = NAMEMIN; n < nameHw; n++)
+      if (name(n).text == t) break;
+   if (n == nameHw) internal("getHugs_AsmObject_for(1)");
+   v = name(n).stgVar;
+   if (!isStgVar(v) || !isPtr(stgVarInfo(v)))
+      internal("getHugs_AsmObject_for(2)");
+   return ptrOf(stgVarInfo(v));
+}
+
 /* --------------------------------------------------------------------------
  * Primitive functions:
  * ------------------------------------------------------------------------*/
 
+Module findFakeModule ( Text t )
+{
+   Module m = findModule(t);
+   if (nonNull(m)) {
+      if (!module(m).fake) internal("findFakeModule");
+   } else {
+      m = newModule(t);
+      module(m).fake = TRUE;
+   }
+   return m;
+}
+
+
+Name addWiredInBoxingTycon
+        ( String modNm, String typeNm, String constrNm,
+          Int rep, Kind kind )
+{
+   Name   n;
+   Tycon  t;
+   Text   modT  = findText(modNm);
+   Text   typeT = findText(typeNm);
+   Text   conT  = findText(constrNm);
+   Module m     = findFakeModule(modT);
+   setCurrModule(m);
+   
+   n = newName(conT,NIL);
+   name(n).arity  = 1;
+   name(n).number = cfunNo(0);
+   name(n).type   = NIL;
+   name(n).primop = (void*)rep;
+
+   t = newTycon(typeT);
+   tycon(t).what = DATATYPE;
+   tycon(t).kind = kind;
+   return n;
+}
+
+
+Tycon addTupleTycon ( Int n )
+{
+   Int    i;
+   Kind   k;
+   Tycon  t;
+   Module m;
+   Name   nm;
+
+   for (i = TYCMIN; i < tyconHw; i++)
+      if (tycon(i).tuple == n) return i;
+
+   if (combined)
+      m = findFakeModule(findText(n==0 ? "PrelBase" : "PrelTup")); else
+      m = findModule(findText("Prelude"));
+
+   setCurrModule(m);
+   k = STAR;
+   for (i = 0; i < n; i++) k = ap(STAR,k);
+   t = newTycon(ghcTupleText_n(n));
+   tycon(t).kind  = k;
+   tycon(t).tuple = n;
+   tycon(t).what  = DATATYPE;
+
+   if (n == 0) {
+      /* maybe we want to do this for all n ? */
+      nm = newName(ghcTupleText_n(n), t);
+      name(nm).type = t;   /* ummm ... for n > 0 */
+   }
+
+   return t;
+}
+
+
+Tycon addWiredInEnumTycon ( String modNm, String typeNm, 
+                            List /*of Text*/ constrs )
+{
+   Int    i;
+   Tycon  t;
+   Text   modT  = findText(modNm);
+   Text   typeT = findText(typeNm);
+   Module m     = findFakeModule(modT);
+   setCurrModule(m);
+
+   t             = newTycon(typeT);
+   tycon(t).kind = STAR;
+   tycon(t).what = DATATYPE;
+   
+   constrs = reverse(constrs);
+   i       = length(constrs);
+   for (; nonNull(constrs); constrs=tl(constrs),i--) {
+      Text conT        = hd(constrs);
+      Name con         = newName(conT,t);
+      name(con).number = cfunNo(i);
+      name(con).type   = t;
+      name(con).parent = t;
+      tycon(t).defn    = cons(con, tycon(t).defn);      
+   }
+   return t;
+}
+
+
 Name addPrimCfunREP(t,arity,no,rep)     /* add primitive constructor func  */
 Text t;                                 /* sets rep, not type              */
 Int  arity;
@@ -686,18 +1047,17 @@ Text t; {
     cclass(classHw).arity     = 0;
     cclass(classHw).kinds     = NIL;
     cclass(classHw).head      = NIL;
+    cclass(classHw).fds       = NIL;
+    cclass(classHw).xfds      = NIL;
     cclass(classHw).dcon      = NIL;
     cclass(classHw).supers    = NIL;
     cclass(classHw).dsels     = NIL;
     cclass(classHw).members   = NIL;
-    cclass(classHw).dbuild    = NIL;
     cclass(classHw).defaults  = NIL;
     cclass(classHw).instances = NIL;
     classes=cons(classHw,classes);
-#if !IGNORE_MODULES
     cclass(classHw).mod       = currentModule;
     module(currentModule).classes=cons(classHw,module(currentModule).classes);
-#endif
     return classHw++;
 }
 
@@ -719,12 +1079,12 @@ Text t; {
 
 Class addClass(c)                       /* Insert Class in class list      */
 Class c; {                              /*  - if no clash caused           */
-    Class oldc = findClass(cclass(c).text);
+    Class oldc; 
+    assert(whatIs(c)==CLASS);
+    oldc = findClass(cclass(c).text);
     if (isNull(oldc)) {
         classes=cons(c,classes);
-#if !IGNORE_MODULES
         module(currentModule).classes=cons(c,module(currentModule).classes);
-#endif
         return c;
     }
     else
@@ -736,9 +1096,6 @@ Cell c; {                               /* class in class list             */
     if (!isQualIdent(c)) {
         return findClass(textOf(c));
     } else {
-#if IGNORE_MODULES
-        return findClass(qtextOf(c));
-#else /* !IGNORE_MODULES */
         Text   t  = qtextOf(c);
         Module m  = findQualifier(qmodOf(c));
         List   es = NIL;
@@ -749,7 +1106,6 @@ Cell c; {                               /* class in class list             */
             if (isPair(e) && isClass(fst(e)) && cclass(fst(e)).text==t) 
                 return fst(e);
         }
-#endif
     }
     return NIL;
 }
@@ -764,6 +1120,7 @@ Inst newInst() {                       /* Add new instance to table        */
     inst(instHw).specifics  = NIL;
     inst(instHw).implements = NIL;
     inst(instHw).builder    = NIL;
+    inst(instHw).mod        = currentModule;
 
     return instHw++;
 }
@@ -804,6 +1161,161 @@ Type tc; {
                          || typeInvolves(arg(ty),tc)));
 }
 
+
+/* Needed by finishGHCInstance to find classes, before the
+   export list has been built -- so we can't use 
+   findQualClass.
+*/
+Class findQualClassWithoutConsultingExportList ( QualId q )
+{
+   Class cl;
+   Text t_mod;
+   Text t_class;
+
+   assert(isQCon(q));
+
+   if (isCon(q)) {
+      t_mod   = NIL;
+      t_class = textOf(q);
+   } else {
+      t_mod   = qmodOf(q);
+      t_class = qtextOf(q);
+   }
+
+   for (cl = CLASSMIN; cl < classHw; cl++) {
+      if (cclass(cl).text == t_class) {
+         /* Class name is ok, but is this the right module? */
+         if (isNull(t_mod)   /* no module name specified */
+             || (nonNull(t_mod) 
+                 && t_mod == module(cclass(cl).mod).text)
+            )
+            return cl;
+      }
+   }
+   return NIL;
+}
+
+
+/* Same deal, except for Tycons. */
+Tycon findQualTyconWithoutConsultingExportList ( QualId q )
+{
+   Tycon tc;
+   Text t_mod;
+   Text t_tycon;
+
+   assert(isQCon(q));
+
+   if (isCon(q)) {
+      t_mod   = NIL;
+      t_tycon = textOf(q);
+   } else {
+      t_mod   = qmodOf(q);
+      t_tycon = qtextOf(q);
+   }
+
+   for (tc = TYCMIN; tc < tyconHw; tc++) {
+      if (tycon(tc).text == t_tycon) {
+         /* Tycon name is ok, but is this the right module? */
+         if (isNull(t_mod)   /* no module name specified */
+             || (nonNull(t_mod) 
+                 && t_mod == module(tycon(tc).mod).text)
+            )
+            return tc;
+      }
+   }
+   return NIL;
+}
+
+Tycon findTyconInAnyModule ( Text t )
+{
+   Tycon tc;
+   for (tc = TYCMIN; tc < tyconHw; tc++)
+      if (tycon(tc).text == t) return tc;
+   return NIL;
+}
+
+Class findClassInAnyModule ( Text t )
+{
+   Class cc;
+   for (cc = CLASSMIN; cc < classHw; cc++)
+      if (cclass(cc).text == t) return cc;
+   return NIL;
+}
+
+Name findNameInAnyModule ( Text t )
+{
+   Name nm;
+   for (nm = NAMEMIN; nm < nameHw; nm++)
+      if (name(nm).text == t) return nm;
+   return NIL;
+}
+
+/* Same deal, except for Names. */
+Name findQualNameWithoutConsultingExportList ( QualId q )
+{
+   Name nm;
+   Text t_mod;
+   Text t_name;
+
+   assert(isQVar(q) || isQCon(q));
+
+   if (isCon(q) || isVar(q)) {
+      t_mod  = NIL;
+      t_name = textOf(q);
+   } else {
+      t_mod  = qmodOf(q);
+      t_name = qtextOf(q);
+   }
+
+   for (nm = NAMEMIN; nm < nameHw; nm++) {
+      if (name(nm).text == t_name) {
+         /* Name is ok, but is this the right module? */
+         if (isNull(t_mod)   /* no module name specified */
+             || (nonNull(t_mod) 
+                 && t_mod == module(name(nm).mod).text)
+            )
+            return nm;
+      }
+   }
+   return NIL;
+}
+
+
+/* returns List of QualId */
+List getAllKnownTyconsAndClasses ( void )
+{
+   Tycon tc;
+   Class nw;
+   List  xs = NIL;
+   for (tc = TYCMIN; tc < tyconHw; tc++) {
+      /* almost certainly undue paranoia about duplicate avoidance, but .. */
+      QualId q = mkQCon( module(tycon(tc).mod).text, tycon(tc).text );
+      if (!qualidIsMember(q,xs))
+         xs = cons ( q, xs );
+   }
+   for (nw = CLASSMIN; nw < classHw; nw++) {
+      QualId q = mkQCon( module(cclass(nw).mod).text, cclass(nw).text );
+      if (!qualidIsMember(q,xs))
+         xs = cons ( q, xs );
+   }
+   return xs;
+}
+
+/* Purely for debugging. */
+void locateSymbolByName ( Text t )
+{
+   Int i;
+   for (i = NAMEMIN; i < nameHw; i++)
+      if (name(i).text == t)
+         fprintf ( stderr, "name(%d)\n", i-NAMEMIN);
+   for (i = TYCMIN; i < tyconHw; i++)
+      if (tycon(i).text == t)
+         fprintf ( stderr, "tycon(%d)\n", i-TYCMIN);
+   for (i = CLASSMIN; i < classHw; i++)
+      if (cclass(i).text == t)
+         fprintf ( stderr, "class(%d)\n", i-CLASSMIN);
+}
+
 /* --------------------------------------------------------------------------
  * Control stack:
  *
@@ -874,7 +1386,6 @@ Void hugsStackOverflow() {          /* Report stack overflow               */
  *
  * ------------------------------------------------------------------------*/
 
-#if !IGNORE_MODULES
 static  Module   moduleHw;              /* next unused Module              */
 struct  Module   DEFTABLE(tabModule,NUM_MODULE); /* Module storage         */
 Module  currentModule;                  /* Module currently being processed*/
@@ -890,16 +1401,33 @@ Text t; {
         ERRMSG(0) "Module storage space exhausted"
         EEND;
     }
-    module(moduleHw).text          = t; /* clear new module record         */
-    module(moduleHw).qualImports   = NIL;
-    module(moduleHw).exports       = NIL;
-    module(moduleHw).tycons        = NIL;
-    module(moduleHw).names         = NIL;
-    module(moduleHw).classes       = NIL;
-    module(moduleHw).objectFile    = 0;
+    module(moduleHw).text             = t; /* clear new module record      */
+    module(moduleHw).qualImports      = NIL;
+    module(moduleHw).fake             = FALSE;
+    module(moduleHw).exports          = NIL;
+    module(moduleHw).tycons           = NIL;
+    module(moduleHw).names            = NIL;
+    module(moduleHw).classes          = NIL;
+    module(moduleHw).object           = NULL;
+    module(moduleHw).objectExtras     = NULL;
+    module(moduleHw).objectExtraNames = NIL;
     return moduleHw++;
 }
 
+void ppModules ( void )
+{
+   Int i;
+   fflush(stderr); fflush(stdout);
+   printf ( "begin MODULES\n" );
+   for (i = moduleHw-1; i >= MODMIN; i--)
+      printf ( " %2d: %16s\n",
+               i-MODMIN, textToStr(module(i).text)
+             );
+   printf ( "end   MODULES\n" );
+   fflush(stderr); fflush(stdout);
+}
+
+
 Module findModule(t)                    /* locate Module in module table  */
 Text t; {
     Module m;
@@ -919,7 +1447,7 @@ Cell c; {
         case CONIDCELL : return findModule(textOf(c));
         default        : internal("findModid");
     }
-    assert(0); return 0; /* NOTREACHED */
+    return NIL;/*NOTUSED*/
 }
 
 static local Module findQualifier(t)    /* locate Module in import list   */
@@ -939,6 +1467,7 @@ Text t; {
 Void setCurrModule(m)              /* set lookup tables for current module */
 Module m; {
     Int i;
+    assert(isModule(m));
     if (m!=currentModule) {
         currentModule = m; /* This is the only assignment to currentModule */
         for (i=0; i<TYCONHSZ; ++i)
@@ -950,7 +1479,81 @@ Module m; {
         classes = module(m).classes;
     }
 }
-#endif /* !IGNORE_MODULES */
+
+Name jrsFindQualName ( Text mn, Text sn )
+{
+   Module m;
+   List   ns;
+
+   for (m=MODMIN; m<moduleHw; m++)
+      if (module(m).text == mn) break;
+   if (m == moduleHw) return NIL;
+   
+   for (ns = module(m).names; nonNull(ns); ns=tl(ns)) 
+      if (name(hd(ns)).text == sn) return hd(ns);
+
+   return NIL;
+}
+
+
+char* nameFromOPtr ( void* p )
+{
+   int i;
+   Module m;
+   for (m=MODMIN; m<moduleHw; m++) {
+      if (module(m).object) {
+         char* nm = ocLookupAddr ( module(m).object, p );
+         if (nm) return nm;
+      }
+   }
+   return NULL;
+}
+
+
+void* lookupOTabName ( Module m, char* sym )
+{
+   if (module(m).object)
+      return ocLookupSym ( module(m).object, sym );
+   return NULL;
+}
+
+
+void* lookupOExtraTabName ( char* sym )
+{
+   ObjectCode* oc;
+   Module      m;
+   for (m = MODMIN; m < moduleHw; m++) {
+      for (oc = module(m).objectExtras; oc; oc=oc->next) {
+         void* ad = ocLookupSym ( oc, sym );
+         if (ad) return ad;
+      }
+   }
+   return NULL;
+}
+
+
+OSectionKind lookupSection ( void* ad )
+{
+   int          i;
+   Module       m;
+   ObjectCode*  oc;
+   OSectionKind sect;
+
+   for (m=MODMIN; m<moduleHw; m++) {
+      if (module(m).object) {
+         sect = ocLookupSection ( module(m).object, ad );
+         if (sect != HUGS_SECTIONKIND_NOINFOAVAIL)
+            return sect;
+      }
+      for (oc = module(m).objectExtras; oc; oc=oc->next) {
+         sect = ocLookupSection ( oc, ad );
+         if (sect != HUGS_SECTIONKIND_NOINFOAVAIL)
+            return sect;
+      }
+   }
+   return HUGS_SECTIONKIND_OTHER;
+}
+
 
 /* --------------------------------------------------------------------------
  * Script file storage:
@@ -967,9 +1570,7 @@ typedef struct {                       /* record of storage state prior to */
     Text  textHw;
     Text  nextNewText;
     Text  nextNewDText;
-#if !IGNORE_MODULES
     Module moduleHw;
-#endif
     Tycon tyconHw;
     Name  nameHw;
     Class classHw;
@@ -990,6 +1591,25 @@ Int val, mx; {
 static Script scriptHw;                 /* next unused script number       */
 static script scripts[NUM_SCRIPTS];     /* storage for script records      */
 
+
+void ppScripts ( void )
+{
+   Int i;
+   fflush(stderr); fflush(stdout);
+   printf ( "begin SCRIPTS\n" );
+   for (i = scriptHw-1; i >= 0; i--)
+      printf ( " %2d: %16s  tH=%d  mH=%d  yH=%d  "
+               "nH=%d  cH=%d  iH=%d  nnS=%d,%d\n",
+               i, textToStr(scripts[i].file),
+               scripts[i].textHw, scripts[i].moduleHw,
+               scripts[i].tyconHw, scripts[i].nameHw, 
+               scripts[i].classHw, scripts[i].instHw,
+               scripts[i].nextNewText, scripts[i].nextNewDText 
+             );
+   printf ( "end   SCRIPTS\n" );
+   fflush(stderr); fflush(stdout);
+}
+
 Script startNewScript(f)                /* start new script, keeping record */
 String f; {                             /* of status for later restoration  */
     if (scriptHw >= NUM_SCRIPTS) {
@@ -998,9 +1618,7 @@ String f; {                             /* of status for later restoration  */
     }
 #ifdef DEBUG_SHOWUSE
     showUse("Text",   textHw,           NUM_TEXT);
-#if !IGNORE_MODULES
     showUse("Module", moduleHw-MODMIN,  NUM_MODULE);
-#endif
     showUse("Tycon",  tyconHw-TYCMIN,   NUM_TYCON);
     showUse("Name",   nameHw-NAMEMIN,   NUM_NAME);
     showUse("Class",  classHw-CLASSMIN, NUM_CLASSES);
@@ -1009,14 +1627,11 @@ String f; {                             /* of status for later restoration  */
     showUse("Ext",    extHw-EXTMIN,     NUM_EXT);
 #endif
 #endif
-
     scripts[scriptHw].file         = findText( f ? f : "<nofile>" );
     scripts[scriptHw].textHw       = textHw;
     scripts[scriptHw].nextNewText  = nextNewText;
     scripts[scriptHw].nextNewDText = nextNewDText;
-#if !IGNORE_MODULES
     scripts[scriptHw].moduleHw     = moduleHw;
-#endif
     scripts[scriptHw].tyconHw      = tyconHw;
     scripts[scriptHw].nameHw       = nameHw;
     scripts[scriptHw].classHw      = classHw;
@@ -1028,19 +1643,18 @@ String f; {                             /* of status for later restoration  */
 }
 
 Bool isPreludeScript() {                /* Test whether this is the Prelude*/
-    return (scriptHw==0);
+    return (scriptHw < N_PRELUDE_SCRIPTS /*==0*/ );
 }
 
-#if !IGNORE_MODULES
 Bool moduleThisScript(m)                /* Test if given module is defined */
 Module m; {                             /* in current script file          */
-    return scriptHw<1 || m>=scripts[scriptHw-1].moduleHw;
+    return scriptHw < 1
+           || m>=scripts[scriptHw-1].moduleHw;
 }
 
 Module lastModule() {              /* Return module in current script file */
     return (moduleHw>MODMIN ? moduleHw-1 : modulePrelude);
 }
-#endif /* !IGNORE_MODULES */
 
 #define scriptThis(nm,t,tag)            Script nm(x)                       \
                                         t x; {                             \
@@ -1061,7 +1675,6 @@ Script s; {
     return (s==0) ? modulePrelude : scripts[s-1].moduleHw;
 }
 
-#if !IGNORE_MODULES
 String fileOfModule(m)
 Module m; {
     Script s;
@@ -1075,7 +1688,6 @@ Module m; {
     }
     return 0;
 }
-#endif
 
 Script scriptThisFile(f)
 Text f; {
@@ -1098,9 +1710,7 @@ Script sno; {                           /* to reading script sno           */
         textHw       = scripts[sno].textHw;
         nextNewText  = scripts[sno].nextNewText;
         nextNewDText = scripts[sno].nextNewDText;
-#if !IGNORE_MODULES
         moduleHw     = scripts[sno].moduleHw;
-#endif
         tyconHw      = scripts[sno].tyconHw;
         nameHw       = scripts[sno].nameHw;
         classHw      = scripts[sno].classHw;
@@ -1112,7 +1722,7 @@ Script sno; {                           /* to reading script sno           */
         extHw        = scripts[sno].extHw;
 #endif
 
-#if 0  //zzzzzzzzzzzzzzzzz
+#if 0
         for (i=moduleHw; i >= scripts[sno].moduleHw; --i) {
             if (module(i).objectFile) {
                 printf("[bogus] closing objectFile for module %d\n",i);
@@ -1130,21 +1740,6 @@ Script sno; {                           /* to reading script sno           */
                 textHash[i][j] = NOTEXT;
         }
 
-#if IGNORE_MODULES
-        for (i=0; i<TYCONHSZ; ++i) {
-            Tycon tc = tyconHash[i];
-            while (nonNull(tc) && tc>=tyconHw)
-                tc = tycon(tc).nextTyconHash;
-            tyconHash[i] = tc;
-        }
-
-        for (i=0; i<NAMEHSZ; ++i) {
-            Name n = nameHash[i];
-            while (nonNull(n) && n>=nameHw)
-                n = name(n).nextNameHash;
-            nameHash[i] = n;
-        }
-#else /* !IGNORE_MODULES */
         currentModule=NIL;
         for (i=0; i<TYCONHSZ; ++i) {
             tyconHash[i] = NIL;
@@ -1152,7 +1747,6 @@ Script sno; {                           /* to reading script sno           */
         for (i=0; i<NAMEHSZ; ++i) {
             nameHash[i] = NIL;
         }
-#endif /* !IGNORE_MODULES */
 
         for (i=CLASSMIN; i<classHw; i++) {
             List ins = cclass(i).instances;
@@ -1194,14 +1788,6 @@ Heap    heapTopSnd;
 #endif
 Bool    consGC = TRUE;                  /* Set to FALSE to turn off gc from*/
                                         /* C stack; use with extreme care! */
-#if     PROFILING
-Heap    heapThd, heapTopThd;            /* to keep record of producers     */
-Int     sysCount;                       /* record unattached cells         */
-Name    producer;                       /* current producer, if any        */
-Bool    profiling = FALSE;              /* should profiling be performed   */
-Int     profInterval = MAXPOSINT;       /* interval between samples        */
-FILE    *profile = 0;                   /* pointer to profiler log, if any */
-#endif
 Long    numCells;
 Int     numGcs;                         /* number of garbage collections   */
 Int     cellsRecovered;                 /* number of cells recovered       */
@@ -1209,13 +1795,6 @@ Int     cellsRecovered;                 /* number of cells recovered       */
 static  Cell freeList;                  /* free list of unused cells       */
 static  Cell lsave, rsave;              /* save components of pair         */
 
-#if GC_WEAKPTRS
-static List weakPtrs;                   /* list of weak ptrs               */
-                                        /* reconstructed during every GC   */
-List   finalizers = NIL;
-List   liveWeakPtrs = NIL;
-#endif
-
 #if GC_STATISTICS
 
 static Int markCount, stackRoots;
@@ -1273,9 +1852,6 @@ Cell l, r; {                            /* heap, garbage collecting first  */
     freeList = snd(freeList);
     fst(c)   = l;
     snd(c)   = r;
-#if PROFILING
-    thd(c)   = producer;
-#endif
     numCells++;
     return c;
 }
@@ -1312,11 +1888,14 @@ Cell c; {                               /* cells reachable from given root */
         }
     }
 
+    /* STACK_CHECK: Avoid stack overflows during recursive marking. */
     if (isGenPair(fst(c))) {
+       STACK_CHECK
         fst(c) = markCell(fst(c));
         markSnd(c);
     }
     else if (isNull(fst(c)) || fst(c)>=BCSTAG) {
+       STACK_CHECK
         markSnd(c);
     }
 
@@ -1369,135 +1948,20 @@ Void garbageCollect()     {             /* Run garbage collector ...       */
     Int      recovered;
 
     jmp_buf  regs;                      /* save registers on stack         */
-printf("\n\n$$$$$$$$$$$ GARBAGE COLLECTION; aborting\n\n");
-exit(1);
     setjmp(regs);
 
     gcStarted();
     for (i=0; i<marksSize; ++i)         /* initialise mark set to empty    */
         marks[i] = 0;
-#if GC_WEAKPTRS
-    weakPtrs = NIL;                     /* clear list of weak pointers     */
-#endif
-    everybody(MARK);                    /* Mark all components of system   */
-
-#if IO_HANDLES
-    for (i=0; i<NUM_HANDLES; ++i)       /* release any unused handles      */
-        if (nonNull(handles[i].hcell)) {
-            register place = placeInSet(handles[i].hcell);
-            register mask  = maskInSet(handles[i].hcell);
-            if ((marks[place]&mask)==0)
-                freeHandle(i);
-        }
-#endif
-#if GC_MALLOCPTRS
-    for (i=0; i<NUM_MALLOCPTRS; ++i)    /* release any unused mallocptrs   */
-        if (isPair(mallocPtrs[i].mpcell)) {
-            register place = placeInSet(mallocPtrs[i].mpcell);
-            register mask  = maskInSet(mallocPtrs[i].mpcell);
-            if ((marks[place]&mask)==0)
-                incMallocPtrRefCnt(i,-1);
-        }
-#endif /* GC_MALLOCPTRS */
-#if GC_WEAKPTRS
-    /* After GC completes, we scan the list of weak pointers that are
-     * still live and zap their contents unless the contents are still
-     * live (by some other means).
-     * Note that this means the contents must itself be heap allocated.
-     * This means it can't be a nullary constructor or an Int or a Name
-     * or lots of other things - hope this doesn't bite too hard.
-     */
-    for (; nonNull(weakPtrs); weakPtrs=nextWeakPtr(weakPtrs)) {
-        Cell ptr = derefWeakPtr(weakPtrs);
-        if (isGenPair(ptr)) {
-            Int  place = placeInSet(ptr);
-            Int  mask  = maskInSet(ptr);
-            if ((marks[place]&mask)==0) {
-                /* printf("Zapping weak pointer %d\n", ptr); */
-                derefWeakPtr(weakPtrs) = NIL;
-            } else {
-                /* printf("Keeping weak pointer %d\n", ptr); */
-            }
-        } else if (nonNull(ptr)) {
-            printf("Weak ptr contains object which isn't heap allocated %d\n", ptr);
-        }
-    }
-
-    if (nonNull(liveWeakPtrs) || nonNull(finalizers)) {
-        Bool anyMarked;                 /* Weak pointers with finalizers   */
-        List wps;
-        List newFins = NIL;
-
-        /* Step 1: iterate until we've found out what is reachable         */
-        do {
-            anyMarked = FALSE;
-            for (wps=liveWeakPtrs; nonNull(wps); wps=tl(wps)) {
-                Cell wp = hd(wps);
-                Cell k  = fst(snd(wp));
-                if (isNull(k)) {
-                    internal("bad weak ptr");
-                }
-                if (isMarked(k)) {
-                    Cell vf = snd(snd(wp));
-                    if (!isMarked(fst(vf)) || !isMarked(snd(vf))) {
-                        mark(fst(vf));
-                        mark(snd(vf));
-                        anyMarked = TRUE;
-                    }
-                }
-            }
-        } while (anyMarked);
-
-        /* Step 2: Now we know which weak pointers will die, so we can     */
-        /* remove them from the live set and gather their finalizers.  But */
-        /* note that we mustn't mark *anything* at this stage or we will   */
-        /* corrupt our view of what's alive, and what's dead.              */
-        wps = NIL;
-        while (nonNull(liveWeakPtrs)) {
-            Cell wp = hd(liveWeakPtrs);
-            List nx = tl(liveWeakPtrs);
-            Cell k  = fst(snd(wp));
-            if (!isMarked(k)) {                 /* If the key is dead, then*/
-                Cell vf      = snd(snd(wp));    /* stomp on weak pointer   */
-                fst(vf)      = snd(vf);
-                snd(vf)      = newFins;
-                newFins      = vf;              /* reuse because we can't  */
-                fst(snd(wp)) = NIL;             /* reallocate here ...     */
-                snd(snd(wp)) = NIL;
-                snd(wp)      = NIL;
-                liveWeakPtrs = nx;
-            } else {
-                tl(liveWeakPtrs) = wps;         /* Otherwise, weak pointer */
-                wps              = liveWeakPtrs;/* survives to face another*/
-                liveWeakPtrs     = nx;          /* garbage collection      */
-            }
-        }
 
-        /* Step 3: Now we've identified the live cells and the newly       */
-        /* scheduled finalizers, but we had better make sure that they are */
-        /* all marked now, including any internal structure, to ensure that*/
-        /* they make it to the other side of gc.                           */
-        for (liveWeakPtrs=wps; nonNull(wps); wps=tl(wps)) {
-            mark(snd(hd(wps)));
-        }
-        mark(liveWeakPtrs);
-        mark(newFins);
-        finalizers = revOnto(newFins,finalizers);
-    }
+    everybody(MARK);                    /* Mark all components of system   */
 
-#endif /* GC_WEAKPTRS */
     gcScanning();                       /* scan mark set                   */
     mask      = 1;
     place     = 0;
     recovered = 0;
     j         = 0;
-#if PROFILING
-    if (profile) {
-        sysCount = 0;
-        for (i=NAMEMIN; i<nameHw; i++)
-            name(i).count = 0;
-    }
-#endif
+
     freeList = NIL;
     for (i=1; i<=heapSize; i++) {
         if ((marks[place] & mask) == 0) {
@@ -1506,12 +1970,6 @@ exit(1);
             freeList = -i;
             recovered++;
         }
-#if PROFILING
-        else if (nonNull(thd(-i)))
-            name(thd(-i)).count++;
-        else
-            sysCount++;
-#endif
         mask <<= 1;
         if (++j == bitsPerWord) {
             place++;
@@ -1523,48 +1981,7 @@ exit(1);
     gcRecovered(recovered);
     breakOn(breakStat);                 /* restore break trapping if nec.  */
 
-#if PROFILING
-    if (profile) {
-        fprintf(profile,"BEGIN_SAMPLE %ld.00\n",numReductions);
-/* For the time being, we won't include the system count in the output:
-        if (sysCount>0)
-            fprintf(profile,"  SYSTEM %d\n",sysCount);
-*/
-        /* Accumulate costs in top level objects */
-        for (i=NAMEMIN; i<nameHw; i++) {
-            Name cc = i;
-            /* Use of "while" instead of "if" is pure paranoia - ADR */
-            while (isName(name(cc).parent)) 
-                cc = name(cc).parent;
-            if (i != cc) {
-                name(cc).count += name(i).count;
-                name(i).count = 0;
-            }
-        }
-        for (i=NAMEMIN; i<nameHw; i++)
-            if (name(i).count>0) 
-                if (isPair(name(i).parent)) {
-                    Pair p = name(i).parent;
-                    Cell f = fst(p);
-                    fprintf(profile,"  ");
-                    if (isClass(f))
-                        fprintf(profile,"%s",textToStr(cclass(f).text));
-                    else {
-                        fprintf(profile,"%s_",textToStr(cclass(inst(f).c).text));
-                        /* Will hp2ps accept the spaces produced by this? */
-                        printPred(profile,inst(f).head);
-                    }
-                    fprintf(profile,"_%s %d\n",
-                            textToStr(name(snd(p)).text),
-                            name(i).count);
-                } else {
-                    fprintf(profile,"  %s %d\n",
-                            textToStr(name(i).text),
-                            name(i).count);
-                }
-        fprintf(profile,"END_SAMPLE %ld.00\n",numReductions);
-    }
-#endif
+    everybody(GCDONE);
 
     /* can only return if freeList is nonempty on return. */
     if (recovered<minRecovery || isNull(freeList)) {
@@ -1574,22 +1991,6 @@ exit(1);
     cellsRecovered = recovered;
 }
 
-#if PROFILING
-Void profilerLog(s)                     /* turn heap profiling on, saving log*/
-String s; {                             /* in specified file                 */
-    if ((profile=fopen(s,"w")) != NULL) {
-        fprintf(profile,"JOB \"Hugs Heap Profile\"\n");
-        fprintf(profile,"DATE \"%s\"\n",timeString());
-        fprintf(profile,"SAMPLE_UNIT \"reductions\"\n");
-        fprintf(profile,"VALUE_UNIT \"cells\"\n");
-    }
-    else {
-        ERRMSG(0) "Cannot open profile log file \"%s\"", s
-        EEND;
-    }
-}
-#endif
-
 /* --------------------------------------------------------------------------
  * Code for saving last expression entered:
  *
@@ -1674,14 +2075,17 @@ register Cell c; {
         register Cell fstc = fst(c);
         return isTag(fstc) ? fstc : AP;
     }
-    if (c<TUPMIN)    return c;
+    if (c<OFFMIN)    return c;
+#if TREX
+    if (isExt(c))    return EXT;
+#endif
     if (c>=INTMIN)   return INTCELL;
 
     if (c>=NAMEMIN){if (c>=CLASSMIN)   {if (c>=CHARMIN) return CHARCELL;
                                         else            return CLASS;}
                     else                if (c>=INSTMIN) return INSTANCE;
                                         else            return NAME;}
-    else            if (c>=MODMIN)     {if (c>=TYCMIN)  return TYCON;
+    else            if (c>=MODMIN)     {if (c>=TYCMIN)  return isTuple(c) ? TUPLE : TYCON;
                                         else            return MODULE;}
                     else                if (c>=OFFMIN)  return OFFSET;
 #if TREX
@@ -1779,12 +2183,16 @@ Int  depth; {
                 Printf("Offset %d", offsetOf(c));
                 break;
         case TUPLE:
-                Printf("Tuple %d", tupleOf(c));
+                Printf("%s", textToStr(ghcTupleText(c)));
                 break;
         case POLYTYPE:
                 Printf("Polytype");
                 print(snd(c),depth-1);
                 break;
+        case QUAL:
+                Printf("Qualtype");
+                print(snd(c),depth-1);
+                break;
         case RANK2:
                 Printf("Rank2(");
                 if (isPair(snd(c)) && isInt(fst(snd(c)))) {
@@ -1816,6 +2224,14 @@ Int  depth; {
         case CONOPCELL:
                 Printf("{id %s}",textToStr(textOf(c)));
                 break;
+#if IPARAM
+         case IPCELL :
+             Printf("{ip %s}",textToStr(textOf(c)));
+             break;
+         case IPVAR :
+             Printf("?%s",textToStr(textOf(c)));
+             break;
+#endif
         case QUALIDENT:
                 Printf("{qid %s.%s}",textToStr(qmodOf(c)),textToStr(qtextOf(c)));
                 break;
@@ -1889,6 +2305,37 @@ Int  depth; {
                 print(snd(snd(c)),depth-1);
                 Putchar(')');
                 break;
+        case DICTAP:
+                Printf("(DICTAP,");
+                print(snd(c),depth-1);
+                Putchar(')');
+                break;
+        case UNBOXEDTUP:
+                Printf("(UNBOXEDTUP,");
+                print(snd(c),depth-1);
+                Putchar(')');
+                break;
+        case ZTUP2:
+                Printf("<ZPair ");
+                print(zfst(c),depth-1);
+                Putchar(' ');
+                print(zsnd(c),depth-1);
+                Putchar('>');
+                break;
+        case ZTUP3:
+                Printf("<ZTriple ");
+                print(zfst3(c),depth-1);
+                Putchar(' ');
+                print(zsnd3(c),depth-1);
+                Putchar(' ');
+                print(zthd3(c),depth-1);
+                Putchar('>');
+                break;
+        case BANG:
+                Printf("(BANG,");
+                print(snd(c),depth-1);
+                Putchar(')');
+                break;
         default:
                 if (isBoxTag(tag)) {
                     Printf("Tag(%d)=%d", c, tag);
@@ -1951,6 +2398,16 @@ Cell c; {
     return isPair(c) && (fst(c)==QUALIDENT);
 }
 
+Bool eqQualIdent ( QualId c1, QualId c2 )
+{
+   assert(isQualIdent(c1));
+   if (!isQualIdent(c2)) {
+   assert(isQualIdent(c2));
+   }
+   return qmodOf(c1)==qmodOf(c2) &&
+          qtextOf(c1)==qtextOf(c2);
+}
+
 Bool isIdent(c)                        /* is cell an identifier?           */
 Cell c; {
     if (!isPair(c)) return FALSE;
@@ -1984,14 +2441,7 @@ Int n; {
            : pair(INTCELL,n);
 }
 
-#if BIGNUMS
-Bool isBignum(c)                       /* cell holds bignum value?         */
-Cell c; {
-    return c==ZERONUM || (isPair(c) && (fst(c)==POSNUM || fst(c)==NEGNUM));
-}
-#endif
-
-#if SIZEOF_INTP == SIZEOF_INT
+#if SIZEOF_VOID_P == SIZEOF_INT
 typedef union {Int i; Ptr p;} IntOrPtr;
 Cell mkPtr(p)
 Ptr p;
@@ -2009,7 +2459,23 @@ Cell c;
     x.i = snd(c);
     return x.p;
 }
-#elif SIZEOF_INTP == 2*SIZEOF_INT
+Cell mkCPtr(p)
+Ptr p;
+{
+    IntOrPtr x;
+    x.p = p;
+    return pair(CPTRCELL,x.i);
+}
+
+Ptr cptrOf(c)
+Cell c;
+{
+    IntOrPtr x;
+    assert(fst(c) == CPTRCELL);
+    x.i = snd(c);
+    return x.p;
+}
+#elif SIZEOF_VOID_P == 2*SIZEOF_INT
 typedef union {struct {Int i1; Int i2;} i; Ptr p;} IntOrPtr;
 Cell mkPtr(p)
 Ptr p;
@@ -2118,26 +2584,14 @@ List xs, ys; {                         /* list xs onto list ys...          */
     return ys;
 }
 
-#if 0
-List delete(xs,y)                      /* Delete first use of y from xs    */
-List xs;
-Cell y; {
-    if (isNull(xs)) {
-        return xs;
-    } else if (hs(xs) == y) {
-        return tl(xs);
-    } else {
-        tl(xs) = delete(tl(xs),y);
-        return xs;
-    }
-}
-
-List minus(xs,ys)                      /* Delete members of ys from xs     */
-List xs, ys; {
-    mapAccum(delete,xs,ys);
-    return xs;
-}
-#endif
+QualId qualidIsMember ( QualId q, List xs )
+{
+   for (; nonNull(xs); xs=tl(xs)) {
+      if (eqQualIdent(q, hd(xs)))
+         return hd(xs);
+   }
+   return NIL;
+}  
 
 Cell varIsMember(t,xs)                 /* Test if variable is a member of  */
 Text t;                                /* given list of variables          */
@@ -2244,7 +2698,7 @@ List xs; {
     return ys;
 }
 
-List splitAt(n,xs)                         /* drop n things from front of list*/
+List splitAt(n,xs)                      /* drop n things from front of list*/
 Int  n;       
 List xs; {
     for(; n>0; --n) {
@@ -2253,7 +2707,7 @@ List xs; {
     return xs;
 }
 
-Cell nth(n,xs)                         /* extract n'th element of list    */
+Cell nth(n,xs)                          /* extract n'th element of list    */
 Int  n;
 List xs; {
     for(; n>0 && nonNull(xs); --n, xs=tl(xs)) {
@@ -2282,6 +2736,143 @@ List xs; {
     return xs;                          /* here if element not found       */
 }
 
+List nubList(xs)                        /* nuke dups in list               */
+List xs; {                              /* non destructive                 */
+   List outs = NIL;
+   for (; nonNull(xs); xs=tl(xs))
+      if (isNull(cellIsMember(hd(xs),outs)))
+         outs = cons(hd(xs),outs);
+   outs = rev(outs);
+   return outs;
+}
+
+
+/* --------------------------------------------------------------------------
+ * Strongly-typed lists (z-lists) and tuples (experimental)
+ * ------------------------------------------------------------------------*/
+
+static void z_tag_check ( Cell x, int tag, char* caller )
+{
+   char buf[100];
+   if (isNull(x)) {
+      sprintf(buf,"z_tag_check(%s): null\n", caller);
+      internal(buf);
+   }
+   if (whatIs(x) != tag) {
+      sprintf(buf, 
+          "z_tag_check(%s): tag was %d, expected %d\n",
+          caller, whatIs(x), tag );
+      internal(buf);
+   }  
+}
+
+#if 0
+Cell zcons ( Cell x, Cell xs )
+{
+   if (!(isNull(xs) || whatIs(xs)==ZCONS)) 
+      internal("zcons: ill typed tail");
+   return ap(ZCONS,ap(x,xs));
+}
+
+Cell zhd ( Cell xs )
+{
+   if (isNull(xs)) internal("zhd: empty list");
+   z_tag_check(xs,ZCONS,"zhd");
+   return fst( snd(xs) );
+}
+
+Cell ztl ( Cell xs )
+{
+   if (isNull(xs)) internal("ztl: empty list");
+   z_tag_check(xs,ZCONS,"zhd");
+   return snd( snd(xs) );
+}
+
+Int zlength ( ZList xs )
+{
+   Int n = 0;
+   while (nonNull(xs)) {
+      z_tag_check(xs,ZCONS,"zlength");
+      n++;
+      xs = snd( snd(xs) );
+   }
+   return n;
+}
+
+ZList zreverse ( ZList xs )
+{
+   ZList rev = NIL;
+   while (nonNull(xs)) {
+      z_tag_check(xs,ZCONS,"zreverse");
+      rev = zcons(zhd(xs),rev);
+      xs = ztl(xs);
+   }
+   return rev;
+}
+
+Cell zsingleton ( Cell x )
+{
+   return zcons (x,NIL);
+}
+
+Cell zdoubleton ( Cell x, Cell y )
+{
+   return zcons(x,zcons(y,NIL));
+}
+#endif
+
+Cell zpair ( Cell x1, Cell x2 )
+{ return ap(ZTUP2,ap(x1,x2)); }
+Cell zfst ( Cell zpair )
+{ z_tag_check(zpair,ZTUP2,"zfst"); return fst( snd(zpair) ); }
+Cell zsnd ( Cell zpair )
+{ z_tag_check(zpair,ZTUP2,"zsnd"); return snd( snd(zpair) ); }
+
+Cell ztriple ( Cell x1, Cell x2, Cell x3 )
+{ return ap(ZTUP3,ap(x1,ap(x2,x3))); }
+Cell zfst3 ( Cell zpair )
+{ z_tag_check(zpair,ZTUP3,"zfst3"); return fst( snd(zpair) ); }
+Cell zsnd3 ( Cell zpair )
+{ z_tag_check(zpair,ZTUP3,"zsnd3"); return fst(snd( snd(zpair) )); }
+Cell zthd3 ( Cell zpair )
+{ z_tag_check(zpair,ZTUP3,"zthd3"); return snd(snd( snd(zpair) )); }
+
+Cell z4ble ( Cell x1, Cell x2, Cell x3, Cell x4 )
+{ return ap(ZTUP4,ap(x1,ap(x2,ap(x3,x4)))); }
+Cell zsel14 ( Cell zpair )
+{ z_tag_check(zpair,ZTUP4,"zsel14"); return fst( snd(zpair) ); }
+Cell zsel24 ( Cell zpair )
+{ z_tag_check(zpair,ZTUP4,"zsel24"); return fst(snd( snd(zpair) )); }
+Cell zsel34 ( Cell zpair )
+{ z_tag_check(zpair,ZTUP4,"zsel34"); return fst(snd(snd( snd(zpair) ))); }
+Cell zsel44 ( Cell zpair )
+{ z_tag_check(zpair,ZTUP4,"zsel44"); return snd(snd(snd( snd(zpair) ))); }
+
+Cell z5ble ( Cell x1, Cell x2, Cell x3, Cell x4, Cell x5 )
+{ return ap(ZTUP5,ap(x1,ap(x2,ap(x3,ap(x4,x5))))); }
+Cell zsel15 ( Cell zpair )
+{ z_tag_check(zpair,ZTUP5,"zsel15"); return fst( snd(zpair) ); }
+Cell zsel25 ( Cell zpair )
+{ z_tag_check(zpair,ZTUP5,"zsel25"); return fst(snd( snd(zpair) )); }
+Cell zsel35 ( Cell zpair )
+{ z_tag_check(zpair,ZTUP5,"zsel35"); return fst(snd(snd( snd(zpair) ))); }
+Cell zsel45 ( Cell zpair )
+{ z_tag_check(zpair,ZTUP5,"zsel45"); return fst(snd(snd(snd( snd(zpair) )))); }
+Cell zsel55 ( Cell zpair )
+{ z_tag_check(zpair,ZTUP5,"zsel55"); return snd(snd(snd(snd( snd(zpair) )))); }
+
+
+Cell unap ( int tag, Cell c )
+{
+   char buf[100];
+   if (whatIs(c) != tag) {
+      sprintf(buf, "unap: specified %d, actual %d\n",
+                   tag, whatIs(c) );
+      internal(buf);
+   }
+   return snd(c);
+}
+
 /* --------------------------------------------------------------------------
  * Operations on applications:
  * ------------------------------------------------------------------------*/
@@ -2334,171 +2925,141 @@ List args; {
 }
 
 /* --------------------------------------------------------------------------
- * Handle operations:
+ * debugging support
  * ------------------------------------------------------------------------*/
 
-#if IO_HANDLES
-struct strHandle DEFTABLE(handles,NUM_HANDLES);
-
-Cell openHandle(s,hmode,binary)         /* open handle to file named s in  */
-String s;                               /* the specified hmode             */
-Int    hmode; 
-Bool   binary; {
-    Int i;
-
-    for (i=0; i<NUM_HANDLES && nonNull(handles[i].hcell); ++i)
-        ;                                       /* Search for unused handle*/
-    if (i>=NUM_HANDLES) {                       /* If at first we don't    */
-        garbageCollect();                       /* succeed, garbage collect*/
-        for (i=0; i<NUM_HANDLES && nonNull(handles[i].hcell); ++i)
-            ;                                   /* and try again ...       */
-    }
-    if (i>=NUM_HANDLES) {                       /* ... before we give up   */
-        ERRMSG(0) "Too many handles open; cannot open \"%s\"", s
-        EEND;
-    }
-    else {                                      /* prepare to open file    */
-        String stmode;
-        if (binary) {
-            stmode = (hmode&HAPPEND) ? "ab+" :
-                     (hmode&HWRITE)  ? "wb+" :
-                     (hmode&HREAD)   ? "rb" : (String)0;
-        } else {
-            stmode = (hmode&HAPPEND) ? "a+"  :
-                     (hmode&HWRITE)  ? "w+"  :
-                     (hmode&HREAD)   ? "r"  : (String)0;
-        }
-        if (stmode && (handles[i].hfp=fopen(s,stmode))) {
-            handles[i].hmode = hmode;
-            return (handles[i].hcell = ap(HANDCELL,i));
-        }
-    }
-    return NIL;
+static String maybeModuleStr ( Module m )
+{
+   if (isModule(m)) return textToStr(module(m).text); else return "??";
 }
 
-static Void local freeHandle(n)         /* release handle storage when no  */
-Int n; {                                /* heap references to it remain    */
-    if (0<=n && n<NUM_HANDLES && nonNull(handles[n].hcell)) {
-        if (n>HSTDERR && handles[n].hmode!=HCLOSED && handles[n].hfp) {
-            fclose(handles[n].hfp);
-            handles[n].hfp = 0;
-        }
-        fst(handles[n].hcell) = snd(handles[n].hcell) = NIL;
-        handles[n].hcell      = NIL;
-    }
-}
-#endif
-
-#if GC_MALLOCPTRS
-/* --------------------------------------------------------------------------
- * Malloc Ptrs:
- * ------------------------------------------------------------------------*/
-
-struct strMallocPtr mallocPtrs[NUM_MALLOCPTRS];
-
-/* It might GC (because it uses a table not a list) which will trash any
- * unstable pointers.  
- * (It happens that we never use it with unstable pointers.)
- */
-Cell mkMallocPtr(ptr,cleanup)            /* create a new malloc pointer    */
-Ptr ptr;
-Void (*cleanup) Args((Ptr)); {
-    Int i;
-    for (i=0; i<NUM_MALLOCPTRS && mallocPtrs[i].refCount!=0; ++i)
-        ;                                       /* Search for unused entry */
-    if (i>=NUM_MALLOCPTRS) {                    /* If at first we don't    */
-        garbageCollect();                       /* succeed, garbage collect*/
-        for (i=0; i<NUM_MALLOCPTRS && mallocPtrs[i].refCount!=0; ++i)
-            ;                                   /* and try again ...       */
-    }
-    if (i>=NUM_MALLOCPTRS) {                    /* ... before we give up   */
-        ERRMSG(0) "Too many ForeignObjs open"
-        EEND;
-    }
-    mallocPtrs[i].ptr      = ptr;
-    mallocPtrs[i].cleanup  = cleanup;
-    mallocPtrs[i].refCount = 1;
-    return (mallocPtrs[i].mpcell = ap(MPCELL,i));
+static String maybeNameStr ( Name n )
+{
+   if (isName(n)) return textToStr(name(n).text); else return "??";
 }
 
-Void incMallocPtrRefCnt(n,i)             /* change ref count of MallocPtr */
-Int n;
-Int i; {        
-    if (!(0<=n && n<NUM_MALLOCPTRS && mallocPtrs[n].refCount > 0))
-        internal("freeMallocPtr");
-    mallocPtrs[n].refCount += i;
-    if (mallocPtrs[n].refCount <= 0) {
-        mallocPtrs[n].cleanup(mallocPtrs[n].ptr);
-
-        mallocPtrs[n].ptr      = 0;
-        mallocPtrs[n].cleanup  = 0;
-        mallocPtrs[n].refCount = 0;
-        mallocPtrs[n].mpcell   = NIL;
-    }
+static String maybeTyconStr ( Tycon t )
+{
+   if (isTycon(t)) return textToStr(tycon(t).text); else return "??";
 }
-#endif /* GC_MALLOCPTRS */
-
-/* --------------------------------------------------------------------------
- * Stable pointers
- * This is a mechanism that allows the C world to manipulate pointers into the
- * Haskell heap without having to worry that the garbage collector is going
- * to delete it or move it around.
- * The implementation and interface is based on my implementation in
- * GHC - but, at least for now, is simplified by using a fixed size
- * table of stable pointers.
- * ------------------------------------------------------------------------*/
-
-#if GC_STABLEPTRS
-
-/* Each entry in the stable pointer table is either a heap pointer
- * or is not currently allocated.
- * Unallocated entries are threaded together into a freelist.
- * The last entry in the list contains the Cell 0; all other values
- * contain a Cell whose value is the next free stable ptr in the list.
- * It follows that stable pointers are strictly positive (>0).
- */
-static Cell stablePtrTable[NUM_STABLEPTRS];
-static Int  sptFreeList;
-#define SPT(sp) stablePtrTable[(sp)-1]
 
-static Void local resetStablePtrs() {
-    Int i;
-    /* It would be easier to build the free list in the other direction
-     * but, when debugging, it's way easier to understand if the first
-     * pointer allocated is "1".
-     */
-    for(i=1; i < NUM_STABLEPTRS; ++i)
-        SPT(i) = i+1;
-    SPT(NUM_STABLEPTRS) = 0;
-    sptFreeList = 1;
+static String maybeClassStr ( Class c )
+{
+   if (isClass(c)) return textToStr(cclass(c).text); else return "??";
 }
 
-Int mkStablePtr(c)                  /* Create a stable pointer            */
-Cell c; {
-    Int i = sptFreeList;
-    if (i == 0)
-        return 0;
-    sptFreeList = SPT(i);
-    SPT(i) = c;
-    return i;
+static String maybeText ( Text t )
+{
+   if (isNull(t)) return "(nil)";
+   return textToStr(t);
 }
 
-Cell derefStablePtr(p)              /* Dereference a stable pointer       */
-Int p; {
-    if (!(1 <= p && p <= NUM_STABLEPTRS)) {
-        internal("derefStablePtr");
-    }
-    return SPT(p);
+static void print100 ( Int x )
+{
+   print ( x, 100); printf("\n");
 }
 
-Void freeStablePtr(i)               /* Free a stable pointer             */
-Int i; {
-    SPT(i) = sptFreeList;
-    sptFreeList = i;
+void dumpTycon ( Int t )
+{
+   if (isTycon(TYCMIN+t) && !isTycon(t)) t += TYCMIN;
+   if (!isTycon(t)) {
+      printf ( "dumpTycon %d: not a tycon\n", t);
+      return;
+   }
+   printf ( "{\n" );
+   printf ( "    text: %s\n",     textToStr(tycon(t).text) );
+   printf ( "    line: %d\n",     tycon(t).line );
+   printf ( "     mod: %s\n",     maybeModuleStr(tycon(t).mod));
+   printf ( "   tuple: %d\n",     tycon(t).tuple);
+   printf ( "   arity: %d\n",     tycon(t).arity);
+   printf ( "    kind: ");        print100(tycon(t).kind);
+   printf ( "    what: %d\n",     tycon(t).what);
+   printf ( "    defn: ");        print100(tycon(t).defn);
+   printf ( "    cToT: %d %s\n",  tycon(t).conToTag, 
+                                  maybeNameStr(tycon(t).conToTag));
+   printf ( "    tToC: %d %s\n",  tycon(t).tagToCon, 
+                                  maybeNameStr(tycon(t).tagToCon));
+   printf ( "    itbl: %p\n",     tycon(t).itbl);
+   printf ( "  nextTH: %d %s\n",  tycon(t).nextTyconHash,
+                                  maybeTyconStr(tycon(t).nextTyconHash));
+   printf ( "}\n" );
+}
+
+void dumpName ( Int n )
+{
+   if (isName(NAMEMIN+n) && !isName(n)) n += NAMEMIN;
+   if (!isName(n)) {
+      printf ( "dumpName %d: not a name\n", n);
+      return;
+   }
+   printf ( "{\n" );
+   printf ( "    text: %s\n",     textToStr(name(n).text) );
+   printf ( "    line: %d\n",     name(n).line );
+   printf ( "     mod: %s\n",     maybeModuleStr(name(n).mod));
+   printf ( "  syntax: %d\n",     name(n).syntax );
+   printf ( "  parent: %d\n",     name(n).parent );
+   printf ( "   arity: %d\n",     name(n).arity );
+   printf ( "  number: %d\n",     name(n).number );
+   printf ( "    type: ");        print100(name(n).type);
+   printf ( "    defn: %d\n",     name(n).defn );
+   printf ( "  stgVar: ");        print100(name(n).stgVar);
+   printf ( "   cconv: %d\n",     name(n).callconv );
+   printf ( "  primop: %p\n",     name(n).primop );
+   printf ( "    itbl: %p\n",     name(n).itbl );
+   printf ( "  nextNH: %d\n",     name(n).nextNameHash );
+   printf ( "}\n" );
+}
+
+
+void dumpClass ( Int c )
+{
+   if (isClass(CLASSMIN+c) && !isClass(c)) c += CLASSMIN;
+   if (!isClass(c)) {
+      printf ( "dumpClass %d: not a class\n", c);
+      return;
+   }
+   printf ( "{\n" );
+   printf ( "    text: %s\n",     textToStr(cclass(c).text) );
+   printf ( "    line: %d\n",     cclass(c).line );
+   printf ( "     mod: %s\n",     maybeModuleStr(cclass(c).mod));
+   printf ( "   arity: %d\n",     cclass(c).arity );
+   printf ( "   level: %d\n",     cclass(c).level );
+   printf ( "   kinds: ");        print100( cclass(c).kinds );
+   printf ( "     fds: %d\n",     cclass(c).fds );
+   printf ( "    xfds: %d\n",     cclass(c).xfds );
+   printf ( "    head: ");        print100( cclass(c).head );
+   printf ( "    dcon: ");        print100( cclass(c).dcon );
+   printf ( "  supers: ");        print100( cclass(c).supers );
+   printf ( " #supers: %d\n",     cclass(c).numSupers );
+   printf ( "   dsels: ");        print100( cclass(c).dsels );
+   printf ( " members: ");        print100( cclass(c).members );
+   printf ( "#members: %d\n",     cclass(c).numMembers );
+   printf ( "defaults: ");        print100( cclass(c).defaults );
+   printf ( "   insts: ");        print100( cclass(c).instances );
+   printf ( "}\n" );
+}
+
+
+void dumpInst ( Int i )
+{
+   if (isInst(INSTMIN+i) && !isInst(i)) i += INSTMIN;
+   if (!isInst(i)) {
+      printf ( "dumpInst %d: not an instance\n", i);
+      return;
+   }
+   printf ( "{\n" );
+   printf ( "   class: %s\n",     maybeClassStr(inst(i).c) );
+   printf ( "    line: %d\n",     inst(i).line );
+   printf ( "     mod: %s\n",     maybeModuleStr(inst(i).mod));
+   printf ( "   kinds: ");        print100( inst(i).kinds );
+   printf ( "    head: ");        print100( inst(i).head );
+   printf ( "   specs: ");        print100( inst(i).specifics );
+   printf ( "  #specs: %d\n",     inst(i).numSpecifics );
+   printf ( "   impls: ");        print100( inst(i).implements );
+   printf ( " builder: %s\n",     maybeNameStr( inst(i).builder ) );
+   printf ( "}\n" );
 }
 
-#undef SPT
-#endif /* GC_STABLEPTRS */
 
 /* --------------------------------------------------------------------------
  * plugin support
@@ -2606,6 +3167,8 @@ Int what; {
     Int i;
 
     switch (what) {
+        case POSTPREL: break;
+
         case RESET   : clearStack();
 
                        /* the next 2 statements are particularly important
@@ -2615,31 +3178,6 @@ Int what; {
                         */
                        heapTopFst = heapFst + heapSize;
                        heapTopSnd = heapSnd + heapSize;
-#if PROFILING
-                       heapTopThd = heapThd + heapSize;
-                       if (profile) {
-                           garbageCollect();
-                           fclose(profile);
-#if HAVE_HP2PS
-                           system("hp2ps profile.hp");
-#endif
-                           profile = 0;
-                       }
-#endif
-#if IO_HANDLES
-                       handles[HSTDIN].hmode  = HREAD;
-                       handles[HSTDOUT].hmode = HAPPEND;
-                       handles[HSTDERR].hmode = HAPPEND;
-#endif
-#if GC_MALLOCPTRS
-                       for (i=0; i<NUM_MALLOCPTRS; i++)
-                           mallocPtrs[i].mpcell = NIL;
-#endif
-#if !HSCRIPT
-#if GC_STABLEPTRS
-                       resetStablePtrs();
-#endif
-#endif
                        consGC = TRUE;
                        lsave  = NIL;
                        rsave  = NIL;
@@ -2654,10 +3192,9 @@ Int what; {
                            mark(name(i).defn);
                            mark(name(i).stgVar);
                            mark(name(i).type);
-                       }
+                        }
                        end("Names", nameHw-NAMEMIN);
 
-#if !IGNORE_MODULES
                        start();
                        for (i=MODMIN; i<moduleHw; ++i) {
                            mark(module(i).tycons);
@@ -2665,9 +3202,9 @@ Int what; {
                            mark(module(i).classes);
                            mark(module(i).exports);
                            mark(module(i).qualImports);
+                           mark(module(i).objectExtraNames);
                        }
                        end("Modules", moduleHw-MODMIN);
-#endif
 
                        start();
                        for (i=TYCMIN; i<tyconHw; ++i) {
@@ -2681,6 +3218,8 @@ Int what; {
                        for (i=CLASSMIN; i<classHw; ++i) {
                            mark(cclass(i).head);
                            mark(cclass(i).kinds);
+                          mark(cclass(i).fds);
+                          mark(cclass(i).xfds);
                            mark(cclass(i).dsels);
                            mark(cclass(i).supers);
                            mark(cclass(i).members);
@@ -2709,24 +3248,6 @@ Int what; {
                        mark(lsave);
                        mark(rsave);
                        end("Last expression", 3);
-#if IO_HANDLES
-                       start();
-                       mark(handles[HSTDIN].hcell);
-                       mark(handles[HSTDOUT].hcell);
-                       mark(handles[HSTDERR].hcell);
-                       end("Standard handles", 3);
-#endif
-
-#if GC_STABLEPTRS
-                       start();
-                       for (i=0; i<NUM_STABLEPTRS; ++i)
-                           mark(stablePtrTable[i]);
-                       end("Stable pointers", NUM_STABLEPTRS);
-#endif
-
-#if GC_WEAKPTRS
-                       mark(finalizers);
-#endif
 
                        if (consGC) {
                            start();
@@ -2736,7 +3257,7 @@ Int what; {
 
                        break;
 
-        case INSTALL : heapFst = heapAlloc(heapSize);
+        case PREPREL : heapFst = heapAlloc(heapSize);
                        heapSnd = heapAlloc(heapSize);
 
                        if (heapFst==(Heap)0 || heapSnd==(Heap)0) {
@@ -2747,17 +3268,6 @@ Int what; {
 
                        heapTopFst = heapFst + heapSize;
                        heapTopSnd = heapSnd + heapSize;
-#if PROFILING
-                       heapThd = heapAlloc(heapSize);
-                       if (heapThd==(Heap)0) {
-                           ERRMSG(0) "Cannot allocate profiler storage space"
-                           EEND;
-                       }
-                       heapTopThd   = heapThd + heapSize;
-                       profile      = 0;
-                       if (0 == profInterval)
-                           profInterval = heapSize / DEF_PROFINTDIV;
-#endif
                        for (i=1; i<heapSize; ++i) {
                            fst(-i) = FREECELL;
                            snd(-i) = -(i+1);
@@ -2788,18 +3298,6 @@ Int what; {
 #endif
                        clearStack();
 
-#if IO_HANDLES
-                       TABALLOC(handles,   struct strHandle, NUM_HANDLES)
-                       for (i=0; i<NUM_HANDLES; i++)
-                           handles[i].hcell = NIL;
-                       handles[HSTDIN].hcell  = ap(HANDCELL,HSTDIN);
-                       handles[HSTDIN].hfp    = stdin;
-                       handles[HSTDOUT].hcell = ap(HANDCELL,HSTDOUT);
-                       handles[HSTDOUT].hfp   = stdout;
-                       handles[HSTDERR].hcell = ap(HANDCELL,HSTDERR);
-                       handles[HSTDERR].hfp   = stderr;
-#endif
-
                        textHw        = 0;
                        nextNewText   = NUM_TEXT;
                        nextNewDText  = (-1);
@@ -2809,23 +3307,11 @@ Int what; {
                            textHash[i][0] = NOTEXT;
 
 
-#if !IGNORE_MODULES
                        moduleHw = MODMIN;
-#endif
 
                        tyconHw  = TYCMIN;
                        for (i=0; i<TYCONHSZ; ++i)
                            tyconHash[i] = NIL;
-
-#if GC_WEAKPTRS
-                       finalizers   = NIL;
-                       liveWeakPtrs = NIL;
-#endif
-
-#if GC_STABLEPTRS
-                       resetStablePtrs();
-#endif
-
 #if TREX
                        extHw    = EXTMIN;
 #endif