refactor tc7 and tc16 checks
[bpt/guile.git] / libguile / tags.h
index 6a6c352..f6d2f8d 100644 (file)
@@ -3,22 +3,23 @@
 #ifndef SCM_TAGS_H
 #define SCM_TAGS_H
 
-/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004
+/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2008,2009,2010,2011
  * Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
  *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
  */
 
 \f
 /* picks up scmconfig.h too */
 #include "libguile/__scm.h"
 
-#if HAVE_INTTYPES_H
-# include <inttypes.h>  /* for INTPTR_MAX and friends */
-#else
-# if HAVE_STDINT_H
-#  include <stdint.h>   /* for INTPTR_MAX and friends */
-# endif
-#endif
-
 \f
 
 /* In the beginning was the Word:
 /* For dealing with the bit level representation of scheme objects we define
  * scm_t_bits:
  */
-/* On Solaris 7 and 8, /usr/include/sys/int_limits.h defines
-   INTPTR_MAX and UINTPTR_MAX to empty, INTPTR_MIN is not defined.
-   To avoid uintptr_t and intptr_t in this case we require
-   UINTPTR_MAX-0 != 0 etc.  */
-#if SCM_SIZEOF_INTPTR_T != 0 && defined(INTPTR_MAX) && defined(INTPTR_MIN) \
-  && INTPTR_MAX-0 != 0 && INTPTR_MIN-0 != 0 \
-  && SCM_SIZEOF_UINTPTR_T != 0 && defined(UINTPTR_MAX) && UINTPTR_MAX-0 != 0
-
-typedef intptr_t scm_t_signed_bits;
-#define SCM_T_SIGNED_BITS_MAX INTPTR_MAX
-#define SCM_T_SIGNED_BITS_MIN INTPTR_MIN
-typedef uintptr_t scm_t_bits;
-#define SIZEOF_SCM_T_BITS SCM_SIZEOF_UINTPTR_T
-#define SCM_T_BITS_MAX UINTPTR_MAX
 
-#else
+typedef scm_t_intptr  scm_t_signed_bits;
+typedef scm_t_uintptr scm_t_bits;
 
-typedef signed long scm_t_signed_bits;
-#define SCM_T_SIGNED_BITS_MAX LONG_MAX
-#define SCM_T_SIGNED_BITS_MIN LONG_MIN
-typedef unsigned long scm_t_bits;
-#define SIZEOF_SCM_T_BITS SCM_SIZEOF_UNSIGNED_LONG
-#define SCM_T_BITS_MAX ULONG_MAX
+#define SCM_T_SIGNED_BITS_MAX SCM_T_INTPTR_MAX
+#define SCM_T_SIGNED_BITS_MIN SCM_T_INTPTR_MIN
+#define SCM_T_BITS_MAX        SCM_T_UINTPTR_MAX
 
-#endif
 
 /* But as external interface, we define SCM, which may, according to the
  * desired level of type checking, be defined in several ways:
  */
 #if (SCM_DEBUG_TYPING_STRICTNESS == 2)
-    typedef union { struct { scm_t_bits n; } n; } SCM;
-    static SCM scm_pack(scm_t_bits b) { SCM s; s.n.n = b; return s; }
+typedef union SCM { struct { scm_t_bits n; } n; } SCM;
 #   define SCM_UNPACK(x) ((x).n.n)
-#   define SCM_PACK(x) (scm_pack ((scm_t_bits) (x)))
+#   define SCM_PACK(x) ((SCM) { { (scm_t_bits) (x) } })
 #elif (SCM_DEBUG_TYPING_STRICTNESS == 1)
 /* This is the default, which provides an intermediate level of compile time
  * type checking while still resulting in very efficient code.
  */
-    typedef struct scm_unused_struct SCM;
+    typedef struct scm_unused_struct { char scm_unused_field; } *SCM;
 
 /*
   The 0?: constructions makes sure that the code is never executed,
   and that there is no performance hit.  However, the alternative is
   compiled, and does generate a warning when used with the wrong
   pointer type.
- */
+
+  The Tru64 and ia64-hp-hpux11.23 compilers fail on `case (0?0=0:x)'
+  statements, so for them type-checking is disabled.  */
+#if defined __DECC || defined __HP_cc
+#   define SCM_UNPACK(x) ((scm_t_bits) (x))
+#else
 #   define SCM_UNPACK(x) ((scm_t_bits) (0? (*(SCM*)0=(x)): x))
+#endif
 
 /*
   There is no typechecking on SCM_PACK, since all kinds of types
@@ -142,51 +123,57 @@ typedef unsigned long scm_t_bits;
 
 /* Representation of scheme objects:
  *
- * Guile's type system is designed to work on systems where scm_t_bits and SCM
- * variables consist of at least 32 bits.  The objects that a SCM variable can
- * represent belong to one of the following two major categories:
- *
- * - Immediates -- meaning that the SCM variable contains an entire Scheme
- *   object.  That means, all the object's data (including the type tagging
- *   information that is required to identify the object's type) must fit into
- *   32 bits.
- *
- * - Non-immediates -- meaning that the SCM variable holds a pointer into the
- *   heap of cells (see below).  On systems where a pointer needs more than 32
- *   bits this means that scm_t_bits and SCM variables need to be large enough
- *   to hold such pointers.  In contrast to immediates, the object's data of
- *   a non-immediate can consume arbitrary amounts of memory: The heap cell
- *   being pointed to consists of at least two scm_t_bits variables and thus
- *   can be used to hold pointers to malloc'ed memory of any size.
- *
- * The 'heap' is the memory area that is under control of Guile's garbage
- * collector.  It holds 'single-cells' or 'double-cells', which consist of
- * either two or four scm_t_bits variables, respectively.  It is guaranteed
- * that the address of a cell on the heap is 8-byte aligned.  That is, since
- * non-immediates hold a cell address, the three least significant bits of a
- * non-immediate can be used to store additional information.  The bits are
- * used to store information about the object's type and thus are called
- * tc3-bits, where tc stands for type-code.  
- *
- * For a given SCM value, the distinction whether it holds an immediate or
- * non-immediate object is based on the tc3-bits (see above) of its scm_t_bits
+ * Guile's type system is designed to work on systems where scm_t_bits
+ * and SCM variables consist of at least 32 bits.  The objects that a
+ * SCM variable can represent belong to one of the following two major
+ * categories:
+ *
+ * - Immediates -- meaning that the SCM variable contains an entire
+ *   Scheme object.  That means, all the object's data (including the
+ *   type tagging information that is required to identify the object's
+ *   type) must fit into 32 bits.
+ *
+ * - Heap objects -- meaning that the SCM variable holds a pointer into
+ *   the heap.  On systems where a pointer needs more than 32 bits this
+ *   means that scm_t_bits and SCM variables need to be large enough to
+ *   hold such pointers.  In contrast to immediates, the data associated
+ *   with a heap object can consume arbitrary amounts of memory.
+ *
+ * The 'heap' is the memory area that is under control of Guile's
+ * garbage collector.  It holds allocated memory of various sizes.  The
+ * impact on the runtime type system is that Guile needs to be able to
+ * determine the type of an object given the pointer.  Usually the way
+ * that Guile does this is by storing a "type tag" in the first word of
+ * the object.
+ *
+ * Some objects are common enough that they get special treatment.
+ * Since Guile guarantees that the address of a GC-allocated object on
+ * the heap is 8-byte aligned, Guile can play tricks with the lower 3
+ * bits.  That is, since heap objects encode a pointer to an
+ * 8-byte-aligned pointer, the three least significant bits of a SCM can
+ * be used to store additional information.  The bits are used to store
+ * information about the object's type and thus are called tc3-bits,
+ * where tc stands for type-code.
+ *
+ * For a given SCM value, the distinction whether it holds an immediate
+ * or heap object is based on the tc3-bits (see above) of its scm_t_bits
  * equivalent: If the tc3-bits equal #b000, then the SCM value holds a
- * non-immediate, and the scm_t_bits variable's value is just the pointer to
- * the heap cell.
+ * heap object, and the scm_t_bits variable's value is just the pointer
+ * to the heap cell.
  *
  * Summarized, the data of a scheme object that is represented by a SCM
- * variable consists of a) the SCM variable itself, b) in case of
- * non-immediates the data of the single-cell or double-cell the SCM object
- * points to, c) in case of non-immediates potentially additional data outside
- * of the heap (like for example malloc'ed data), and d) in case of
- * non-immediates potentially additional data inside of the heap, since data
- * stored in b) and c) may hold references to other cells.
+ * variable consists of a) the SCM variable itself, b) in case of heap
+ * objects memory that the SCM object points to, c) in case of heap
+ * objects potentially additional data outside of the heap (like for
+ * example malloc'ed data), and d) in case of heap objects potentially
+ * additional data inside of the heap, since data stored in b) and c)
+ * may hold references to other cells.
  *
  *
  * Immediates
  *
  * Operations on immediate objects can typically be processed faster than on
- * non-immediates.  The reason is that the object's data can be extracted
+ * heap objects.  The reason is that the object's data can be extracted
  * directly from the SCM variable (or rather a corresponding scm_t_bits
  * variable), instead of having to perform additional memory accesses to
  * obtain the object's data from the heap.  In order to get the best possible
@@ -220,69 +207,56 @@ typedef unsigned long scm_t_bits;
  * special objects listed above.
  *
  *
- * Non-Immediates
- *
- * All object types not mentioned above in the list of immedate objects are
- * represented as non-immediates.  Whether a non-immediate scheme object is
- * represented by a single-cell or a double-cell depends on the object's type,
- * namely on the set of attributes that have to be stored with objects of that
- * type.  Every non-immediate type is allowed to define its own layout and
- * interpretation of the data stored in its cell (with some restrictions, see
- * below).
- *
- * One of the design goals of guile's type system is to make it possible to
- * store a scheme pair with as little memory usage as possible.  The minimum
- * amount of memory that is required to store two scheme objects (car and cdr
- * of a pair) is the amount of memory required by two scm_t_bits or SCM
- * variables.  Therefore pairs in guile are stored in single-cells.
- *
- * Another design goal for the type system is to store procedure objects
- * created by lambda expresssions (closures) and class instances (goops
- * objects) with as little memory usage as possible.  Closures are represented
- * by a reference to the function code and a reference to the closure's
- * environment.  Class instances are represented by a reference to the
- * instance's class definition and a reference to the instance's data.  Thus,
- * closures as well as class instances also can be stored in single-cells.
- *
- * Certain other non-immediate types also store their data in single-cells.
- * By design decision, the heap is split into areas for single-cells and
- * double-cells, but not into areas for single-cells-holding-pairs and areas
- * for single-cells-holding-non-pairs.  Any single-cell on the heap therefore
- * can hold pairs (consisting of two scm_t_bits variables representing two
- * scheme objects - the car and cdr of the pair) and non-pairs (consisting of
- * two scm_t_bits variables that hold bit patterns as defined by the layout of
- * the corresponding object's type).
+ * Heap Objects
+ *
+ * All object types not mentioned above in the list of immedate objects
+ * are represented as heap objects.  The amount of memory referenced by
+ * a heap object depends on the object's type, namely on the set of
+ * attributes that have to be stored with objects of that type.  Every
+ * heap object type is allowed to define its own layout and
+ * interpretation of the data stored in its cell (with some
+ * restrictions, see below).
+ *
+ * One of the design goals of guile's type system is to make it possible
+ * to store a scheme pair with as little memory usage as possible.  The
+ * minimum amount of memory that is required to store two scheme objects
+ * (car and cdr of a pair) is the amount of memory required by two
+ * scm_t_bits or SCM variables.  Therefore pairs in guile are stored in
+ * two words, and are tagged with a bit pattern in the SCM value, not
+ * with a type tag on the heap.
  *
  *
  * Garbage collection
  *
- * During garbage collection, unreachable cells on the heap will be freed.
- * That is, the garbage collector will detect cells which have no SCM variable
- * pointing towards them.  In order to properly release all memory belonging
- * to the object to which a cell belongs, the gc needs to be able to interpret
- * the cell contents in the correct way.  That means that the gc needs to be
- * able to determine the object type associated with a cell only from the cell
- * itself.
- *
- * Consequently, if the gc detects an unreachable single-cell, those two
- * scm_t_bits variables must provide enough information to determine whether
- * they belong to a pair (i. e. both scm_t_bits variables represent valid
- * scheme objects), to a closure, a class instance or if they belong to any
- * other non-immediate.  Guile's type system is designed to make it possible
- * to determine a the type to which a cell belongs in the majority of cases
- * from the cell's first scm_t_bits variable.  (Given a SCM variable X holding
- * a non-immediate object, the macro SCM_CELL_TYPE(X) will deliver the
- * corresponding cell's first scm_t_bits variable.)
- *
- * If the cell holds a scheme pair, then we already know that the first
- * scm_t_bits variable of the cell will hold a scheme object with one of the
- * following tc3-codes: #b000 (non-immediate), #b010 (small integer), #b100
- * (small integer), #b110 (non-integer immediate).  All these tc3-codes have
- * in common, that their least significant bit is #b0.  This fact is used by
- * the garbage collector to identify cells that hold pairs.  The remaining
- * tc3-codes are assigned as follows: #b001 (class instance or, more
- * precisely, a struct, of which a class instance is a special case), #b011
- * (closure), #b101/#b111 (all remaining non-immediate types).
+ * During garbage collection, unreachable objects on the heap will be
+ * freed.  To determine the set of reachable objects, by default, the GC
+ * just traces all words in all heap objects.  It is possible to
+ * register custom tracing ("marking") procedures.
+ *
+ * If an object is unreachable, by default, the GC just notes this fact
+ * and moves on.  Later allocations will clear out the memory associated
+ * with the object, and re-use it.  It is possible to register custom
+ * finalizers, however.
+ *
+ *
+ * Run-time type introspection
+ *
+ * Guile's type system is designed to make it possible to determine a
+ * the type of a heap object from the object's first scm_t_bits
+ * variable.  (Given a SCM variable X holding a heap object, the macro
+ * SCM_CELL_TYPE(X) will deliver the corresponding object's first
+ * scm_t_bits variable.)
+ *
+ * If the object holds a scheme pair, then we already know that the
+ * first scm_t_bits variable of the cell will hold a scheme object with
+ * one of the following tc3-codes: #b000 (heap object), #b010 (small
+ * integer), #b110 (small integer), #b100 (non-integer immediate).  All
+ * these tc3-codes have in common, that their least significant bit is
+ * #b0.  This fact is used by the garbage collector to identify cells
+ * that hold pairs.  The remaining tc3-codes are assigned as follows:
+ * #b001 (class instance or, more precisely, a struct, of which a class
+ * instance is a special case), #b011 (closure), #b101/#b111 (all
+ * remaining heap object types).
  *
  *
  * Summary of type codes of scheme objects (SCM variables)
@@ -293,7 +267,7 @@ typedef unsigned long scm_t_bits;
  * of the SCM variables corresponding scm_t_bits value.
  *
  * Note that (as has been explained above) tc1==1 can only occur in the first
- * scm_t_bits variable of a cell belonging to a non-immediate object that is
+ * scm_t_bits variable of a cell belonging to a heap object that is
  * not a pair.  For an explanation of the tc tags with tc1==1, see the next
  * section with the summary of the type codes on the heap.
  *
@@ -302,13 +276,13 @@ typedef unsigned long scm_t_bits;
  *  (1:  This can never be the case for a scheme object.)
  *
  * tc2:
- *   00:  Either a non-immediate or some non-integer immediate
+ *   00:  Either a heap object or some non-integer immediate
  *  (01:  This can never be the case for a scheme object.)
  *   10:  Small integer
  *  (11:  This can never be the case for a scheme object.)
  *
  * tc3:
- *   000:  a non-immediate object (pair, closure, class instance etc.)
+ *   000:  a heap object (pair, closure, class instance etc.)
  *  (001:  This can never be the case for a scheme object.)
  *   010:  an even small integer (least significant bit is 0).
  *  (011:  This can never be the case for a scheme object.)
@@ -317,16 +291,16 @@ typedef unsigned long scm_t_bits;
  *   110:  an odd small integer (least significant bit is 1).
  *  (111:  This can never be the case for a scheme object.)
  *
- * The remaining bits of the non-immediate objects form the pointer to the
- * heap cell.  The remaining bits of the small integers form the integer's
+ * The remaining bits of the heap objects form the pointer to the heap
+ * cell.  The remaining bits of the small integers form the integer's
  * value and sign.  Thus, the only scheme objects for which a further
  * subdivision is of interest are the ones with tc3==100.
  *
  * tc8 (for objects with tc3==100):
  *   00000-100:  special objects ('flags')
  *   00001-100:  characters
- *   00010-100:  evaluator byte codes ('isyms')
- *   00011-100:  evaluator byte codes ('ilocs')
+ *   00010-100:  unused
+ *   00011-100:  unused
  *
  *
  * Summary of type codes on the heap
@@ -340,19 +314,19 @@ typedef unsigned long scm_t_bits;
  *
  * tc2:
  *   00:  the cell belongs to a pair with no short integer in its car.
- *   01:  the cell belongs to a non-pair (struct or some other non-immediate).
+ *   01:  the cell belongs to a non-pair (struct or some other heap object).
  *   10:  the cell belongs to a pair with a short integer in its car.
- *   11:  the cell belongs to a non-pair (closure or some other non-immediate).
+ *   11:  the cell belongs to a non-pair (closure or some other heap object).
  *
  * tc3:
- *   000:  the cell belongs to a pair with a non-immediate in its car.
+ *   000:  the cell belongs to a pair with a heap object in its car.
  *   001:  the cell belongs to a struct
  *   010:  the cell belongs to a pair with an even short integer in its car.
  *   011:  the cell belongs to a closure
  *   100:  the cell belongs to a pair with a non-integer immediate in its car.
- *   101:  the cell belongs to some other non-immediate.
+ *   101:  the cell belongs to some other heap object.
  *   110:  the cell belongs to a pair with an odd short integer in its car.
- *   111:  the cell belongs to some other non-immediate.
+ *   111:  the cell belongs to some other heap object.
  *
  * tc7 (for tc3==1x1):
  *   See below for the list of types.  Note the special case of scm_tc7_vector
@@ -367,15 +341,11 @@ typedef unsigned long scm_t_bits;
  * tc16 (for tc7==scm_tc7_smob):
  *   The largest part of the space of smob types is not subdivided in a
  *   predefined way, since smobs can be added arbitrarily by user C code.
- *   However, while Guile also defines a number of smob types throughout,
- *   there is one smob type, namely scm_tc_free_cell, for which Guile assumes
- *   that it is declared first and thus gets a known-in-advance tc16-code.
- *   The reason of requiring a fixed tc16-code for this type is performance.
  */
 
 \f
 
-/* Checking if a SCM variable holds an immediate or a non-immediate object:
+/* Checking if a SCM variable holds an immediate or a heap object:
  * This check can either be performed by checking for tc3==000 or tc3==00x,
  * since for a SCM variable it is known that tc1==0.  */
 #define SCM_IMP(x)             (6 & SCM_UNPACK (x))
@@ -387,7 +357,7 @@ typedef unsigned long scm_t_bits;
 
 /* Checking if a SCM variable holds a pair (for historical reasons, in Guile
  * also known as a cons-cell): This is done by first checking that the SCM
- * variable holds a non-immediate, and second, by checking that tc1==0 holds
+ * variable holds a heap object, and second, by checking that tc1==0 holds
  * for the SCM_CELL_TYPE of the SCM variable.  
 */
 
@@ -408,7 +378,7 @@ typedef unsigned long scm_t_bits;
 #define scm_tc3_cons            0
 #define scm_tc3_struct          1
 #define scm_tc3_int_1           (scm_tc2_int + 0)
-#define scm_tc3_closure                 3
+#define scm_tc3_unused          3
 #define scm_tc3_imm24           4
 #define scm_tc3_tc7_1           5
 #define scm_tc3_int_2           (scm_tc2_int + 4)
@@ -420,6 +390,10 @@ typedef unsigned long scm_t_bits;
 #define SCM_ITAG7(x)           (127 & SCM_UNPACK (x))
 #define SCM_TYP7(x)            (0x7f &        SCM_CELL_TYPE (x))
 #define SCM_TYP7S(x)           ((0x7f & ~2) & SCM_CELL_TYPE (x))
+#define SCM_HAS_HEAP_TYPE(x, type, tag)                         \
+  (SCM_NIMP (x) && type (x) == (tag))
+#define SCM_HAS_TYP7(x, tag)    (SCM_HAS_HEAP_TYPE (x, SCM_TYP7, tag))
+#define SCM_HAS_TYP7S(x, tag)   (SCM_HAS_HEAP_TYPE (x, SCM_TYP7S, tag))
 
 #define scm_tc7_symbol         5
 #define scm_tc7_variable        7
@@ -431,36 +405,32 @@ typedef unsigned long scm_t_bits;
 #define scm_tc7_string         21
 #define scm_tc7_number         23
 #define scm_tc7_stringbuf       39
-
-/* Many of the following should be turned
- * into structs or smobs.  We need back some
- * of these 7 bit tags!  */
-
-#define scm_tc7_pws            31
-
-#define scm_tc7_unused_1        29
-#define scm_tc7_unused_2       37
-#define scm_tc7_unused_3       45
-#define scm_tc7_unused_4       47
-#define scm_tc7_unused_5       53
-#define scm_tc7_unused_6       55
-#define scm_tc7_unused_7       71
-#define scm_tc7_unused_8       77
-#define scm_tc7_unused_9       79
-
-#define scm_tc7_dsubr          61
-#define scm_tc7_cclo           63
-#define scm_tc7_rpsubr         69
-#define scm_tc7_subr_0         85
-#define scm_tc7_subr_1         87
-#define scm_tc7_cxr            93
-#define scm_tc7_subr_3         95
-#define scm_tc7_subr_2         101
-#define scm_tc7_asubr          103
-#define scm_tc7_subr_1o                109
-#define scm_tc7_subr_2o                111
-#define scm_tc7_lsubr_2                117
-#define scm_tc7_lsubr          119
+#define scm_tc7_bytevector     77
+
+#define scm_tc7_pointer                31
+#define scm_tc7_hashtable      29
+#define scm_tc7_fluid          37
+#define scm_tc7_dynamic_state  45
+
+#define scm_tc7_frame          47
+#define scm_tc7_objcode                53
+#define scm_tc7_vm             55
+#define scm_tc7_vm_cont                71
+
+#define scm_tc7_prompt         61
+#define scm_tc7_with_fluids    63
+#define scm_tc7_unused_19      69
+#define scm_tc7_program                79
+#define scm_tc7_weak_set       85
+#define scm_tc7_weak_table     87
+#define scm_tc7_unused_20      93
+#define scm_tc7_unused_11      95
+#define scm_tc7_unused_12      101
+#define scm_tc7_unused_18      103
+#define scm_tc7_unused_13      109
+#define scm_tc7_unused_14      111
+#define scm_tc7_unused_15      117
+#define scm_tc7_unused_16      119
 
 /* There are 256 port subtypes.  */
 #define scm_tc7_port           125
@@ -474,15 +444,10 @@ typedef unsigned long scm_t_bits;
 
 /* Definitions for tc16: */
 #define SCM_TYP16(x)           (0xffff & SCM_CELL_TYPE (x))
-#define SCM_TYP16_PREDICATE(tag, x) (!SCM_IMP (x) && SCM_TYP16 (x) == (tag))
+#define SCM_HAS_TYP16(x, tag)   (SCM_HAS_HEAP_TYPE (x, SCM_TYP16, tag))
+#define SCM_TYP16_PREDICATE(tag, x) (SCM_HAS_TYP16 (x, tag))
 
 
-/* Here is the first smob subtype.  */
-
-/* scm_tc_free_cell is the 0th smob type.  We place this in free cells to tell
- * the conservative marker not to trace it.  */
-#define scm_tc_free_cell       (scm_tc7_smob + 0 * 256L)
-
 \f
 
 /* {Immediate Values}
@@ -492,12 +457,13 @@ enum scm_tc8_tags
 {
   scm_tc8_flag = scm_tc3_imm24 + 0x00,  /* special objects ('flags') */
   scm_tc8_char = scm_tc3_imm24 + 0x08,  /* characters */
-  scm_tc8_isym = scm_tc3_imm24 + 0x10,  /* evaluator byte codes ('isyms') */
-  scm_tc8_iloc = scm_tc3_imm24 + 0x18   /* evaluator byte codes ('ilocs') */
+  scm_tc8_unused_0 = scm_tc3_imm24 + 0x10,
+  scm_tc8_unused_1 = scm_tc3_imm24 + 0x18
 };
 
 #define SCM_ITAG8(X)           (SCM_UNPACK (X) & 0xff)
-#define SCM_MAKE_ITAG8(X, TAG) SCM_PACK (((X) << 8) + TAG)
+#define SCM_MAKE_ITAG8_BITS(X, TAG) (((X) << 8) + TAG)
+#define SCM_MAKE_ITAG8(X, TAG) (SCM_PACK (SCM_MAKE_ITAG8_BITS (X, TAG)))
 #define SCM_ITAG8_DATA(X)      (SCM_UNPACK (X) >> 8)
 
 \f
@@ -506,15 +472,69 @@ enum scm_tc8_tags
  * declarations in print.c: iflagnames.  */
 
 #define SCM_IFLAGP(n)    (SCM_ITAG8 (n) == scm_tc8_flag)
-#define SCM_MAKIFLAG(n)  SCM_MAKE_ITAG8 ((n), scm_tc8_flag)
+#define SCM_MAKIFLAG_BITS(n)  (SCM_MAKE_ITAG8_BITS ((n), scm_tc8_flag))
 #define SCM_IFLAGNUM(n)  (SCM_ITAG8_DATA (n))
 
-#define SCM_BOOL_F             SCM_MAKIFLAG (0)
-#define SCM_BOOL_T             SCM_MAKIFLAG (1)
-#define SCM_UNDEFINED          SCM_MAKIFLAG (2)
-#define SCM_EOF_VAL            SCM_MAKIFLAG (3)
-#define SCM_EOL                        SCM_MAKIFLAG (4)
-#define SCM_UNSPECIFIED                SCM_MAKIFLAG (5)
+/*
+ * IMPORTANT NOTE regarding IFLAG numbering!!!
+ *
+ * Several macros depend upon careful IFLAG numbering of SCM_BOOL_F,
+ * SCM_BOOL_T, SCM_ELISP_NIL, SCM_EOL, and the two SCM_XXX_*_DONT_USE
+ * constants.  In particular:
+ *
+ * - SCM_BOOL_F and SCM_BOOL_T must differ in exactly one bit position.
+ *   (used to implement scm_is_bool_and_not_nil, aka scm_is_bool)
+ *
+ * - SCM_ELISP_NIL and SCM_BOOL_F must differ in exactly one bit position.
+ *   (used to implement scm_is_false_or_nil and
+ *    scm_is_true_and_not_nil)
+ *
+ * - SCM_ELISP_NIL and SCM_EOL must differ in exactly one bit position.
+ *   (used to implement scm_is_null_or_nil)
+ *
+ * - SCM_ELISP_NIL, SCM_BOOL_F, SCM_EOL, SCM_XXX_ANOTHER_LISP_FALSE_DONT_USE
+ *   must all be equal except for two bit positions.
+ *   (used to implement scm_is_lisp_false)
+ *
+ * - SCM_ELISP_NIL, SCM_BOOL_F, SCM_BOOL_T, SCM_XXX_ANOTHER_BOOLEAN_DONT_USE_0
+ *   must all be equal except for two bit positions.
+ *   (used to implement scm_is_bool_or_nil)
+ *
+ * These properties allow the aforementioned macros to be implemented
+ * by bitwise ANDing with a mask and then comparing with a constant,
+ * using as a common basis the macro SCM_MATCHES_BITS_IN_COMMON,
+ * defined below.  The properties are checked at compile-time using
+ * `verify' macros near the top of boolean.c and pairs.c.
+ */
+#define SCM_BOOL_F_BITS                SCM_MAKIFLAG_BITS (0)
+#define SCM_ELISP_NIL_BITS     SCM_MAKIFLAG_BITS (1)
+
+#define SCM_BOOL_F             SCM_PACK (SCM_BOOL_F_BITS)
+#define SCM_ELISP_NIL          SCM_PACK (SCM_ELISP_NIL_BITS)
+
+#ifdef BUILDING_LIBGUILE
+#define SCM_XXX_ANOTHER_LISP_FALSE_DONT_USE    SCM_MAKIFLAG_BITS (2)
+#endif
+
+#define SCM_EOL_BITS           SCM_MAKIFLAG_BITS (3)
+#define SCM_BOOL_T_BITS        SCM_MAKIFLAG_BITS (4)
+
+#define SCM_EOL                        SCM_PACK (SCM_EOL_BITS)
+#define SCM_BOOL_T             SCM_PACK (SCM_BOOL_T_BITS)
+
+#ifdef BUILDING_LIBGUILE
+#define SCM_XXX_ANOTHER_BOOLEAN_DONT_USE_0     SCM_MAKIFLAG_BITS (5)
+#define SCM_XXX_ANOTHER_BOOLEAN_DONT_USE_1     SCM_MAKIFLAG_BITS (6)
+#define SCM_XXX_ANOTHER_BOOLEAN_DONT_USE_2     SCM_MAKIFLAG_BITS (7)
+#endif
+
+#define SCM_UNSPECIFIED_BITS   SCM_MAKIFLAG_BITS (8)
+#define SCM_UNDEFINED_BITS     SCM_MAKIFLAG_BITS (9)
+#define SCM_EOF_VAL_BITS       SCM_MAKIFLAG_BITS (10)
+
+#define SCM_UNSPECIFIED                SCM_PACK (SCM_UNSPECIFIED_BITS)
+#define SCM_UNDEFINED          SCM_PACK (SCM_UNDEFINED_BITS)
+#define SCM_EOF_VAL            SCM_PACK (SCM_EOF_VAL_BITS)
 
 /* When a variable is unbound this is marked by the SCM_UNDEFINED
  * value.  The following is an unbound value which can be handled on
@@ -524,51 +544,53 @@ enum scm_tc8_tags
  * the code which handles this value in C so that SCM_UNDEFINED can be
  * used instead.  It is not ideal to let this kind of unique and
  * strange values loose on the Scheme level.  */
-#define SCM_UNBOUND            SCM_MAKIFLAG (6)
-
-/* The Elisp nil value.  */
-#define SCM_ELISP_NIL          SCM_MAKIFLAG (7)
-
+#define SCM_UNBOUND_BITS       SCM_MAKIFLAG_BITS (11)
+#define SCM_UNBOUND            SCM_PACK (SCM_UNBOUND_BITS)
 
 #define SCM_UNBNDP(x)          (scm_is_eq ((x), SCM_UNDEFINED))
 
-\f
-
-/* Evaluator byte codes ('immediate symbols').  These constants are used only
- * in eval but their values have to be allocated here.  The indices of the
- * SCM_IM_ symbols must agree with the declarations in print.c:
- * scm_isymnames.  */
-
-#define SCM_ISYMP(n)           (SCM_ITAG8 (n) == scm_tc8_isym)
-#define SCM_MAKISYM(n)                 SCM_MAKE_ITAG8 ((n), scm_tc8_isym)
-
-#define SCM_IM_AND              SCM_MAKISYM (0)
-#define SCM_IM_BEGIN            SCM_MAKISYM (1)
-#define SCM_IM_CASE             SCM_MAKISYM (2)
-#define SCM_IM_COND             SCM_MAKISYM (3)
-#define SCM_IM_DO               SCM_MAKISYM (4)
-#define SCM_IM_IF               SCM_MAKISYM (5)
-#define SCM_IM_LAMBDA           SCM_MAKISYM (6)
-#define SCM_IM_LET              SCM_MAKISYM (7)
-#define SCM_IM_LETSTAR          SCM_MAKISYM (8)
-#define SCM_IM_LETREC           SCM_MAKISYM (9)
-#define SCM_IM_OR               SCM_MAKISYM (10)
-#define SCM_IM_QUOTE            SCM_MAKISYM (11)
-#define SCM_IM_SET_X            SCM_MAKISYM (12)
-#define SCM_IM_DEFINE           SCM_MAKISYM (13)
-#define SCM_IM_APPLY           SCM_MAKISYM (14)
-#define SCM_IM_CONT            SCM_MAKISYM (15)
-#define SCM_IM_DISPATCH                SCM_MAKISYM (16)
-#define SCM_IM_SLOT_REF                SCM_MAKISYM (17)
-#define SCM_IM_SLOT_SET_X      SCM_MAKISYM (18)
-#define SCM_IM_DELAY           SCM_MAKISYM (19)
-#define SCM_IM_FUTURE          SCM_MAKISYM (20)
-#define SCM_IM_CALL_WITH_VALUES SCM_MAKISYM (21)
-#define SCM_IM_ELSE             SCM_MAKISYM (22)
-#define SCM_IM_ARROW            SCM_MAKISYM (23)
-#define SCM_IM_NIL_COND         SCM_MAKISYM (24)  /* Multi-language support */
-#define SCM_IM_BIND             SCM_MAKISYM (25)  /* Multi-language support */
+/*
+ * SCM_MATCHES_BITS_IN_COMMON(x,a,b) returns 1 if and only if x
+ * matches both a and b in every bit position where a and b are equal;
+ * otherwise it returns 0.  Bit positions where a and b differ are
+ * ignored.
+ *
+ * This is used to efficiently compare against two values which differ
+ * in exactly one bit position, or against four values which differ in
+ * exactly two bit positions.  It is the basis for the following
+ * macros:
+ *
+ *   scm_is_null_or_nil,
+ *   scm_is_false_or_nil,
+ *   scm_is_true_and_not_nil,
+ *   scm_is_lisp_false,
+ *   scm_is_lisp_true,
+ *   scm_is_bool_and_not_nil (aka scm_is_bool)
+ *   scm_is_bool_or_nil.
+ */
+#define SCM_MATCHES_BITS_IN_COMMON(x,a,b)                              \
+  ((SCM_UNPACK(x) & ~(SCM_UNPACK(a) ^ SCM_UNPACK(b))) ==               \
+   (SCM_UNPACK(a) & SCM_UNPACK(b)))
 
+/*
+ * These macros are used for compile-time verification that the
+ * constants have the properties needed for the above macro to work
+ * properly.
+ */
+#ifdef BUILDING_LIBGUILE
+#define SCM_WITH_LEAST_SIGNIFICANT_1_BIT_CLEARED(x)  ((x) & ((x)-1))
+#define SCM_HAS_EXACTLY_ONE_BIT_SET(x)                                 \
+  ((x) != 0 && SCM_WITH_LEAST_SIGNIFICANT_1_BIT_CLEARED (x) == 0)
+#define SCM_HAS_EXACTLY_TWO_BITS_SET(x)                                        \
+  (SCM_HAS_EXACTLY_ONE_BIT_SET (SCM_WITH_LEAST_SIGNIFICANT_1_BIT_CLEARED (x)))
+
+#define SCM_BITS_DIFFER_IN_EXACTLY_ONE_BIT_POSITION(a,b)               \
+  (SCM_HAS_EXACTLY_ONE_BIT_SET ((a) ^ (b)))
+#define SCM_BITS_DIFFER_IN_EXACTLY_TWO_BIT_POSITIONS(a,b,c,d)          \
+  (SCM_HAS_EXACTLY_TWO_BITS_SET (((a) ^ (b)) |                          \
+                                 ((b) ^ (c)) |                          \
+                                 ((c) ^ (d))))
+#endif /* BUILDING_LIBGUILE */
 \f
 
 /* Dispatching aids:
@@ -597,7 +619,7 @@ enum scm_tc8_tags
   case scm_tc2_int + 112: case scm_tc2_int + 116: case scm_tc3_imm24 + 112:\
   case scm_tc2_int + 120: case scm_tc2_int + 124: case scm_tc3_imm24 + 120
 
-/* For cons pairs with non-immediate values in the SCM_CAR
+/* For cons pairs with heap objects in the SCM_CAR
  */
 #define scm_tcs_cons_nimcar \
        scm_tc3_cons + 0:\
@@ -637,51 +659,8 @@ enum scm_tc8_tags
   case scm_tc3_struct + 112:\
   case scm_tc3_struct + 120
 
-/* For closures
- */
-#define scm_tcs_closures \
-       scm_tc3_closure + 0:\
-  case scm_tc3_closure + 8:\
-  case scm_tc3_closure + 16:\
-  case scm_tc3_closure + 24:\
-  case scm_tc3_closure + 32:\
-  case scm_tc3_closure + 40:\
-  case scm_tc3_closure + 48:\
-  case scm_tc3_closure + 56:\
-  case scm_tc3_closure + 64:\
-  case scm_tc3_closure + 72:\
-  case scm_tc3_closure + 80:\
-  case scm_tc3_closure + 88:\
-  case scm_tc3_closure + 96:\
-  case scm_tc3_closure + 104:\
-  case scm_tc3_closure + 112:\
-  case scm_tc3_closure + 120
-
-/* For subrs
- */
-#define scm_tcs_subrs \
-       scm_tc7_asubr:\
-  case scm_tc7_subr_0:\
-  case scm_tc7_subr_1:\
-  case scm_tc7_dsubr:\
-  case scm_tc7_cxr:\
-  case scm_tc7_subr_3:\
-  case scm_tc7_subr_2:\
-  case scm_tc7_rpsubr:\
-  case scm_tc7_subr_1o:\
-  case scm_tc7_subr_2o:\
-  case scm_tc7_lsubr_2:\
-  case scm_tc7_lsubr
-
 \f
 
-#if (SCM_ENABLE_DEPRECATED == 1)
-
-#define SCM_CELLP(x)   (((sizeof (scm_t_cell) - 1) & SCM_UNPACK (x)) == 0)
-#define SCM_NCELLP(x)  (!SCM_CELLP (x))
-
-#endif
-
 #endif  /* SCM_TAGS_H */
 
 /*