This document is a description of the interfaces between the loader and
other parts of the system.


Module space and Module tables
==============================

Module tables
-------------

  Two sorts of module tables, one in OCaml and the other in C, have to be
maintained, each entry of which corresponds to a top-level module in
a importing (accumulating) chain. For fast access, both sorts of the
tables should be encoded as arrays with a common (fixed) size. Further,
the entries in the two tables for a common module have to have the same
index.

  a. OCaml module table
     Each entry of the OCaml module table should contain the following
     information:

     1. a string representation of the module name
     2. a (black/red tree representation) of the parsing symbol table
        of global kinds of the top-level module
     3. a (black/red tree representation) of the parsing symbol table
        of global constants of the top-level module

     Elements in 2 and 3 should be represented in their abstract syntax
     with a mapping field recording a reference to the run-time symbol
     table. If the index method is used, such a correspondence is simply
     an index in the constant/kind tables of the bytecode file
     plus the number of pervasives.
     The absolute address encoding will make the maintenance a bit more
     complicated: the mapping field should contain an address in C, which
     implies that the starting addresses of the run-time symbol tables
     have to be known when filling in the mapping fields.
     Similar complication also occurs in compacting memory (if it is realized):
     with the index method, the OCaml symbol tables need not to be touched,
     whereas the mapping fields have to be adjusted when the absolute address
     method is used.

  b. C module table
     Each entry of the C module table should contain the following information:

     1. a pointer to the add code table for the top-level module
     2. records of space usage for the chain of modules starting from the current
        top-level module.
     [3. starting addresses of rum-time kind/constant symbol tables]


     The second item above is used for reclamation of space in unloading.
     Its structure depends on how space for the modules in a chain is to be
     allocated.
     If the modules are allocated into contiguous allocations,
     the space usage can be decided by the starting address and the total size
     of all the modules in the chain.
     Otherwise, a linked list containing the starting address and the size of
     each module in the chain has to be maintained. (This may be relevant
     if the malloc method is used.)
     The third item above is necessary if constant/kind reference is realized
     through indices.

Module space
------------
  This is space for each module in a chain.
  Depending on whether entries of run-time constant/kind tables have to be
allocated contiguous, two sorts of schemes can be used for module space.

  First, suppose the entries have to be contiguous, which is required by
the index encoding of constant/kind reference. A distinction has to be made
on top-level modules and imported/accumulated modules.
The structure of a top-level module looks like:

   --------------------------------------------
   | run-time kind symbol table               |
   --------------------------------------------
   | type skeleton table                      |
   --------------------------------------------
   | type skeleton area                       |
   --------------------------------------------
   | run-time constant symbol table           |
   --------------------------------------------
   | code area                                |
   | (instructions together with add code and |
   |  search tables)                          |
   --------------------------------------------

where the symbol tables contain all constants/kinds/type skeletons in
the chain of modules. The structure of an imported/accumulated module only
have the code area.
This sort of allocation requires an additional pass over the bytecode files
of the imported/accumulated modules to read the number
of locals, hidden constants, type skeletons and the size of type
skeleton areas.

The alternative can be used when the absolute address encoding is
used for constant/kind references. Under this scheme, the symbol
tables are maintained along with each module. Apparently,
the constant and kind tables in the imported/accumulated ones only
contain the locals and hidden constants.


Run-time symbol tables
=======================
   Kind table
   ----------
   The structure of each entry in the kind table should be:
    a. a pointer to the string representation of the name;
    b. arity of the type constructor, the type of which should
       agree with that defined in simulator/dataformat.h.

   typedef struct {
    char* name;               //the name of the type constructor
    DF_TY_ARITY arity;        //the arity of the type constructor
   } KindTableEntry;


   Type skeleton table
   -------------------
   Type skeletons will be encoded as the run-time type representations,
   each category of which has an atomic head (2 words).
   Entries of the type skeleton table have only one field which then is
   the atomic head of the type skeleton representation, which should
   agree with that defined in simulater/dataformat.h.

   typedef DF_TYPE TySkelTableEntry;

   Note that the variables in type skeletons are to be encoded as first-order
   variables. They cannot be encoded as offset into type environment
   anymore, because some type variables may not be present in our new
   type association scheme.

   Constant table
   --------------
   The structure of each entry in the constant table should be:
    a. a pointer to the string representation of the name;
    b. the atomic head of the type skeleton representation of the constant
       (of type DF_TYPE defined in simulator/dataformat.h);
    c. type environment size: a integer number which should agree with
       that used in the compiler;
    d. a needness vector; (bit vector?)
    e. universe index;
    f. fixity;
    g. precedence;



Search functions and hash function
===================================

Two sorts of search functions could be used in finding code, which
are sequential search and hash search.
C encoding of these functions have to be provided, the function
pointers to which together with corresponding search tables should be
recorded in relevant locations of the code area. For the hash search
function, a hash function has also to be provided.

The search functions used in Teyjus implementation can be found in
teyjus/source/loader/searchfns.c(h)
The hash function used in Teyjus implementation can be found in
teyjus/source/loader/hash.c(h)

A sequential search table should be allocated in contiguous locations.
Each entry in the table takes two words with the first as a
reference to the (run-time) constant table entry for a predicate constant,
and the second is the absolute address of the code location.

A hash table should be allocated in contiguous locations with the following
structure.
 ------------------------------------
 | number of entries     (1 word)   |
 ------------------------------------
 | entry 1               (1 word)   |
 ------------------------------------
 |  ...                             |
 ------------------------------------
 | entry n               (1 word)   |
 ------------------------------------
 | hash chains for relevant entries |
 ------------------------------------
Each entry above could be either NULL or a pointer referring to
a hash chain in the following space. Each hash chain is represented
as a linked list with 3 words: the first is a reference to a constant
table entry for the predicate; the second is an absolute address of
the code location; the third is a pointer referring to the next element
in the list.


Code Areas
==========

The code area of a module takes the following structure:
 ------------------------------------------------
 | implication table                            |
 ------------------------------------------------
 | hash table for constant indexing             |
 ------------------------------------------------
 | branch table for bound variable indexing     |
 ------------------------------------------------
 | import table (add code table) for this module|
 ------------------------------------------------
 | instructions                                 |
 ------------------------------------------------


Implication tables
---------------------
   An implication table should be maintained in contiguous locations
   with the following structure.

 1. A count of the number of predicates whose previous definitions
    might be extended in the antecedent of the implication goal.
    (1 word)

 2. Pointer to a function to be invoked for finding code relative to
    the antecedent of the implication. (hash/seq search function)
    (1 word)

 3. Number of entries in the table for the code defined in antecedent of
    implication.
    (1 word)

 4. References to the (run-time) constant symbol table entries corresponding
    to the predicate constants of the kind described in 1.
    (sequence of words of length determined by 1)

 5. A table of suitable form yielding the address of code. The entries
    will depend on the form of the search function (hash/seq).
    The structure of such a table is described in
    Search functions and hash function.


Hash tables for constant indexing
------------------------------------
   The structure of this table is described in Search functions
   and hash function.


Branch tables for bound variable indexing
--------------------------------------------
   The structure of this table is:
    -------------------------------
    | table size    (1 word )     |
    -------------------------------
    | entry 1       (2 words)     |
    -------------------------------
          ...
   where the first word of each entry is a de Bruijn index, and
   the second is an absolute address of the code location.


Import table (add code table) for this module
----------------------------------------------
   (Note that the address of this table for a top-level module has
    to be recorded in C's module table.)

   Maintained in contiguous location with the following structure:

   1. Field containing a count of the number of segments of code
    (1 word)

   2. Count of number of local constants
    (1 word)

   3. A count of the number of predicates whose previous definitions
      might be extended by the code in the module.
    (1 word)

   4. Pointer to a function to be invoked for finding code relative to
      the module. (hash/seq search function)
    (1 word)

   5. Number of entries in the table for the code defined in the module.
    (1 word)

   6. References to run-time constant tables for those representing
      the ``names'' of predicates of the kind described in 3.
    (sequence of words of length determined by 1)

   7. References to run-time constant tables for local constants.
      These are needed for initializing the universe index of local
      variables.
    (A sequence of words of length determined by 2)
    (If the count in 2 is zero, this section is empty.)

 8. A table of suitable form yielding the address of code. The entries
    will depend on the form of the search function. (hash/seq tables
    the structure of which is described in Search functions and hash
    function.)


Instructions
------------
