comparison src/lisp-union.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 8626e4521993
comparison
equal deleted inserted replaced
271:c7b7086b0a39 272:c5d627a313b1
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING. If not, write to 18 along with XEmacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */ 20 Boston, MA 02111-1307, USA. */
21 21
22 /* Synched up with: FSF 19.30. Split out from lisp.h. */ 22 /* Divergent from FSF. */
23
24 /* Definition of Lisp_Object type as a union.
25 The declaration order of the objects within the struct members
26 of the union is dependent on ENDIAN-ness and USE_MINIMAL_TAGBITS.
27 See lisp-disunion.h for more details. */
23 28
24 typedef 29 typedef
25 union Lisp_Object 30 union Lisp_Object
26 { 31 {
32 /* if non-valbits are at lower addresses */
33 #if defined(WORDS_BIGENDIAN) == defined(USE_MINIMAL_TAGBITS)
27 struct 34 struct
28 { 35 {
29 #if (!!defined (WORDS_BIGENDIAN) != !!defined (LOWTAGS)) 36 EMACS_UINT val : VALBITS;
30 /* Big-endian lowtags, little-endian hightags */ 37 #if GCMARKBITS > 0
31 unsigned EMACS_INT type_mark: GCTYPEBITS + GCMARKBITS; 38 unsigned int markbit: GCMARKBITS;
32 signed EMACS_INT val: VALBITS; 39 #endif
33 #else /* If WORDS_BIGENDIAN, or little-endian hightags */ 40 enum_field (Lisp_Type) type : GCTYPEBITS;
34 signed EMACS_INT val: VALBITS; 41 } gu;
35 unsigned EMACS_INT mark_type: GCTYPEBITS + GCMARKBITS; 42
36 #endif /* BIG/LITTLE_ENDIAN vs HIGH/LOWTAGS */
37 } s;
38 struct 43 struct
39 { 44 {
40 #if (!!defined (WORDS_BIGENDIAN) == !!defined (LOWTAGS)) 45 signed EMACS_INT val : INT_VALBITS;
41 unsigned EMACS_INT val: VALBITS; 46 unsigned int bits : INT_GCBITS;
42 #endif 47 } s;
43 #ifdef __GNUC__ /* Non-ANSI extension */ 48
44 enum Lisp_Type type: GCTYPEBITS;
45 #else
46 unsigned EMACS_INT type: GCTYPEBITS;
47 #endif /* __GNUC__ */
48 /* The markbit is not really part of the value of a Lisp_Object,
49 and is always zero except during garbage collection. */
50 #if GCMARKBITS > 0
51 unsigned EMACS_INT markbit: GCMARKBITS;
52 #endif
53 #if (!!defined (WORDS_BIGENDIAN) != !!defined (LOWTAGS))
54 unsigned EMACS_INT val: VALBITS;
55 #endif
56 } gu;
57 #ifdef USE_MINIMAL_TAGBITS
58 struct 49 struct
59 { 50 {
60 #if (!!defined (WORDS_BIGENDIAN) != !!defined (LOWTAGS)) 51 EMACS_UINT val : INT_VALBITS;
61 unsigned bit: GCTYPEBITS - 1; 52 unsigned int bits : INT_GCBITS;
62 #endif 53 } u;
63 signed EMACS_INT val: VALBITS + 1; 54 #else /* non-valbits are at higher addresses */
64 #if (!!defined (WORDS_BIGENDIAN) == !!defined (LOWTAGS))
65 unsigned bit: GCTYPEBITS - 1;
66 #endif
67 } si;
68 struct 55 struct
69 { 56 {
70 #if (!!defined (WORDS_BIGENDIAN) != !!defined (LOWTAGS)) 57 enum_field (Lisp_Type) type : GCTYPEBITS;
71 unsigned bit: GCTYPEBITS - 1; 58 #if GCMARKBITS > 0
59 unsigned int markbit: GCMARKBITS;
72 #endif 60 #endif
73 unsigned EMACS_INT val: VALBITS + 1; 61 EMACS_UINT val : VALBITS;
74 #if (!!defined (WORDS_BIGENDIAN) == !!defined (LOWTAGS)) 62 } gu;
75 unsigned bit: GCTYPEBITS - 1; 63
76 #endif 64 struct
77 } u_i; 65 {
78 #endif /* USE_MINIMAL_TAGBITS */ 66 unsigned int bits : INT_GCBITS;
67 signed EMACS_INT val : INT_VALBITS;
68 } s;
69
70 struct
71 {
72 unsigned int bits : INT_GCBITS;
73 EMACS_UINT val : INT_VALBITS;
74 } u;
75
76 #endif /* non-valbits are at higher addresses */
77
79 EMACS_UINT ui; 78 EMACS_UINT ui;
80 EMACS_INT i; 79 signed EMACS_INT i;
81 /* GCC bites yet again. I fart in the general direction of
82 the GCC authors.
83 80
84 This was formerly declared 'void *v' etc. but that causes 81 /* This was formerly declared 'void *v' etc. but that causes
85 GCC to accept any (yes, any) pointer as the argument of 82 GCC to accept any (yes, any) pointer as the argument of
86 a function declared to accept a Lisp_Object. */ 83 a function declared to accept a Lisp_Object. */
87 struct __nosuchstruct__ *v; 84 struct nosuchstruct *v;
88 CONST struct __nosuchstruct__ *cv; /* C wanks */ 85 CONST struct nosuchstruct *cv;
89 } 86 }
90 Lisp_Object; 87 Lisp_Object;
91 88
92 #ifndef USE_MINIMAL_TAGBITS 89 #define XCHARVAL(x) ((x).gu.val)
93 #ifndef XMAKE_LISP 90
94 #if (__GNUC__ > 1) 91 #ifdef USE_MINIMAL_TAGBITS
95 /* Use GCC's struct initializers feature */ 92 # define XSETINT(var, value) do { \
96 #define XMAKE_LISP(vartype,value) \ 93 Lisp_Object *_xzx = &(var); \
97 ((union Lisp_Object) { gu: { markbit: 0, \ 94 _xzx->s.val = (value); \
98 type: (vartype), \ 95 _xzx->s.bits = 1; \
99 val: ((unsigned EMACS_INT) value) } }) 96 } while (0)
100 #endif /* __GNUC__ */ 97 # define XSETCHAR(var, value) do { \
101 #endif /* !XMAKE_LISP */ 98 Lisp_Object *_xzx = &(var); \
99 _xzx->gu.val = (EMACS_UINT) (value); \
100 _xzx->gu.type = Lisp_Type_Char; \
101 } while (0)
102 # define XSETOBJ(var, vartype, value) \
103 ((void) ((var).ui = (EMACS_UINT) (value)))
104 # define XPNTRVAL(x) ((x).ui)
105 #else /* ! USE_MINIMAL_TAGBITS */
106 # define XSETOBJ(var, vartype, value) do { \
107 Lisp_Object *_xzx = &(var); \
108 _xzx->gu.val = (EMACS_UINT) (value); \
109 _xzx->gu.type = (vartype); \
110 _xzx->gu.markbit = 0; \
111 } while (0)
112 # define XSETINT(var, value) XSETOBJ (var, Lisp_Type_Int, value)
113 # define XSETCHAR(var, value) XSETOBJ (var, Lisp_Type_Char, value)
114 # define XPNTRVAL(x) ((x).gu.val)
102 #endif /* ! USE_MINIMAL_TAGBITS */ 115 #endif /* ! USE_MINIMAL_TAGBITS */
103 116
104 #ifdef XMAKE_LISP 117 INLINE Lisp_Object make_int (EMACS_INT val);
105 #define Qzero (XMAKE_LISP (Lisp_Type_Int, 0)) 118 INLINE Lisp_Object
106 #define make_int(a) (XMAKE_LISP (Lisp_Type_Int, (a))) 119 make_int (EMACS_INT val)
107 #define make_char(a) (XMAKE_LISP (Lisp_Type_Char, (a))) 120 {
121 Lisp_Object obj;
122 XSETINT(obj, val);
123 return obj;
124 }
125
126 INLINE Lisp_Object make_char (Emchar val);
127 INLINE Lisp_Object
128 make_char (Emchar val)
129 {
130 Lisp_Object obj;
131 XSETCHAR(obj, val);
132 return obj;
133 }
134
135 extern Lisp_Object Qnull_pointer, Qzero;
136
137 #define XREALINT(x) ((x).s.val)
138 #define XUINT(x) ((x).u.val)
139 #define XTYPE(x) ((x).gu.type)
140 #define XGCTYPE(x) XTYPE (x)
141 #define EQ(x,y) ((x).v == (y).v)
142
143 #ifdef USE_MINIMAL_TAGBITS
144 #define INTP(x) ((x).s.bits)
145 #define GC_EQ(x,y) EQ (x, y)
108 #else 146 #else
109 extern Lisp_Object Qzero; 147 #define INTP(x) (XTYPE(x) == Lisp_Type_Int)
148 #define GC_EQ(x,y) ((x).gu.val == (y).gu.val && XTYPE (x) == XTYPE (y))
110 #endif 149 #endif
111 150
112 extern Lisp_Object Qnull_pointer; 151 #if GCMARKBITS > 0
113 152 /* XMARKBIT accesses the markbit. Markbits are used only in
114 #define EQ(x,y) ((x).v == (y).v) 153 particular slots of particular structure types. Other markbits are
115 #define GC_EQ(x,y) ((x).gu.val == (y).gu.val && (x).gu.type == (y).gu.type) 154 always zero. Outside of garbage collection, all mark bits are
116 155 always zero. */
117 #define XTYPE(a) ((enum Lisp_Type) (a).gu.type) 156 # define XMARKBIT(x) ((x).gu.markbit)
118 #define XGCTYPE(a) XTYPE (a) 157 # define XMARK(x) ((void) (XMARKBIT (x) = 1))
119 158 # define XUNMARK(x) ((void) (XMARKBIT (x) = 0))
120 /* This was commented out a long time ago. I uncommented it, but it
121 makes the Alpha crash, and that's the only system that would use
122 this, so it stays commented out. */
123 #if 0 /* EXPLICIT_SIGN_EXTEND */
124 /* Make sure we sign-extend; compilers have been known to fail to do so. */
125 #define XREALINT(a) (((a).i << ((LONGBITS) - (VALBITS))) >> ((LONGBITS) - (VALBITS)))
126 #else 159 #else
127 #ifdef USE_MINIMAL_TAGBITS 160 # define XUNMARK(x) DO_NOTHING
128 # define XREALINT(a) ((a).si.val)
129 #else
130 # define XREALINT(a) ((a).s.val)
131 #endif
132 #endif /* EXPLICIT_SIGN_EXTEND */
133
134 #ifdef USE_MINIMAL_TAGBITS
135 # define XUINT(a) ((a).u_i.val)
136 #else
137 # define XUINT(a) XPNTRVAL(a)
138 #endif 161 #endif
139 162
140 #ifdef USE_MINIMAL_TAGBITS 163 /* Convert between a (void *) and a Lisp_Object, as when the
141 # define XPNTRVAL(a) ((a).ui) 164 Lisp_Object is passed to a toolkit callback function */
142 # define XCHARVAL(a) ((a).gu.val)
143 #else
144 # define XPNTRVAL(a) ((a).gu.val)
145 # define XCHARVAL(a) XPNTRVAL(a)
146 #endif
147
148 #ifdef HAVE_SHM
149 /* In this representation, data is found in two widely separated segments. */
150 extern int pure_size;
151 # define XPNTR(a) \
152 ((void *)(XPNTRVAL(a)) | (XPNTRVAL(a) > pure_size ? DATA_SEG_BITS : PURE_SEG_BITS)))
153 #else /* not HAVE_SHM */
154 # ifdef DATA_SEG_BITS
155 /* This case is used for the rt-pc and hp-pa.
156 In the diffs I was given, it checked for ptr = 0
157 and did not adjust it in that case.
158 But I don't think that zero should ever be found
159 in a Lisp object whose data type says it points to something.
160 */
161 # define XPNTR(a) ((void *)((XPNTRVAL(a)) | DATA_SEG_BITS))
162 # else /* not DATA_SEG_BITS */
163 # define XPNTR(a) ((void *) (XPNTRVAL(a)))
164 # endif /* not DATA_SEG_BITS */
165 #endif /* not HAVE_SHM */
166
167 #ifdef USE_MINIMAL_TAGBITS
168 # define XSETINT(a, b) \
169 do { Lisp_Object *_xzx = &(a) ; \
170 (*_xzx).si.val = (b) ; \
171 (*_xzx).si.bit = 1; \
172 } while (0)
173 # define XSETCHAR(a, b) \
174 do { Lisp_Object *_xzx = &(a) ; \
175 (*_xzx).gu.val = (b) ; \
176 (*_xzx).gu.type = Lisp_Type_Char; \
177 } while (0)
178 #else
179 # define XSETINT(a, b) ((void) ((a) = make_int (b)))
180 # define XSETCHAR(a, b) ((void) ((a) = make_char (b)))
181 #endif
182
183 /* XSETOBJ was formerly named XSET. The name change was made to catch
184 C code that attempts to use this macro. You should always use the
185 individual settor macros (XSETCONS, XSETBUFFER, etc.) instead. */
186
187 #ifdef USE_MINIMAL_TAGBITS
188 # define XSETOBJ(var, vartype, value) \
189 ((void) ((var).ui = (EMACS_UINT)(value)))
190 #else
191 # ifdef XMAKE_LISP
192 # define XSETOBJ(a, type, b) ((void) ((a) = XMAKE_LISP (type, b)))
193 # else
194 /* This is haired up to avoid evaluating var twice...
195 This is necessary only in the "union" version.
196 The "int" version has never done double evaluation.
197 */
198 /* XEmacs change: put the assignment to val first; otherwise you
199 can trip up the error_check_*() stuff */
200 # define XSETOBJ(var, vartype, value) \
201 do { \
202 Lisp_Object *tmp_xset_var = &(var); \
203 (*tmp_xset_var).s.val = ((EMACS_INT) (value)); \
204 (*tmp_xset_var).gu.markbit = 0; \
205 (*tmp_xset_var).gu.type = (vartype); \
206 } while (0)
207 # endif /* ! XMAKE_LISP */
208 #endif /* ! USE_MINIMAL_TAGBITS */
209
210 #if GCMARKBITS > 0
211 /*
212 * XMARKBIT access the markbit. Markbits are used only in particular
213 * slots of particular structure types. Other markbits are always
214 * zero. Outside of garbage collection, all mark bits are always
215 * zero.
216 */
217 # define XMARKBIT(a) ((a).gu.markbit)
218 # define XMARK(a) ((void) (XMARKBIT (a) = 1))
219 # define XUNMARK(a) ((void) (XMARKBIT (a) = 0))
220 #else
221 # define XUNMARK(a) DO_NOTHING
222 #endif
223
224 /* Use this for turning a (void *) into a Lisp_Object, as when the
225 Lisp_Object is passed into a toolkit callback function */
226 #define VOID_TO_LISP(larg,varg) \ 165 #define VOID_TO_LISP(larg,varg) \
227 ((void) ((larg).v = (struct __nosuchstruct__ *) (varg))) 166 ((void) ((larg).v = (struct nosuchstruct *) (varg)))
228 #define CVOID_TO_LISP(larg,varg) \ 167 #define CVOID_TO_LISP(larg,varg) \
229 ((void) ((larg).cv = (CONST struct __nosuchstruct__ *) (varg))) 168 ((void) ((larg).cv = (CONST struct nosuchstruct *) (varg)))
230
231 /* Use this for turning a Lisp_Object into a (void *), as when the
232 Lisp_Object is passed into a toolkit callback function */
233 #define LISP_TO_VOID(larg) ((void *) ((larg).v)) 169 #define LISP_TO_VOID(larg) ((void *) ((larg).v))
234 #define LISP_TO_CVOID(larg) ((CONST void *) ((larg).cv)) 170 #define LISP_TO_CVOID(larg) ((CONST void *) ((larg).cv))
235 171
236 /* Convert a Lisp_Object into something that can't be used as an 172 /* Convert a Lisp_Object into something that can't be used as an
237 lvalue. Useful for type-checking. */ 173 lvalue. Useful for type-checking. */