(U+6215): Apply new conventions for glyph granularity.
[chise/xemacs-chise.git.1] / src / lisp-disunion.h
index f2c321b..47c3626 100644 (file)
@@ -38,28 +38,30 @@ Boston, MA 02111-1307, USA.  */
             VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVT
 
  For integral Lisp types, i.e. integers and characters, the value
- bits are the Lisp object.
+ bits are the Lisp object.  Some people call such Lisp_Objects "immediate".
 
-     The object is obtained by masking off the type and mark bits.
+ The object is obtained by masking off the type bits.
      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.
+ into two subtypes, Lisp_Type_Int_Even and Lisp_Type_Int_Odd.
+ By this trickery we get 31 bits for integers instead of 30.
 
  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.
 
      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.
+ 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.  This requires that
+ all structs implementing Lisp_Objects have an alignment of at least 4
+ bytes.  Because of this, Lisp_Object pointers don't have to be masked
+ and are full-sized.
 
- There are no mark bits.
- 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.
+ There are no mark bits in the Lisp_Object itself (there used to be).
+
+ Integers and characters don't need to be marked.  All other types are
+ lrecord-based, which means they get marked by setting the mark bit in
+ the struct lrecord_header.
 
  Here is a brief description of the following macros:
 
@@ -68,40 +70,56 @@ Boston, MA 02111-1307, USA.  */
  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?
+ INTP      Non-zero if this Lisp_Object is an integer
  Qzero     Lisp Integer 0
- EQ        Non-zero if two Lisp_Objects are identical
- GC_EQ Version of EQ used during garbage collection */
+ EQ        Non-zero if two Lisp_Objects are identical, not merely equal. */
+
 
 typedef EMACS_INT Lisp_Object;
 
 #define Lisp_Type_Int_Bit (Lisp_Type_Int_Even & Lisp_Type_Int_Odd)
-#define make_obj(vartype, x) ((Lisp_Object) (x))
-#define make_int(x) ((Lisp_Object) (((x) << INT_GCBITS) | Lisp_Type_Int_Bit))
-#define make_char(x) ((Lisp_Object) (((x) << GCBITS) | Lisp_Type_Char))
+#define wrap_object(ptr) ((Lisp_Object) (ptr))
+#define make_int(x) ((Lisp_Object) (((EMACS_INT)(x) << INT_GCBITS) | Lisp_Type_Int_Bit))
+#define make_char(x) ((Lisp_Object) (((EMACS_INT)(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)
+#if defined(UTF2000) && (SIZEOF_EMACS_INT == 4)
+INLINE_HEADER Emchar XCHARVAL (Lisp_Object chr);
+INLINE_HEADER Emchar
+XCHARVAL (Lisp_Object chr)
+{
+  int code = (EMACS_UINT)(chr) >> GCBITS;
+
+  if (code & 0x20000000)
+    return code | 0x40000000;
+  else
+    return code;
+}
+#else
+#define XCHARVAL(x) ((Emchar)((EMACS_UINT)(x) >> GCBITS))
+#endif
 #define XREALINT(x) ((x) >> INT_GCBITS)
 #define XUINT(x) ((EMACS_UINT)(x) >> INT_GCBITS)
 #define INTP(x) ((EMACS_UINT)(x) & Lisp_Type_Int_Bit)
+#define INT_PLUS(x,y)  ((x)+(y)-Lisp_Type_Int_Bit)
+#define INT_MINUS(x,y) ((x)-(y)+Lisp_Type_Int_Bit)
+#define INT_PLUS1(x)   INT_PLUS  (x, make_int (1))
+#define INT_MINUS1(x)  INT_MINUS (x, make_int (1))
 
 #define Qzero make_int (0)
 #define Qnull_pointer ((Lisp_Object) 0)
-#define XGCTYPE(x) XTYPE(x)
 #define EQ(x,y) ((x) == (y))
-#define XSETINT(var,  value) ((void) ((var) = make_int (value)))
+#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)))
+#define XSETOBJ(var, value) ((void) ((var) = wrap_object (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
 #define LISP_TO_VOID(larg) ((void *) (larg))
-#define LISP_TO_CVOID(varg) ((CONST void *) (larg))
+#define LISP_TO_CVOID(larg) ((const void *) (larg))
 
 /* Convert a Lisp_Object into something that can't be used as an
    lvalue.  Useful for type-checking. */