diff src/lisp-disunion.h @ 272:c5d627a313b1 r21-0b34

Import from CVS: tag r21-0b34
author cvs
date Mon, 13 Aug 2007 10:28:48 +0200
parents 11cf20601dec
children 5a79be0ef6a8
line wrap: on
line diff
--- a/src/lisp-disunion.h	Mon Aug 13 10:27:41 2007 +0200
+++ b/src/lisp-disunion.h	Mon Aug 13 10:28:48 2007 +0200
@@ -20,211 +20,143 @@
 
 /* Synched up with: FSF 19.30.  Split out from lisp.h. */
 /* This file has diverged greatly from FSF Emacs.  Syncing is no
-   longer desired or possible */
+   longer desirable or possible */
 
 /*
- * Format of a non-union-type Lisp Object
- *
- *   For the USE_MINIMAL_TAGBITS implementation:
- *
- *             3         2         1         0
- *       bit  10987654321098765432109876543210
- *            --------------------------------
- *            VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVTT
- *
- *   For the non-USE_MINIMAL_TAGBITS implementation:
- *
- *             3         2         1         0
- *       bit  10987654321098765432109876543210
- *            --------------------------------
- *            TTTMVVVVVVVVVVVVVVVVVVVVVVVVVVVV
- *
- *    V = value bits
- *    T = type bits
- *    M = mark bits
- *
- * For integral Lisp types, i.e. integers and characters, the value
- * bits are the Lisp object.
- *
- *     The object is obtained by masking off the type and mark
- *     bits.  In the USE_MINIMAL_TAGBITS implementation, bit 1 is
- *     used as a value bit by splitting the Lisp integer type into
- *     two subtypes, Lisp_Type_Int_Even and Lisp_Type_Int_Odd.  By
- *     this trickery we get 31 bits for integers instead of 30.
- *
- *     In the non-USE_MINIMAL_TAGBITS world, Lisp integers are 28
- *     bits, or more properly (LONGBITS - GCTYPEBITS - 1) bits.
- *
- * For non-integral types, the value bits of Lisp_Object contain a
- * pointer to structure containing the object.  The pointer is
- * obtained by masking off the type and mark bits.
- *
- *     In the USE_MINIMAL_TAGBITS implementation, all
- *     pointer-based types are coalesced under a single type called
- *     Lisp_Type_Record.  The type bits for this type are required
- *     by the implementation to be 00, just like the least
- *     significant bits of word-aligned struct pointers on 32-bit
- *     hardware.  Because of this, Lisp_Object pointers don't have
- *     to be masked and are full-sized.
- *
- *     In the non-USE_MINIMAL_TAGBITS implementation, the type and
- *     mark bits must be masked off and pointers are limited to 28
- *     bits (really LONGBITS - GCTYPEBITS - 1 bits).
- */
+ Format of a non-union-type Lisp Object
+
+   For the USE_MINIMAL_TAGBITS implementation:
+
+             3         2         1         0
+       bit  10987654321098765432109876543210
+            --------------------------------
+            VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVTT
+
+   Integers are treated specially, and look like this:
+
+             3         2         1         0
+       bit  10987654321098765432109876543210
+            --------------------------------
+            VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVT
+
+   For the non-USE_MINIMAL_TAGBITS implementation:
+
+             3         2         1         0
+       bit  10987654321098765432109876543210
+            --------------------------------
+            TTTMVVVVVVVVVVVVVVVVVVVVVVVVVVVV
+
+    V = value bits
+    T = type bits
+    M = mark bits
+
+ For integral Lisp types, i.e. integers and characters, the value
+ bits are the Lisp object.
+
+     The object is obtained by masking off the type and mark
+     bits.  In the USE_MINIMAL_TAGBITS implementation, bit 1 is
+     used as a value bit by splitting the Lisp integer type into
+     two subtypes, Lisp_Type_Int_Even and Lisp_Type_Int_Odd.  By
+     this trickery we get 31 bits for integers instead of 30.
+
+     In the non-USE_MINIMAL_TAGBITS world, Lisp integers are 28 bits,
+     or more properly (BITS_PER_EMACS_INT - GCTYPEBITS - 1) bits.
 
-#ifdef USE_MINIMAL_TAGBITS
-# define Qzero Lisp_Type_Int_Even
-# define VALMASK (((1UL << (VALBITS)) - 1L) << (GCTYPEBITS))
-#else
-# define Qzero Lisp_Type_Int
-# define VALMASK ((1L << (VALBITS)) - 1L)
-# define GCTYPEMASK ((1L << (GCTYPEBITS)) - 1L)
-#endif
+ For non-integral types, the value bits of a Lisp_Object contain
+ a pointer to a structure containing the object.  The pointer is
+ obtained by masking off the type and mark bits.
+
+     In the USE_MINIMAL_TAGBITS implementation, all
+     pointer-based types are coalesced under a single type called
+     Lisp_Type_Record.  The type bits for this type are required
+     by the implementation to be 00, just like the least
+     significant bits of word-aligned struct pointers on 32-bit
+     hardware.  Because of this, Lisp_Object pointers don't have
+     to be masked and are full-sized.
+
+     In the non-USE_MINIMAL_TAGBITS implementation, the type and
+     mark bits must be masked off and pointers are limited to 28
+     bits (really BITS_PER_EMACS_INT - GCTYPEBITS - 1 bits).
+
+ There are no mark bits in the USE_MINIMAL_TAGBITS implementation.
+ Integers and characters don't need to be marked.  All other types
+ are lrecord-based, which means they get marked by incrementing
+ their ->implementation pointer.
+
+ In the non-USE_MINIMAL_TAGBITS implementation, the markbit is stored
+ in the Lisp_Object itself.  It is stored in the middle so that the
+ type bits can be obtained by simply shifting them.
+
+ Outside of garbage collection, all mark bits are always zero.
+
+ Here is a brief description of the following macros:
+
+ XMARKBIT  Extract the mark bit (non-USE_MINIMAL_TAGBITS)
+ XMARK     Set the mark bit of this Lisp_Object (non-USE_MINIMAL_TAGBITS)
+ XUNMARK   Clear the mark bit of this Lisp_Object (non-USE_MINIMAL_TAGBITS)
+ XTYPE     The type bits of a Lisp_Object
+ XPNTRVAL  The value bits of a Lisp_Object storing a pointer
+ XCHARVAL  The value bits of a Lisp_Object storing a Emchar
+ XREALINT  The value bits of a Lisp_Object storing an integer, signed
+ XUINT     The value bits of a Lisp_Object storing an integer, unsigned
+ INTP      Non-zero if this Lisp_Object an integer?
+ Qzero     Lisp Integer 0
+ EQ        Non-zero if two Lisp_Objects are identical
+ GC_EQ     Version of EQ used during garbage collection
+*/
 
 typedef EMACS_INT Lisp_Object;
 
-#define Qnull_pointer 0
-
-/*
- * There are no mark bits in the USE_MINIMAL_TAGBITS implementation.
- * Integers and characters don't need to be marked.  All other types 
- * are lrecord-based, which means they get marked by incrementing
- * their ->implementation pointer.
- */
-#if GCMARKBITS > 0
- /*
-  * XMARKBIT accesses the markbit.  Markbits are used only in particular
-  * slots of particular structure types.  Other markbits are always
-  * zero.  Outside of garbage collection, all mark bits are always zero.
-  */
-# define MARKBIT (1UL << (VALBITS))
-# define XMARKBIT(a) ((a) & (MARKBIT))
-
-# define XMARK(a) ((void) ((a) |= (MARKBIT)))
-# define XUNMARK(a) ((void) ((a) &= (~(MARKBIT))))
-#else
-# define XUNMARK(a) DO_NOTHING
-#endif
-
-/*
- * Extract the type bits from a Lisp_Object.  If using USE_MINIMAL_TAGBITS, 
- * the least significant two bits are the type bits.  Otherwise the
- * most significant GCTYPEBITS bits are the type bits. 
- *
- * In the non-USE_MINIMAL_TAGBITS case, one needs to override this
- * if there must be high bits set in data space.  Masking the bits
- * (doing the result of the below & ((1 << (GCTYPEBITS)) - 1) would
- * work on all machines, but would penalize machines which don't
- * need it)
- */
-#ifdef USE_MINIMAL_TAGBITS
-# define XTYPE(a) ((enum Lisp_Type) (((EMACS_UINT)(a)) & ~(VALMASK)))
-#else
-# define XTYPE(a) ((enum Lisp_Type) (((EMACS_UINT)(a)) >> ((VALBITS) + 1)))
-#endif
-
-/*
- * This applies only to the non-USE_MINIMAL_TAGBITS Lisp_Object.
- *
- * In the past, during garbage collection, XGCTYPE needed to be used
- * for extracting types so that the mark bit was ignored.  XGCTYPE
- * did and exatr & operation to remove the mark bit.  But the mark
- * bit has been since moved so that the type bits could be extracted
- * with a single shift operation, making XGCTYPE no more expensive
- * than XTYPE, so the two operations are now equivalent.	
- */
-#ifndef XGCTYPE
-# define XGCTYPE(a) XTYPE(a)
-#endif
-
-#define EQ(x,y) ((x) == (y))
-
-#ifdef USE_MINIMAL_TAGBITS
-# define GC_EQ(x,y) EQ(x,y)
-#else
-# define GC_EQ(x,y) (XGCTYPE (x) == XGCTYPE (y) && XPNTR (x) == XPNTR (y))
-#endif
-
-/*
- * Extract the value of a Lisp_Object as a signed integer.
- *
- * The right shifts below are non-portable because >> is allowed to
- * sign extend or not signed extend signed integers depending on the
- * compiler implementors preference.  But this right-shifting of
- * signed ints has been here forever, so the apparently reality is
- * that all compilers of any consequence do sign extension, which is
- * what is needed here.
- */
-#ifndef XREALINT   /* Some machines need to do this differently.  */
-# ifdef USE_MINIMAL_TAGBITS
-#  define XREALINT(a) ((a) >> (LONGBITS-VALBITS-1))
-# else
-#  define XREALINT(a) (((a) << (LONGBITS-VALBITS)) >> (LONGBITS-VALBITS))
-# endif
-#endif
-
-/* Extract the value of a Lisp integer as an unsigned integer. */
-#ifdef USE_MINIMAL_TAGBITS
-# define XUINT(a) ((EMACS_UINT)(a) >> (LONGBITS-VALBITS-1))
-#else
-# define XUINT(a) XPNTRVAL(a)
-#endif
-
-/*
- * Extract the pointer value bits of a pointer based type.
- */
-#ifdef USE_MINIMAL_TAGBITS
-# define XPNTRVAL(a) (a) /* This depends on Lisp_Type_Record == 0 */
-# define XCHARVAL(a) ((a) >> (LONGBITS-VALBITS))
-#else
-# define XPNTRVAL(a) ((a) & VALMASK)
-# define XCHARVAL(a) XPNTRVAL(a)
-#endif
-
-#ifdef HAVE_SHM
-/* In this representation, data is found in two widely separated segments.  */
-extern int pure_size;
-#  define XPNTR(a) \
-  (XPNTRVAL (a) | (XPNTRVAL (a) > pure_size ? DATA_SEG_BITS : PURE_SEG_BITS))
-# else /* not HAVE_SHM */
-#  ifdef DATA_SEG_BITS
-/* This case is used for the rt-pc.
-   In the diffs I was given, it checked for ptr = 0
-   and did not adjust it in that case.
-   But I don't think that zero should ever be found
-   in a Lisp object whose data type says it points to something. */
-#   define XPNTR(a) (XPNTRVAL (a) | DATA_SEG_BITS)
-#  else
-#   define XPNTR(a) XPNTRVAL (a)
-#  endif
-#endif /* not HAVE_SHM */
-
 #ifdef USE_MINIMAL_TAGBITS
 
-/* XSETINT depends on Lisp_Type_Int_Even == 1 and Lisp_Type_Int_Odd == 3 */
-# define XSETINT(var, value) \
-  ((void) ((var) = ((value) << (LONGBITS-VALBITS-1)) + 1))
-# define XSETCHAR(var, value) \
-  ((void) ((var) = ((value) << (LONGBITS-VALBITS)) + Lisp_Type_Char))
-# define XSETOBJ(var, type_tag, value) \
-  ((void) ((var) = ((EMACS_UINT) (value))))
+# define XUNMARK(x) DO_NOTHING
+# define make_obj(vartype, x) ((Lisp_Object) (x))
+# define make_int(x) ((Lisp_Object) (((x) << INT_GCBITS) + 1))
+# define make_char(x) ((Lisp_Object) (((x) << GCBITS) + Lisp_Type_Char))
+# define VALMASK (((1UL << VALBITS) - 1UL) << GCTYPEBITS)
+# define XTYPE(x) ((enum Lisp_Type) (((EMACS_UINT)(x)) & ~VALMASK))
+# define XPNTRVAL(x) (x) /* This depends on Lisp_Type_Record == 0 */
+# define XCHARVAL(x) ((x) >> GCBITS)
+# define GC_EQ(x,y) EQ (x,y)
+# define XREALINT(x) ((x) >> INT_GCBITS)
+# define XUINT(x) ((EMACS_UINT)(x) >> INT_GCBITS)
+# define INTP(x) ((EMACS_UINT)(x) & 1)
+# define Qzero ((Lisp_Object) 1UL)
 
-#else
+#else /* !USE_MINIMAL_TAGBITS */
 
-# define XSETINT(a, b) XSETOBJ (a, Lisp_Type_Int, b)
-# define XSETCHAR(var, value) XSETOBJ (var, Lisp_Type_Char, value)
-# define XSETOBJ(var, type_tag, value)			\
-  ((void) ((var) = (((EMACS_UINT) (type_tag) << ((VALBITS) + 1))	\
-                   + ((EMACS_INT) (value) & VALMASK))))
-#endif
+# define MARKBIT (1UL << VALBITS)
+# define XMARKBIT(x) ((x) & MARKBIT)
+# define XMARK(x) ((void) ((x) |= MARKBIT))
+# define XUNMARK(x) ((void) ((x) &= ~MARKBIT))
+# define make_obj(vartype, value) \
+  ((Lisp_Object) (((EMACS_UINT) (vartype) << (VALBITS + GCMARKBITS)) \
+		  + ((EMACS_UINT) (value) & VALMASK)))
+# define make_int(value) make_obj (Lisp_Type_Int, value)
+# define make_char(value) make_obj (Lisp_Type_Char, value)
+# define VALMASK ((1UL << VALBITS) - 1UL)
+# define XTYPE(x) ((enum Lisp_Type) (((EMACS_UINT)(x)) >> (VALBITS + GCMARKBITS)))
+# define XPNTRVAL(x) ((x) & VALMASK)
+# define XCHARVAL(x) XPNTRVAL(x)
+# define GC_EQ(x,y) (((x) & ~MARKBIT) == ((y) & ~MARKBIT))
+# define XREALINT(x) (((x) << INT_GCBITS) >> INT_GCBITS)
+# define XUINT(x) ((EMACS_UINT) ((x) & VALMASK))
+# define INTP(x) (XTYPE (x) == Lisp_Type_Int)
+# define Qzero ((Lisp_Object) Lisp_Type_Int)
 
-/* Use this for turning a (void *) into a Lisp_Object, as when the
-  Lisp_Object is passed into a toolkit callback function */
+#endif /* !USE_MINIMAL_TAGBITS */
+
+#define Qnull_pointer 0
+#define XGCTYPE(x) XTYPE(x)
+#define EQ(x,y) ((x) == (y))
+#define XSETINT(var,  value) ((void) ((var) = make_int (value)))
+#define XSETCHAR(var, value) ((void) ((var) = make_char (value)))
+#define XSETOBJ(var, vartype, value) ((void) ((var) = make_obj (vartype, value)))
+
+/* Convert between a (void *) and a Lisp_Object, as when the
+   Lisp_Object is passed to a toolkit callback function */
 #define VOID_TO_LISP(larg,varg) ((void) ((larg) = ((Lisp_Object) (varg))))
 #define CVOID_TO_LISP VOID_TO_LISP
-
-/* Use this for turning a Lisp_Object into a (void *), as when the
-   Lisp_Object is passed into a toolkit callback function */
 #define LISP_TO_VOID(larg) ((void *) (larg))
 #define LISP_TO_CVOID(varg) ((CONST void *) (larg))