Initial revision
[chise/xemacs-chise.git.1] / src / lisp-disunion.h
1 /* Fundamental definitions for XEmacs Lisp interpreter -- non-union objects.
2    Copyright (C) 1985, 1986, 1987, 1992, 1993 Free Software Foundation, Inc.
3
4 This file is part of XEmacs.
5
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING.  If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 /* Synched up with: FSF 19.30.  Split out from lisp.h. */
22 /* This file has diverged greatly from FSF Emacs.  Syncing is no
23    longer desirable or possible */
24
25 /*
26  Format of a non-union-type Lisp Object
27
28    For the USE_MINIMAL_TAGBITS implementation:
29
30              3         2         1         0
31        bit  10987654321098765432109876543210
32             --------------------------------
33             VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVTT
34
35    Integers are treated specially, and look like this:
36
37              3         2         1         0
38        bit  10987654321098765432109876543210
39             --------------------------------
40             VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVT
41
42    For the non-USE_MINIMAL_TAGBITS implementation:
43
44              3         2         1         0
45        bit  10987654321098765432109876543210
46             --------------------------------
47             TTTMVVVVVVVVVVVVVVVVVVVVVVVVVVVV
48
49     V = value bits
50     T = type bits
51     M = mark bits
52
53  For integral Lisp types, i.e. integers and characters, the value
54  bits are the Lisp object.
55
56      The object is obtained by masking off the type and mark
57      bits.  In the USE_MINIMAL_TAGBITS implementation, bit 1 is
58      used as a value bit by splitting the Lisp integer type into
59      two subtypes, Lisp_Type_Int_Even and Lisp_Type_Int_Odd.  By
60      this trickery we get 31 bits for integers instead of 30.
61
62      In the non-USE_MINIMAL_TAGBITS world, Lisp integers are 28 bits,
63      or more properly (BITS_PER_EMACS_INT - GCTYPEBITS - 1) bits.
64
65  For non-integral types, the value bits of a Lisp_Object contain
66  a pointer to a structure containing the object.  The pointer is
67  obtained by masking off the type and mark bits.
68
69      In the USE_MINIMAL_TAGBITS implementation, all
70      pointer-based types are coalesced under a single type called
71      Lisp_Type_Record.  The type bits for this type are required
72      by the implementation to be 00, just like the least
73      significant bits of word-aligned struct pointers on 32-bit
74      hardware.  Because of this, Lisp_Object pointers don't have
75      to be masked and are full-sized.
76
77      In the non-USE_MINIMAL_TAGBITS implementation, the type and
78      mark bits must be masked off and pointers are limited to 28
79      bits (really BITS_PER_EMACS_INT - GCTYPEBITS - 1 bits).
80
81  There are no mark bits in the USE_MINIMAL_TAGBITS implementation.
82  Integers and characters don't need to be marked.  All other types
83  are lrecord-based, which means they get marked by incrementing
84  their ->implementation pointer.
85
86  In the non-USE_MINIMAL_TAGBITS implementation, the markbit is stored
87  in the Lisp_Object itself.  It is stored in the middle so that the
88  type bits can be obtained by simply shifting them.
89
90  Outside of garbage collection, all mark bits are always zero.
91
92  Here is a brief description of the following macros:
93
94  XMARKBIT  Extract the mark bit (non-USE_MINIMAL_TAGBITS)
95  XMARK     Set the mark bit of this Lisp_Object (non-USE_MINIMAL_TAGBITS)
96  XUNMARK   Clear the mark bit of this Lisp_Object (non-USE_MINIMAL_TAGBITS)
97  XTYPE     The type bits of a Lisp_Object
98  XPNTRVAL  The value bits of a Lisp_Object storing a pointer
99  XCHARVAL  The value bits of a Lisp_Object storing a Emchar
100  XREALINT  The value bits of a Lisp_Object storing an integer, signed
101  XUINT     The value bits of a Lisp_Object storing an integer, unsigned
102  INTP      Non-zero if this Lisp_Object an integer?
103  Qzero     Lisp Integer 0
104  EQ        Non-zero if two Lisp_Objects are identical
105  GC_EQ     Version of EQ used during garbage collection
106 */
107
108 typedef EMACS_INT Lisp_Object;
109
110 #ifdef USE_MINIMAL_TAGBITS
111
112 # define XUNMARK(x) DO_NOTHING
113 # define make_obj(vartype, x) ((Lisp_Object) (x))
114 # define make_int(x) ((Lisp_Object) (((x) << INT_GCBITS) + 1))
115 # define make_char(x) ((Lisp_Object) (((x) << GCBITS) + Lisp_Type_Char))
116 # define VALMASK (((1UL << VALBITS) - 1UL) << GCTYPEBITS)
117 # define XTYPE(x) ((enum Lisp_Type) (((EMACS_UINT)(x)) & ~VALMASK))
118 # define XPNTRVAL(x) (x) /* This depends on Lisp_Type_Record == 0 */
119 # define XCHARVAL(x) ((x) >> GCBITS)
120 # define GC_EQ(x,y) EQ (x,y)
121 # define XREALINT(x) ((x) >> INT_GCBITS)
122 # define XUINT(x) ((EMACS_UINT)(x) >> INT_GCBITS)
123 # define INTP(x) ((EMACS_UINT)(x) & 1)
124 # define Qzero ((Lisp_Object) 1UL)
125
126 #else /* !USE_MINIMAL_TAGBITS */
127
128 # define MARKBIT (1UL << VALBITS)
129 # define XMARKBIT(x) (((x) & MARKBIT) != 0)
130 # define XMARK(x) ((void) ((x) |= MARKBIT))
131 # define XUNMARK(x) ((void) ((x) &= ~MARKBIT))
132 # define make_obj(vartype, value) \
133   ((Lisp_Object) (((EMACS_UINT) (vartype) << (VALBITS + GCMARKBITS)) \
134                   + ((EMACS_UINT) (value) & VALMASK)))
135 # define make_int(value) make_obj (Lisp_Type_Int, value)
136 # define make_char(value) make_obj (Lisp_Type_Char, value)
137 # define VALMASK ((1UL << VALBITS) - 1UL)
138 # define XTYPE(x) ((enum Lisp_Type) (((EMACS_UINT)(x)) >> (VALBITS + GCMARKBITS)))
139 # define XPNTRVAL(x) ((x) & VALMASK)
140 # define XCHARVAL(x) XPNTRVAL(x)
141 # define GC_EQ(x,y) (((x) & ~MARKBIT) == ((y) & ~MARKBIT))
142 # define XREALINT(x) (((x) << INT_GCBITS) >> INT_GCBITS)
143 # define XUINT(x) ((EMACS_UINT) ((x) & VALMASK))
144 # define INTP(x) (XTYPE (x) == Lisp_Type_Int)
145 # define Qzero ((Lisp_Object) Lisp_Type_Int)
146
147 #endif /* !USE_MINIMAL_TAGBITS */
148
149 #define Qnull_pointer 0
150 #define XGCTYPE(x) XTYPE(x)
151 #define EQ(x,y) ((x) == (y))
152 #define XSETINT(var,  value) ((void) ((var) = make_int (value)))
153 #define XSETCHAR(var, value) ((void) ((var) = make_char (value)))
154 #define XSETOBJ(var, vartype, value) ((void) ((var) = make_obj (vartype, value)))
155
156 /* Convert between a (void *) and a Lisp_Object, as when the
157    Lisp_Object is passed to a toolkit callback function */
158 #define VOID_TO_LISP(larg,varg) ((void) ((larg) = ((Lisp_Object) (varg))))
159 #define CVOID_TO_LISP VOID_TO_LISP
160 #define LISP_TO_VOID(larg) ((void *) (larg))
161 #define LISP_TO_CVOID(varg) ((CONST void *) (larg))
162
163 /* Convert a Lisp_Object into something that can't be used as an
164    lvalue.  Useful for type-checking. */
165 #define NON_LVALUE(larg) ((larg) + 0)