[project @ 2003-07-01 10:21:21 by simonmar]
authorsimonmar <unknown>
Tue, 1 Jul 2003 10:21:21 +0000 (10:21 +0000)
committersimonmar <unknown>
Tue, 1 Jul 2003 10:21:21 +0000 (10:21 +0000)
Add ancient HEP document, which might be revived.

docs/hep/hep.tex [new file with mode: 0644]

diff --git a/docs/hep/hep.tex b/docs/hep/hep.tex
new file mode 100644 (file)
index 0000000..772aee5
--- /dev/null
@@ -0,0 +1,1299 @@
+\documentstyle[11pt]{article}
+
+% copied from the Haskore tutorial
+\textheight=8.5in
+\textwidth=6.5in
+\topmargin=-.3in
+\oddsidemargin=0in
+\evensidemargin=0in
+\parskip=6pt plus2pt minus2pt
+
+% and some of my own personal preferences
+\parindent=0in
+
+\newcommand{\var}[1]{{\tt #1\/}}    % variables
+\newcommand{\fun}[1]{{\tt #1\/}}    % functions
+\newcommand{\expr}[1]{{\tt #1\/}}   % expressions
+\newcommand{\type}[1]{{\tt #1\/}}   % types
+\newcommand{\class}[1]{{\tt #1\/}}  % classes
+\newcommand{\module}[1]{{\tt #1\/}} % modules
+
+\newcommand{\tva}{$\alpha$} % type variables
+\newcommand{\tvb}{$\beta $}
+\newcommand{\tvc}{$\gamma$}
+
+\newcommand{\arrow}{$\enspace\to\enspace$} % type constructors
+
+\newcommand{\Hugs}{{\bf Hugs\/}}
+\newcommand{\GHC}{{\bf GHC\/}}
+\newcommand{\Haskell}{{\bf Haskell\/}}
+
+\newcommand{\cexpr}[1]{{\tt #1\/}}   % C expressions
+\newcommand{\ctype}[1]{{\tt #1\/}}   % C types
+\newcommand{\cvar}[1]{{\tt #1\/}}    % C variables
+\newcommand{\cfun}[1]{{\tt #1\/}}    % C functions
+\newcommand{\cfile}[1]{{\tt #1\/}}   % C files (.c, .h, etc)
+
+\newenvironment{aside}{%
+  \medbreak
+  \noindent
+  {\bf Aside: }
+  \begingroup
+    \sl
+    \begin{indent}  % why doesn't this do what I expect?
+}{%
+    \end{indent}
+  \endgroup
+  \par
+  {\bf End aside.}
+  \medbreak
+}
+
+\newenvironment{note}{%
+  \medbreak
+  \noindent
+  {\bf Note: }
+  \begingroup
+    \sl
+    \begin{indent}  % why doesn't this do what I expect?
+}{%
+    \end{indent}
+  \endgroup
+  \par
+  {\bf End note.}
+  \medbreak
+}
+
+\newcommand{\Portability}[1]{\par{{\bf Portability Note:} \sl #1}\par}
+\newcommand{\Warning}[1]{\par{{\bf Warning:} \sl #1}\par}
+
+% These are used for reminders, communication between authors, etc.
+% There should be no calls to these guys in the final document.
+
+%\newcommand{\ToDo}[1]{\par{{\bf ToDo:} \sl #1}\par}
+\newcommand{\ToDo}[1]{{{\bf ToDo:} \sl #1}}
+
+\newenvironment{outline}{%
+  \medbreak
+  \noindent
+  {\bf Outline: }
+  \begingroup
+    \nobreak
+    \sl
+}{%
+  \endgroup
+  \nobreak
+  {\bf End outline.}
+  \medbreak
+}
+
+% Here's how you create figures
+%
+% \begin{figure*}
+% \centerline{
+% Foo
+% }
+% \caption{...}
+% \label{...}
+% \end{figure*}
+
+\begin{document}
+
+\title{%
+  Architecture of the Haskell Execution Platform (HEP)\\
+  Version 6
+}
+
+\author{Julian Seward, Simon Marlow, Andy Gill, Sigbjorn Finne, Simon
+  Peyton Jones \\
+Microsoft Research, Cambridge, UK\\
+{\tt \{v-julsew,simonmar,v-sfinne,simonpj\}@microsoft.com}, {\tt andy@cse.ogi.edu}}
+\date{29 July 1999}
+\maketitle
+
+
+
+\section{What this document is for}
+As the combined GHC--Hugs system comes ever closer to running compiled
+code, it becomes clearer than an architectural overhaul is
+needed.  We at MSRC, together with Andy Gill, have been discussing
+this at length.
+
+Those wishing to go directly to the all-important HEP
+interface will find it in section 6.1.
+
+\section{Names}
+One frequent point of confusion in our discussions so far has
+been what the names mean.  Here's some defns:
+
+\begin{itemize}
+\item ``GHC'' is the standalone native-code compiler.
+\item ``Hugs''
+  denotes the version built from sources in the Glasgow tree,
+  using an STG back end and GHC runtime support.  On supported
+  architectures, Hugs will be able to load binaries compiled by GHC.
+\item ``Hugs98'' is the current public distribution.  This document is not
+  concerned with it.  Further changes to
+  Hugs98 will be bugfixes/maintenance, and we expect that Hugs will
+  supercede Hugs98 at some point.
+\end{itemize}
+
+
+\section{Rationale and motivation}
+As of 10 June, Hugs is able to load and run
+extremely simple functions compiled by GHC.  To get to this stage has
+required drastic changes to the original Hugs98 from which it was
+derived:
+\begin{itemize}
+\item dumping the original back end and runtime support, and using
+  an STG-based code generator and GHC's RTS instead.
+\item adding a new parser to read GHC's interface files (easy) and
+  a significant amount of code to manufacture appropriate
+  symbol table entries (not so easy).
+\item modifying the import chasing mechanism to follow dependencies
+  through both source and interface files.
+\end{itemize}
+
+These changes, particularly the latter two, are inelegantly integrated
+into the original structure.  It is clear that whatever Hugs
+emerges as a result of my current hackery will be more a
+proof-of-concept vehicle than as something which we can carry
+forwards.  Some of the design decisions I made on the way are, in
+hindsight,  bad.  A decent system will need a cleaned-up
+architecture.
+
+Hugs is becoming more complex as more parties modify it for their own
+diverse purposes.  There are now various user interfaces (WinHugs, the
+``standard'' text UI, the HaskellScript stuff, and RunHugs).  Not far
+ahead will come the further complexity of supporting multiple code
+generators.  We already have the original and STG codegens, and 
+further codegens are proposed for Hugs and GHC.
+
+A powerful motivating factor for redoing the architecture is to try
+and modularise Hugs so that
+\begin{itemize}
+\item supporting these various extensions is simpler.
+\item supporting different platforms is simpler.  Hugs is not too
+  bad, but GHC is very Unix oriented.
+\item new extensions don't involve grappling with so many
+  parts of the system.
+\item building customised variants is simpler.
+\end{itemize}
+
+Finally, it would be nice to at least review, and possibly redo, some
+aspects of the existing code base:
+\begin{itemize}
+\item The conservative garbage collector (now reduced to compile-time only
+  duty in Hugs) has been much discussed.  Perhaps we could
+  do away with it and use the GHC heap instead.
+
+\item Symbol table (names, classes, values, instances, modules) management
+  in Hugs is too inflexible to support loading and unloading of
+  arbitrary mixtures of compiled and interpreted code in arbitrary
+  orders.  It needs redoing.
+
+\item The import chasing mechanism is hard to understand, and has proven
+  difficult to adapt for use in Hugs.  Redesign is unavoidable.
+\end{itemize}
+
+
+
+\section{Issues}
+Here are the major architectural difficulties which have been encountered.
+
+\begin{itemize}
+\item 
+  What mixtures of compiled and interpreted code should be supported?
+  Currently there are at three proposals, in increasing order of
+  complexity to implement:
+  \begin{itemize}
+  \item ``Downward closure'': if module M is compiled, then all modules
+     reachable from M, including Prelude, must be too.
+  \item ``Prelude + any'': arbitrary mixtures are allowed, with the proviso
+     that if any module is compiled, then the Prelude must be compiled
+     too.
+  \item ``Any'': any mixture at all.
+  \end{itemize}
+  Underlying problems are:
+  \begin{itemize}
+  \item 
+     Run-time linking of object files.  Use of the Unix \cfun{dlopen}
+     facility mandates a downward closure approach, since there is
+     no way to resolve references to interpreted code from compiled
+     code.  How the windows DLL loaders would behave I don't know.
+     To be more flexible seems to require writing one's own linkers.
+  \item
+     Primops.  Operations on, and assumptions about representation of
+     primops have to be compatible in compiled and interpreted code.
+     One possibility is to ensure that Hugs's and GHC's primops
+     exactly correspond.  That seems wasteful, and difficult and
+     bug-prone to maintain.  Another approach it to route all
+     primop calls to GHC, probably by routing them all via a
+     GHC-compiled Prelude.
+  \item
+     Interface files.  All but the downward closure option require
+     Hugs to generate interface files for interpreted modules
+     so GHC can compile against them.
+  \end{itemize}
+
+\item
+  When the user asks ``:reload'', how should Hugs go about bringing
+  the execution environment up-to-date?  How intelligent should it be?
+  (how accurately do we track changes in the module dependencies?)
+  Where do we put the intelligence?  Is Hugs allowed to invoke GHC,
+  or must the user do it?  Do the different user interfaces require
+  different levels of sophistication?
+
+\item
+  For platforms on which GHC is not supported, 
+  we still desire to build a standalone Hugs without object loading
+  facilities.
+  The main trickyness is that a standalone Hugs will have to supply 
+  its own implementation of primops, since it can't rely on use of
+  primop facilities in a GHC-compiled prelude.
+\end{itemize}
+
+Some less troublesome issues are
+
+\begin{itemize}
+\item
+  We might want a form of BCO which can be dumped
+  into a file and reloaded/linked later.  One use would be to 
+  give an architecture-neutral way to distribute libraries
+  in binary form.  Another is for shipping code across a network.
+  Finally, for platforms on which GHC is not supported, it offers
+  the possibility of fast startup, by loading \cfun{Prelude.bco} and
+  reading \cfun{Prelude.hi}.  One consequence of doing dumpable
+  BCOs is that Hugs would need to create interface files.
+\item
+  Multiple code generators.  If Hugs is to acquire other code
+  generators, it may be desirable to create an interface at the
+  boundary between STGland and the code generators.
+
+  Since GHC may also want to target new platforms, work on new
+  code generators should aim to maximise compatibility between
+  Hugs and GHC.
+\item
+  Loading object files.  
+  Hugs is fairly platform independent, except
+  for its need to load object files.  We can
+  create an object file loading/linking generic API, and hook
+  specific loaders, for example ELF and Win32 DLL, under that. 
+  However, as mentioned above, use of the native facilities may be
+  too inflexible, and so necessitate writing our own linkers.
+\item
+  Object vs source-level symbol tables.
+  For each function \cfun{f} that GHC compiles, a whole
+  bunch of symbols are spewed into the object code: \cfun{f\_closure},
+  \cfun{f\_entry}, \cfun{f\_info} and \cfun{f\_fastk}, at the very
+  least.
+
+  On the one hand, you need to remember all these names because other
+  object modules will reference them.  On the other hand, the bytecode
+  compiler is only interested in source-level facts about \cfun{f}, such as
+  its type, and not about the addresses of its derivative symbols.
+  We propose to have a
+  separate symbol table for object code symbols, with only minimal
+  connection to the source-level symbol table (a pointer to
+  \cfun{f\_closure} ?)
+\item
+  Replacement of the conservative garbage collector.  It doesn't
+  make much sense to have two heaps, allocators and GCs in the new Hugs.
+  Either we can move compile-time allocation into the
+  execution heap, or move to an arena-based allocator.  Hugs allocates
+  heap when compiling so slowly that the latter possibility is quite
+  practical.  Either way, the main criteria is to reimplement the \cfun{fst},
+  \cfun{snd}, \cfun{pair}, \&c, macros, so that client code doesn't have to be
+  changed.
+
+  Changing the heap representation would require a new scheme
+  for dealing with Hugs' symbol tables, since pointers to places
+  outside the (Hugs) heap are interpreted in various ways, including
+  as symbol table references.
+
+  It's also unclear what the consequences would be of any client
+  code which dynamically changes the type of a (eg) pair field
+  from pointer to non-pointer, or vice versa.
+\item 
+  Dictionary layouts.  Hugs and GHC need to agree on the order
+  in which dictionary arguments are passed, and on the order of
+  methods within a dictionary.  We also need to make GHC regard
+  selector functions as possibly overloaded, if necessary,
+  and pass dictionaries appropriately.
+\item
+  Currently GHC, and therefore Hugs, is very Unix oriented.  This
+  is not acceptable for a standalone Hugs.  The main blocking points for
+  development on WinNT are the GHC driver (Perl) and the
+  build environment (GNU Make).
+\item
+  Profiling.  If Hugs is to be able to do profiling,
+  it needs to be able to handle scc annotations and probably implement
+  auto-sccification.  Will it be difficult to make sure the
+  implemented cost semantics are the same as that of GHC ?
+\item 
+  Type system extensions.  If Hugs is to implement them, Hugs and
+  GHC must agree on them.  Currently: multiparam type classes, 
+  local universal quantification, existential quantification.
+\item 
+  Issues to do with startup and loading the Prelude, so as
+  to minimise code duplication and complexity in Hugs.
+  Interacts with the primops issue.
+\item
+  Andy is interested in looking into some hooks for debugging.
+\end{itemize}
+
+
+\section{Proposed structure}
+\begin{verbatim}
+              TextUI    WinUI  HaskellScript  etcUI    VisualStudio
+                 |        |         |          |           |
+                 +--------+----+----+----------+ ..........+
+                               |
+                             ..... HEP interface
+      /~                       |
+      |                    Session                     ((Compile-time
+      |                    Manager                       storage mgr))
+      |                        |
+ HEP -+        +----------+----+----+----------+---------+
+      |        |          |    |    |          |         |
+      |    Bytecode    Source  |  Object     Object    IFace
+      |    Compiler    SymTab  |  Loader     SymTab    Reader
+      \_                       |
+                            StorMgr
+                            & Eval
+\end{verbatim}
+This crude picture depicts the main blocks, with lines indicating flow
+of control, not data.  Underlying all components is the compile-time
+storage manager.  The session manager is central to the design, so
+I'll start there.
+
+The parts from the Session Manager on downwards, including the 
+compile-time storage manager, are collectively known as the
+Haskell Execution Platform (HEP).  HEP has to support a diversity
+of clients, both those which offer human user interfaces (TextUI,
+WinUI, etc) or those offering higher level programmatic interfaces
+(HaskellScript, VisualStudio).  Because of this, the HEP interface
+is critical.  It is described in detail in Section 6.1.
+\begin{itemize}
+\item
+  Session manager (SM): Responsible for building an up-to-date
+  executable image (mixture of byte and native code) when the user
+  interfaces request a particular Haskell module to be made available
+  for execution.  Responsible for arranging
+  evaluation of Haskell expressions passed from the user interfaces.
+
+  To build an up-to-date image, SM needs to keep track of module
+  dependencies and source/object in-or-out-of-dateness, so as to
+  determine when to reload/recompile modules.
+  It's fair to say that SM will have to
+  incorporate the functionality of (\cfun{hbc|nhc|}$\epsilon$)\cfun{make}.
+
+  The RTS can support multiple Haskell threads running concurrently,
+  so SM offers that service too.  This might be useful for a GUI based
+  Hugs in which there are multiple read-eval windows.  Further, SM
+  needs to offer GUIs a way to check their own event queues whilst the
+  evaluator or compiler is running.  We have devised what we hope is a
+  flexible scheme to support this.  The same mechanism allows UIs to
+  interrupt compilation or evaluation in a portable manner.
+\item
+  Bytecode Compiler (BC): the previous core of Hugs.  Reads Haskell
+  source and translates it via STG code to bytecode, which it places
+  in the (runtime) heap.  Updates the Source SymTab (SSym) entry for
+  this module and references SSym entries for other modules.
+  Optionally emits a simple, GHC-readable interface file for the
+  module.
+
+  In order that SM can determine the dependencies of a given source
+  file without attempting full compilation, BC has a facility to parse
+  a file and return the import list, but do nothing more.
+
+\item
+  IFace Reader (RdIF): reads GHC created interface files and
+  manufactures symbol table entries in SSym for the specified module.
+
+  Analogously to BC, has a submode for finding just the dependencies
+  of an interface file.
+
+  When called upon to load an interface, RdIF must engage Object
+  Loader (OLoad) to load the corresponding object file.  It is OLoad's
+  responsibility to relocate and link this file, since that's platform
+  dependent.  However, RdIF must add some minimal info about the
+  object code to this module's SSym entry, namely the address of the
+  \cfun{\_closure} entry points.
+
+\item
+  Source Symbol Table (SSym): is the global source-level symbol
+  table, containing info on modules (imports, exports), classes
+  (types, members, etc), instances, tycons and functions.  This is
+  what BC will have to consult and update in order to static-check and
+  typecheck source files.  SSym only contains enough info about object
+  files to be able to create calls to GHC compiled functions.  At the
+  moment this would appear to be the \cfun{f\_closure} addresses.
+
+  SSym must be designed so that modules can be thrown out of the
+  system in any order, rather than just the stack-like order in the
+  current Hugs.  Fixed limits on table sizes should also be avoided.
+
+  SSym must be designed so client code doesn't have to change.
+  I think most accesses go via the \cfun{name}, \cfun{isName},
+  \cfun{findName}, \cfun{newName} macros (ditto \cfun{module},
+  \cfun{cclass}, \cfun{inst}, \cfun{tycon}), so it's ok.
+
+\item
+  Object Symbol Table (OSym): global object-level symbol table.
+  Contains a binding for every symbol in every object currently
+  loaded.  New objects can be linked merely by querying OSym;
+  no reference to SSym is needed.  As motivation, GHC compiled 
+  functions have dozens of symbols not referred to at the source
+  level but which are referred to from other objects, and also 
+  internally between code and data sections, so we need
+  to record their addresses.
+
+
+\item
+  Object Loader (OLoad) has two duties: (1) bring an object file into
+  memory and create OSym entries for it.  (2) resolve references in an
+  object file in memory by consulting OSym (and possibly SSym?).
+
+  OLoad is obviously object-format dependent.  It should be structured
+  so that it has a 
+  format independent interface, and implementations of (1) and (2) for
+  each format (ELF, DLL, COFF, etc).  The ELF implementation is
+  already done and takes only about 300 lines of C.
+
+  Extra complication: object files can refer to symbols in the RTS,
+  and to symbols like \cfun{printf}.  These symbols will be bound into the
+  executable Hugs image at the time that is built.   So we need a
+  way to find the addresses of symbols ``in this process image''.  On
+  one hand, logically it is up to OSym to supply these addresses.  But
+  this is also object/executable format dependent, so OLoad needs to
+  be involved.  Blargh.  Possibly have an OLoad call to preload 
+  OSym with these symbols at Hugs startup time.
+
+
+\item
+  Storage Manager and Evaluator (RTS): This is the GHC RTS,
+  along with the bytecode interpreter already in StgHugs.  Executes the
+  native/bytecode mixture.  (Not sure what else to say.  This is
+  what Simon and Alastair created.  It works and is more or less in
+  the required form).
+
+
+\item
+  The user interfaces, TextUI, WinUI, RunHugsUI, etc.  These wrap up
+  the services of SM and present them to the end-user, either human
+  or programmatic, in some
+  appropriate way.  The pictures show multiple interfaces built into
+  the system, but in practice we expect only one to be linked in to
+  any particular system.  The requests that they can pass to SM are:
+  \begin{itemize}
+  \item Initialise system, shut down.
+  \item Change system settings (implements :set in Hugs)
+  \item Prepare a module for use, returning a module handle.
+  \item Translate expressions in the context of a given module.
+  \item Evaluate a translated expression.
+  \item Query SSym (so that :info, :type, etc can be implemented)
+  \end{itemize}
+
+\item
+  Underlying everything is the compile-time storage manager.
+  Details currently hazy.
+\end{itemize}
+
+\subsubsection*{Possible variant 1: multiple code generators}
+Chop up BC, so it becomes a single source-to-STGcode converter
+plus some number of STGcode-to-whatever code generators.
+Hopefully the code generators would all have the same interface.
+\begin{verbatim}
+  TextUI    WinUI   RunHugsUI  etcUI    VisualStudio
+     |        |         |        |           |
+     +--------+----+----+--------+ ..........+
+                   |
+                Session                     ((Compile-time
+                Manager                       storage mgr))
+                   |
+   +----------+----+----+----------+---------+--------+----------+
+   |          |    |    |          |         |        |          |
+ Haskell   Source  |  Object     Object    IFace    STG to     STG to
+ to STG    SymTab  |  Loader     SymTab    Reader   Bytecode   OTHER
+                   |
+                StorMgr
+                & Eval
+\end{verbatim}
+
+\subsubsection*{Possible variant 2: dumpable BCOs}
+If BCOs are dumpable to file, they can be regarded as just another
+flavour of object format.  Then the Haskell to BCO (BC) component can
+be factored off into another process.  Loading of BCOs would be done
+via OLoad, with RdIF reading the interface files which would have
+to be created by BC.  It also means BC would have to read
+interface files.
+
+This scheme has overheads in both compile speed and
+implementational complexity.  The point of mentioning it is to
+emphasise the idea that there's no particularly fundamental reason why
+the BC component should be compiled into SystemC whilst GHC remains a
+separate entity.  If we need to do this, it's not difficult.
+However, nor is it at present of the highest priority.
+
+
+\section{The component interfaces}
+
+Many of the calls can fail.  It would be good to think about a
+consistent error-recovery strategy.  I've ignored any error cases
+in the signatures below.  I'm working with Variant 1 (multiple code
+generators) above.
+
+
+
+\subsection{Session manager (SM)}
+These interfaces are presented in IDLishly, with
+Haskell types.  Regard the return types as really being \verb@IO@
+types.
+\begin{verbatim}
+interface IUnknown {
+   addRef, release :: ()
+}
+\end{verbatim}
+All interfaces inherit reference counting methods in \verb@IUnknown@.
+When a client copies a pointer, it should \verb@addRef@ it, and
+conversely \verb@release@ it when done.
+Once a pointer is \verb@release@d, the thing it points at may or
+may not still be alive, but in any case the owner of the
+pointer must assume it is dead.  \ToDo{Are these the COM semantics?}
+
+\subsubsection{Servers}
+\begin{verbatim}
+getServer :: HsServer
+
+interface HsServer : IUnknown {
+   loadModule   :: LoadHooks -> String -> Maybe HsModule
+
+   setOptions   :: [(String,String)] -> ()
+   getOptions   :: [(String,String)]
+   canUseObject :: Bool
+}
+\end{verbatim}
+For simplicity, we assume there is only one server, obtained
+via \verb@getServer@.  In practice they might be manufactured 
+by a class factory (???), but that's too COM specific here.
+
+A client can ask a \verb@HsServer@ object whether it is 
+capable of loading object code with \verb@canUseObject@.
+HEPs hosted on non-GHC-supporting platforms will return
+\verb@False@ here.  The HEP will still work but must
+interpret everything.
+
+Clients can query and set options for this server using
+\verb@getOptions@ and \verb@setOptions@.  \verb@getOptions@
+returns all the available options and their current values.
+\verb@setOptions@ can supply new values for any subset, or all, of
+them.
+
+\verb@HsServer@'s main purpose is to supply \verb@loadModule@.
+Clients supply a string such as ``\verb@List@'', indicating a
+module name, with no filename extension or directory.  
+HEP tries to return a \verb@HsModule@ handle reflecting
+the current state of the source/object code base.  In doing so,
+it may need to load and/or compile arbitrary numbers of 
+subsidiary modules.  This operation may fail, hence the \verb@Maybe@
+return type.
+
+Once a \verb@HsModule@ handle has been successfully acquired,
+that handle remains valid until the client calls \verb@release@
+on it.  What the handle refers to is the state of the object/source
+code base at the time the handle was created.  Subsequent changes
+to the code base have no effect on the handle; the executable images
+to which it refers are unchanged.
+
+For example, assuming \verb@s :: HsServer@ and \verb@h :: LoadHooks@,
+then given the following sequence of events
+\begin{enumerate}
+\item \verb@m1 = s.loadModule("M", h)@, and this call succeeds
+\item The source/object for \verb@M@ changes
+\item \verb@m2 = s.loadModule("M", h)@
+\end{enumerate}
+\verb@m1@ will continue to be valid and will refer to the original
+version of \verb@M@, whilst \verb@m2@ refers to the new version.
+Furthermore, if \verb@M@ depends on some other
+modules, \verb@m1@ will still be based on the
+original version of those modules, even if their sources/objects
+change.  In short, once a \verb@HsModule@ comes into existence,
+its meaning never changes.
+
+\subsubsection{Load-time hooks}
+
+HEP decides for itself what modules it needs to load, when, and
+in what order.  It is up to the client to supply the
+actual source/object code for modules.  To facilitate this, 
+clients must pass a \verb@LoadHooks@ object to \verb@loadModule@:
+\begin{verbatim}
+interface LoadHooks : IUnknown {
+   findModule :: String
+         -> (Maybe InStream, Maybe (InStream, InStream))
+      -- .hs file, (.hi file, .o file)
+
+   setProgress :: String -> Float -> Bool   
+      -- True <=> abandon compilation please
+
+   error :: Error -> ()
+}
+\end{verbatim}
+When HEP needs a module, it calls \verb@findModule@, passing it
+the unadorned module name, unadorned in the same way as names 
+passed to \verb@loadModule@.  The client should attempt to locate
+source, interface and object streams for the module in any way
+it pleases.  The returned pair is a possible stream for the
+source text, and a possible pair of streams for the interface
+and object text.  This latter pairing exists because there's
+no point in producing an object stream without the corresponding
+interface stream, or vice versa.
+
+An \verb@InStream@ is an abstract handle with which to read a finite stream.
+\verb@getChar@ reads the next character or returns an end-of-file
+marker.  \verb@fprint@ returns a fingerprint, perhaps a checksum,
+or a file timestamp,
+which characterises the stream's contents.  \verb@eqFPrint@ compares
+this stream's fingerprint against a supplied one.  The fingerprinting
+semantics requires that two identical streams have identical
+fingerprints. \ToDo{Do we care that this isn't implementable,
+strictly speaking?}  The intention is to provide HEP with a 
+way to determine to whether a given stream has changed since it was
+last looked at.  \verb@FPrint@ is regarded as an abstract type
+supplied by the client.
+\begin{verbatim}
+interface InStream : IUnknown {
+   getChar  :: Int
+   fprint   :: FPrint
+   eqFPrint :: FPrint -> Bool
+}
+\end{verbatim}
+
+HEP notifies the client of compilation/loading progress by calling
+\verb@setProgress@, giving the name of a goal, eg ``Typechecking'',
+and a value, increasing monotonically over a sequence of such calls,
+from $0.0$ to $1.0$, indicating progress towards that goal.
+If the client returns \verb@True@ to such a call, HEP abandons 
+compilation as soon as possible.  In this way, clients can
+interrupt compilation in a portable manner.
+
+If a compilation error occurs, HEP creates a \verb@Error@ object
+and passes it to the client with \verb@error@.  For the moment,
+the error object only contains the source coordinates of the
+error, the \verb@InStream@ from which the source originated,
+and a method \verb@show@ which produces the text of the error message.
+Later versions may contain more information.
+\begin{verbatim}
+interface Showable : IUnknown { 
+   show :: String
+}
+
+interface Error : Showable {
+   source    :: InStream
+   line, col :: Int
+}
+\end{verbatim}
+
+\subsubsection{Modules}
+Once a client has obtained a \verb@HsModule@ handle, it can
+translate and run expressions in the context of that module.
+Translated values are \verb@HsVal@ objects.
+\begin{verbatim}
+interface HsModule : IUnknown {
+   exprVal :: String -> Bool -> Maybe HsVal
+      -- A Haskell expression, treated as if
+      -- it was written in the module
+      -- Bool==True <=> wrap in `print' if not :: IO t
+
+   idVal :: String -> Maybe HsVal
+      -- The name of a top-level value in
+      -- scope in the module
+
+   -- takes a regexp, gives list of things
+   -- defined in (Bool==True) or in scope in (Bool==False) this mod
+   getNames     :: Bool -> String -> [Name]
+   getTypes     :: Bool -> String -> [Type]
+   getTycons    :: Bool -> String -> [Tycon]
+   getClasses   :: Bool -> String -> [Class]
+   getInstances :: Bool -> String -> [Instance]
+
+   -- query a specific thing.  String is a name.  Bool as above.
+   findName     :: Bool -> String -> Maybe Name
+   findType     :: Bool -> String -> Maybe Type
+   findTycon    :: Bool -> String -> Maybe Tycon
+   findClass    :: Bool -> String -> Maybe Class
+   findInstance :: Bool -> String -> String -> Maybe Instance
+}
+\end{verbatim}
+The two important methods are \verb@exprVal@ and
+\verb@idVal@.  \verb@exprVal@ takes an arbitrary Haskell
+expression and tries to return a translation of it in the
+context of that module.  The caller can optionally ask to
+have the value wrapped in \verb@print@, since that is often
+convenient.
+
+\verb@idVal@ is simpler.  It simply regards the supplied string
+as the name of a top-level function in scope in the module, and
+returns a \verb@HsVal@ referring to that name.  It's conceivable
+that a skeletal HEP which just loaded object files could implement
+\verb@idVal@ but not \verb@exprVal@.  Such a HEP would not need
+a bytecode compiler or interpreter.
+
+The \verb@get*@ and \verb@find*@ methods allow clients to consult
+the HEP's symbol tables.  In all cases, the \verb@Bool@
+parameter facilitates choosing between ``defined in this module''
+and ``in scope in this module'' interpretation of queries.
+
+\verb@getNames@ returns the names of all top-level values
+matching the wildcard in the supplied string, defined in or
+in scope in this module.  \verb@findName@ returns the 
+corresponding information for a specific name; the supplied
+string must be a real name and not a wildcard.  The \verb@Type@,
+\verb@Tycon@, \verb@Class@ and \verb@Instance@ calls function
+analogously for types, type constructors, classes and instances.
+
+As with error messages, currently the only possible action with 
+a name, type, tycon, class or instance is to print it.  This
+may change later.
+\begin{verbatim}
+interface Class    : Showable { }
+interface Type     : Showable { }
+interface Instance : Showable { }
+interface Tycon    : Showable { }
+interface Name     : Showable { }
+\end{verbatim}
+
+\subsubsection{Values}
+A Haskell value is represented by a \verb@HsVal@ object.
+\verb@HsVal@s carry their type, which is obtained with
+\verb@type@.  
+
+New values can be created by application of
+a value to a list of argument values; \verb@apply@ does this.
+The application is typechecked, and will fail if it is type-incorrect.
+\ToDo{Say more about the rules and extent of this}.
+
+For convenience, new values can be manufactured from integers,
+using \verb@mkIntValue@.  The inverse operation is \verb@intValueOf@,
+which will fail if the type is wrong.  Such mistakes can be avoided
+by first testing with \verb@isIntValue@.  \ToDo{What does
+\verb@intValueOf@ do if the arg is not in whnf?}  Similar functions
+exist for other primitive types.
+\begin{verbatim}
+interface HsVal : IUnknown {
+   type  :: Type
+
+   apply :: [HsVal] -> Maybe HsVal
+      -- can fail because of type error
+      
+   eval   :: RunHooks -> WhyIStopped   
+      -- To WHNF
+   evalIO :: RunHooks -> Maybe WhyIStopped
+      -- Runs a value of type IO t, returning the t
+      -- the result may or may not be evaluated
+
+   mkIntValue :: Int -> HsVal
+   isIntValue :: Bool
+   intValueOf :: Maybe Int
+      -- ditto Bool Char Word Float Double
+}
+\end{verbatim}
+The main purpose of \verb@HsVal@ is to supply \verb@eval@ and
+\verb@evalIO@.  \verb@eval@ evaluates a value, which may be of 
+any type, to WHNF.  The client must supply a \verb@RunHooks@ object
+to be used during evaluation.  \verb@evalIO@ is similar, except
+that the supplied value must have type \verb@IO t@.   The 
+possibly unevaluated \verb@t@ is then returned.
+\begin{verbatim}
+data WhyIStopped = Done
+                 | DoneIO HsVal 
+                 | YouAskedMeToStop 
+                 | NoThreadsToRun
+
+interface RunHooks : IUnknown {
+   continue       :: Bool
+   stdout, stderr :: Char -> ()
+   stdin          :: Char
+   -- if the last three block, the entire HEP does
+}
+\end{verbatim}
+A \verb@RunHooks@ object allows the client to capture \verb@stdout@
+and \verb@stderr@ from the evaluated expression, and supply a
+\verb@stdin@ stream for it.  If any of these calls blocks, the
+entire HEP will too.  \ToDo{Are we sure?}
+
+When running an expression, HEP will call \verb@continue@ on a
+fairly regular basis, to find out if the client wants to interrupt
+evaluation.  If the client returns \verb@True@,
+\verb@eval@/\verb@evalIO@ then will return with the value
+\verb@YouAskedMeToStop@.  The client can resume execution later
+by calling \verb@eval@/\verb@evalIO@ again on that value.
+
+\verb@eval@/\verb@evalIO@ may also return bearing \verb@Done@
+or \verb@DoneIO@ respectively, indicating that the value has
+reached WHNF.  Lastly, a return value of \verb@NoThreadsToRun@
+indicates that the RTS's scheduler could not find any Haskell
+threads to run.  This could indicate deadlock.
+
+\subsubsection{Threading issues for the HEP}
+There are two kinds of threads to consider: Haskell threads,
+managed and scheduled by the RTS's scheduler, and operating-system
+threads.
+
+Haskell threads are easy.  An \verb@eval@/\verb@evalIO@ call
+starts a single ``main'' thread, and that can create new
+threads using the Haskell primitive \verb@forkIO@.
+
+The complication lies in OS threads.  Rather than attempt
+to design a multithreaded HEP, we place a mutex around the
+entire HEP, and allow only one OS thread in at a time.
+To try and create some fairness, the HEP can, at times convenient
+to it, check whether any other OS threads are waiting to enter,
+in which case it may yield, so as to let others enter.
+
+Unfortunately this will cause deadlocks for Haskell programs
+using callbacks.  Typically, a callback function will be 
+supplied to some other subsystem (eg, graphics) using a 
+\verb@ccall@ to that subsystem, bearing the \verb@HsVal@ of the
+callback.  To run the callback, the subsystem will later
+call \verb@eval@ on the callback.  But if the same OS thread is
+still ``inside'' the HEP, this call will block.
+
+A solution is to release the lock when an OS thread \verb@ccall@s 
+out of the HEP.  This allows other threads, or callbacks in the
+same thread, to successfully enter the HEP -- not necessarily 
+immediately, but eventually, assume the OSs thread scheduling
+is fair.
+
+
+\subsection{Haskell to STG compiler (Hs2Stg)}
+\begin{verbatim}
+-- look at text of module and get import list
+getImportList :: ModuleName -> [ModuleName]
+
+-- convert .hs to stg trees
+compileModule :: ModuleName -> [STG]
+\end{verbatim}
+
+
+
+\subsection{Interface reader (RdIF)}
+Loading of mutually recursive groups of objects is allowed even
+though Hugs can't handle that at the source level.  Internally,
+\cfun{loadObjectGroup} has to make two passes through the 
+interface files, the first to create partially-filled entries in SSym, and the 
+second to complete those entries.
+\begin{verbatim}
+-- look at interface file for module and get import list
+getImportList   :: ModuleName -> [ModuleName]
+
+-- load a group of modules, resolving references between them
+-- update OSym and SSym
+loadObjectGroup :: [ModuleName] -> ()
+\end{verbatim}
+
+
+
+\subsection{Source symbol table (SSym)}
+\begin{verbatim}
+-- create/delete entries for a new module
+newModule :: ModuleName -> ()
+delModule :: ModuleName -> ()
+
+-- various functions for adding/querying vars, tycons, classes, instances
+-- and in particular
+setClosureOf :: Name -> Pointer -> ()
+getClosureOf :: Name -> Pointer
+\end{verbatim}
+
+
+\subsection{Object symbol table (OSym)}
+\begin{verbatim}
+-- add, delete module-level entries
+addOMod  :: ModuleName -> ()
+delOMod  :: ModuleName -> ()
+-- add, find symbols
+addOSym  :: ModuleName -> Name -> Pointer -> ()
+findOSym :: ModuleName -> Name -> Pointer
+\end{verbatim}
+
+
+
+\subsection{Object loader (OLoad)}
+\begin{verbatim}
+-- check object for correct format, etc
+validateObject :: ModuleName -> Bool
+-- get object into memory and update OSym, but don't link it
+loadObject :: ModuleName -> ()
+-- resolve refs in previously loaded object
+linkObject :: ModuleName -> ()
+-- remove object from memory
+delObject :: ModuleName -> ()
+\end{verbatim}
+
+
+\subsection{Storage manager and evaluator (RTS)}
+\begin{verbatim}
+-- eval this ptr to WHNF
+enter :: Pointer -> ()
+\end{verbatim}
+
+
+
+\subsection{Code generators, STG to bytecode (Stg2BC) and STG to OTHER
+      (Stg2Com)}
+\begin{verbatim}
+stg2BC, stg2OTHER :: [STG] -> ()
+\end{verbatim}
+
+
+\subsection{The user interfaces}
+... don't have a programmatic interface.
+
+
+
+
+\section{Tentative design details looking for a home}
+
+These sections record how the various bits of the new system
+should work.  In may places it merely records what the existing
+system does.
+
+\subsection{Compile-time storage management}
+{\bf ToDo}: draw some pictures of how the tables interrelate.
+
+Relevant structures are
+\begin{itemize}
+\item compile-time heap
+\item Source symbol table, comprising: name table, tycon table,
+class table, instance table, module table
+\item Text table (not sure where this logically belongs)
+\item Object symbol table
+\end{itemize}
+Needs to be redone.  Design goals are:
+\begin{itemize}
+\item Should be able to delete an arbitrary module from the system
+      and scrub all references to it.  The current Hugs scheme only
+      allows deleting of modules in a LIFO fashion.
+\item No fixed table sizes for anything!
+      Everything to by dynamically resizable on-the-go.
+      This is a long-overdue change.
+\item No changes to the client code.  No way do we want to rewrite
+      the typechecker, static analyser, etc.  That means that
+      any reimplementation will have to supply suitable versions
+      of the many macros used to access storage in current Hugs.
+      Indeed, the viability of this enterprise depends on
+      the observation that the current Hugs consistently uses these 
+      macros/functions and does not go directly to the structures.
+\end{itemize}
+
+For the time being, it seems best not to mix the compile-time
+and run-time heaps.  It might be possible, but there are a bunch
+of unknown factors, and fixing them seems to have a low 
+brownie-points/effort ratio:
+\begin{itemize}
+\item Hugs assumes the existence of a ``generic'' pointer-ish entity.
+      This might point into the heap, but if it doesn't, then it can
+      be a reference to a symbol table, an integer, a piece of text,
+      or various other things.  This simplifies the typechecker and
+      static analysis.  (I guess you could say it's a union type).
+
+      Let's call these values ``compile-time pointers''.
+
+      GHC's storage manager would need to be modified to
+      deal with fields which might or not might be pointers.
+
+\item Assignment.  Hugs frequently (?) mutates heap objects.  I'm
+      unsure what effect this would have on the RTS if a pointer field
+      is changed to a non-pointer one, or vice versa.
+
+      Also, when doing assignments, the old-to-new pointer tables
+      would need to be checked and updated.  Changes to
+      client code at assignment points seem unavoidable.
+\end{itemize}
+\subsubsection*{Name, tycon, class and instance tables}
+Each name table entry describes a top-level value in a Haskell module.
+It holds a pointer to the textual name, the type, pointers to the
+STG trees and compiled bytecode, and various other things.  A
+compile-time pointer can point directly at a name table entry.
+
+Like existing Hugs, we continue to organise the name table as an
+array of name table entries.  Unlike existing Hugs, the name 
+entries for a given module do not occupy a contiguous range
+of the name table.  To do so makes it impossible to delete 
+modules, since deletion of a module would create a large hole
+in the table.  To fill this hole, we'd have to slide other entries
+around, but then we'd need to find and change all
+compile-time pointers to the moved entries (viz, the usual
+compacting-GC problem).  The latter could be
+very difficult.
+
+Instead, each name table entry has a link field, which is used to 
+chain together all entries for a given module.  For unused entries,
+the link fields implement a standard freelist.  Allocation of new
+entries consults the freelist.  If that's empty, the table is 
+expanded as follows: a bigger array, perhaps twice the size, is
+malloc'd.  The existing name table is copied into it, and the
+new entries are put on the free list.  
+
+When a module is deleted, all its name table entries are put back on
+the free list.
+
+The tycon, instance and class tables function in exactly the same way.
+The module table is different.
+
+\subsubsection*{Notion of the ``current module's scope''}
+When translating a module, Hugs needs to have a way, given the text
+of a symbol, to (a) find out if it is in scope in this module, and 
+(b) if so, what value/type it is bound to.  Because a module can
+import symbols from other modules, the current scope is not just
+the contents of the current module.
+
+To support this, name table entries have a second link field.
+This field is used to chain together all entries in the current
+scope.  Unlike the module-link fields, this chain necessarily
+visits entries from many different modules.
+
+Because each name table only has one scope-link field, only
+one current scope can be supported at any time.  When Hugs
+starts processing a new module, the current scope chain has to
+be rebuilt for that module, by processing its import declarations,
+and recursing down through other modules as necessary.  This operation
+is expensive and should be done infrequently.
+
+Having a single chain for the current scope makes
+name lookup terribly inefficient.   The current Hugs uses a small
+256 entry hash table to help.  Each hash table entry points to a
+chain of name-table entries with the same hash value, chained as
+described above through the current-scope field.  In other words,
+there are 256 current-scope chains, not just one, and they all 
+begin at the hash table.  So, when changing current module,
+Hugs has to rebuild the hash table as well as the chains.
+
+Tycons, classes and instances use exactly the same scheme.
+
+
+\subsubsection*{The module table}
+
+Unlike the name, tycon, class and instance table, this one 
+has exactly one entry per module.  Each entry contains 
+pointers to: the textual name of the module,
+an import list, an export list,
+the start of the name-table chain
+for this module, ditto for tycons, classes and instances, 
+and perhaps a pointer to a list of STG trees denoting the
+code generated for the module.  When a module is deleted,
+its module table entry is marked as unused.  This table can
+be resized by copying it into a larger array if needed, in the
+usual way.
+
+\subsubsection*{The text table}
+
+This remains pretty much the same as before, with the proviso
+that entries in it cannot be ejected when a module is deleted.  
+If it gets full, we expand it by copying it onto a bigger
+array in the usual way.  In practice this is unlikely to be
+a problem, since loading a revised version of a recently-deleted
+module is very likely to present almost the same set of strings
+as the old version, thereby not increasing the size of the
+table very much.
+
+One final detail: the current hashing scheme to find stuff in
+the table will need to be carefully revised so that it can
+still work when the table size is, say, doubled.  Apparently
+\verb@rts/Hash.c@ contains a suitable algorithm.
+
+\subsubsection*{The object symbol table}
+
+We may as well make the object symbol table work in the same way as
+the name, tycon, class and instance tables.  That is, an array of 
+symbol records, with each record having a link field to chain together
+entries in the same module, and another field linking together entries
+with the same hash values.  The table can expand dynamically, and
+modules can be thrown out of the table in any order.  There is a
+top-level hash table holding the start point of the hash chains.
+
+Unlike the name, class, tycon and instance tables, the hash table
+and chains for the object symbol table reflects all the available
+symbols, not just those regarded as in scope for the current module
+being translated.
+
+\subsubsection*{Dividing up the compile-time-pointer space}
+
+Hugs has always had the notion of a pointer which {\em might}
+point into the compile-time heap, or it might not, denoting a 
+name, piece of text, etc.  This is a great idea, but needs redoing.
+
+Problem is that the address spaces for the various kinds of
+entities are arranged contiguously, with no gaps in between.  This
+make it impossible to expand the address range for some particular
+kind of entity without disturbing the other address ranges.
+
+We propose instead to use a tag-and-value scheme.  A
+compile-time-pointer
+is still a 32-bit integer, but divided up thusly:
+\begin{verbatim}
+   <-1-> <--7--> <--24-->
+       0     tag    value
+\end{verbatim}
+The tag space is arranged like this (pretty arbitrary; requires a
+trawl through existing storage.h to pick up all stuff):
+\begin{verbatim}
+   000 0000    is an illegal tag
+   0xx xxxx    denotes a heap number.  value field is address in that heap.
+   100 0000    Text
+   100 0001    Name
+   100 0010    Class
+   100 0011    Instance
+   100 0100    an integer; 24-bit value field gives value
+   100 0101    Object symbol table entry
+   100 0110    Tuple constructor; value field gives tuple number
+   100 0111    Offset; value in value field
+   ........
+   101 0000    ``Box cell tag'' (TAGMIN .. BCSTAG); 
+               actual value is in value & 0xff
+   101 0001    ``Constructor tag'' (LETREC .. SPECMIN-1); 
+               value is in value & 0xff
+   101 0010    ``Special tag'' (SPECMIN .. PREDEFINED);
+               value is in value & 0xff
+\end{verbatim}
+\verb@000 0000@ is an illegal tag so that we can continue the
+convention
+that a 32-bit zero word means NIL.  We could have redefined NIL, but
+it is frequently tested for, and tests against zero are fast on most
+(RISC) architectures.
+
+There are up to 63 possible heaps, each with up to 16 M entries.
+This facilitates a dynamically expanding heap.  The idea is to start
+off with a single small heap of say 20000 cells.  When this fills,
+a new lump of memory can be malloc'd and used as a second heap, of
+perhaps 40000 cells, giving 60000 in total.  Hugs needs to know the
+size of each heap for GC purposes, but there are no required size
+relationships between them.  
+
+In principle, if Hugs can guarantee that there are no references
+to a given heap, it can return that memory to the operating system
+(or at least \verb@free@ it).
+
+This is a tradeoff.  The \verb@fst@ and \verb@snd@ macros 
+take more instructions:
+\begin{verbatim}
+   #define fst(p)    heap[p >> 24][p & 0xffffff].fst
+   #define snd(p)    heap[p >> 24][p & 0xffffff].snd
+\end{verbatim}
+Each of these translate to 5 Intel x86 insns; I have measured it.
+In the current Hugs, \verb@fst@ and \verb@snd@ are just array
+references, possibly just 1 x86 insn.
+On the other hand, if \verb@fst(p)@ is referenced close in time
+to \verb@snd(p)@, for the same \verb@p@, it's likely that the
+second reference will still be in the CPU's data cache.  The original
+Hugs has separate arrays for \verb@fst@ and \verb@snd@.
+
+Further compensation is that the ubiquitous \verb@whatIs@ call
+is a lot cheaper this way, since we just shift out the tag:
+\begin{verbatim}
+   #define whatIs(x)     ((x) >> 24)
+\end{verbatim}
+which is just a single instruction, instead of a whole sequence 
+implementing a binary search tree, as at present.
+
+Texts, names, classes, and other entities with only one tag value,
+can have up to 16 M entries, since the value field is 24 bits long.
+After some discussion, we feel that (eg) 16 M names is enough for
+programs at least ten times the size of GHC, around half a million
+lines of code.
+
+I'm going to call these entities \verb@HugsPtr@ in pseudocode bits.
+
+\subsection{The code generator interface}
+More details on how this hangs together.
+\begin{verbatim}
+stg2BC, stg2OTHER :: [(Name, STG_TREE)] -> ()
+markRTSobjects_BC,
+markRTSobjects_OTHER :: Name -> ()
+\end{verbatim}
+The result of translating a Haskell module to STG trees is a
+{\em code list}: a list of pairs \verb@(Name, STG_TREE)@.
+Each tree represents a function or CAF, either written by 
+the programmer in the source module, or generated automatically,
+by desugaring, \verb@deriving@ clauses, or lambda lifting.
+
+The \verb@Name@ component of the pairs points to a name 
+table entry for the tree.  And that name table entry points
+back at the pair.  In previous hacking, I often needed to 
+get a name table entry from a tree, and vice versa.  Without a
+bidirectional link, this requires a search of all the name tables
+or all the trees, which is inefficient.
+
+So each tree has a name table entry, even if it isn't part of
+the source given by the user.  That makes life simpler and more
+uniform, even if it wastes a little space in the name table.
+
+When the bytecode compiler translates source to trees, it 
+generates a code list, and sets up the links from the code
+list to the name table and back.
+
+To generate bytecode objects in the GHC-RTS- or OTHER-managed
+heap, \verb@stg2BC@ or \verb@stg2OTHER@ is passed the code list.
+A simple interface, but what goes on inside could be quite complex.
+\begin{itemize}
+\item For one thing, each STG tree can turn into multiple 
+      BCOs (I guess I should be more general and say ``code blocks''),
+      because of the STG way of translating \verb@case@ expressions.
+      At GC time, all of these need to be found and kept alive.
+      
+      I propose that each name table entry include the following
+      fields:
+      \begin{verbatim}
+         code_list_entry :: HugsPtr
+         rts_primary     :: HugsPtr
+         rts_secondaries :: [HugsPtr]
+      \end{verbatim}
+      \verb@code_list_entry@ is a pointer to the relevant 
+      code list pair.  The STG tree lives, of course, in the
+      compile-time heap.
+
+      After code generation, \verb@rts_primary@ and
+      \verb@rts_secondaries@ hold pointers into the code blocks
+      in the {\em runtime} heap.  (NB -- these pointers are
+      \verb@HugsPtr@s pointing to boxed pointers in the compile-time
+      heap, as at present.)  \verb@rts_primary@ holds the address
+      of the code-block (or whatever one enters) generated from
+      the tree as a whole.  \verb@rts_secondaries@ is a list of
+      pointers to subsidiary code blocks, such as \verb@case@ 
+      return continuations.
+
+      Only the specific code generators needs to understand the
+      precise meaning and layout of what \verb@rts_primary@ and
+      \verb@rts_secondaries@ point at.  Each code generator
+      must also supply a \verb@markRTSobjects@ function, which
+      examines and marks the \verb@rts_@ entries in the specified
+      name table entry.
+
+\item Linking.  
+      Code generators will have to traverse the code list twice,
+      once to generate code, and once to fix inter-tree
+      references.  ((Blargh -- unresolved details ahead))
+      The first pass translates each tree into a collection 
+      of BCOs.  Each BCO has unresolved references to other
+      BCOs, but how are they recorded?  Erk.  But I don't 
+      think this is v. important?
+  
+      In the second pass, the unresolved refs are fixed.
+
+      It seems that the BCOs can't be constructed directly in the
+      heap, because the intermediate BCOs need a fixup table which
+      the final ones don't.  Current StgHugs has \verb@AsmBCO@s for
+      the intermediaries, living in mallocville, and \verb@StgBCOs@
+      for the Real Thing in the RTS heap.  The \verb@AsmBCO@s are
+      freed at the end of code generation for a module.  Because
+      Hugs doesn't support mutually recursive modules, the entire
+      codegen-resolve cycle can happen on a per-module basis.
+
+\end{itemize}
+
+\section{\ToDo{}}
+Clarify how mutually recursive object modules are loaded.
+
+
+\end{document}
\ No newline at end of file