Mercurial > hg > xemacs-beta
comparison 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 |
comparison
equal
deleted
inserted
replaced
271:c7b7086b0a39 | 272:c5d627a313b1 |
---|---|
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
19 Boston, MA 02111-1307, USA. */ | 19 Boston, MA 02111-1307, USA. */ |
20 | 20 |
21 /* Synched up with: FSF 19.30. Split out from lisp.h. */ | 21 /* Synched up with: FSF 19.30. Split out from lisp.h. */ |
22 /* This file has diverged greatly from FSF Emacs. Syncing is no | 22 /* This file has diverged greatly from FSF Emacs. Syncing is no |
23 longer desired or possible */ | 23 longer desirable or possible */ |
24 | 24 |
25 /* | 25 /* |
26 * Format of a non-union-type Lisp Object | 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 * For the non-USE_MINIMAL_TAGBITS implementation: | |
36 * | |
37 * 3 2 1 0 | |
38 * bit 10987654321098765432109876543210 | |
39 * -------------------------------- | |
40 * TTTMVVVVVVVVVVVVVVVVVVVVVVVVVVVV | |
41 * | |
42 * V = value bits | |
43 * T = type bits | |
44 * M = mark bits | |
45 * | |
46 * For integral Lisp types, i.e. integers and characters, the value | |
47 * bits are the Lisp object. | |
48 * | |
49 * The object is obtained by masking off the type and mark | |
50 * bits. In the USE_MINIMAL_TAGBITS implementation, bit 1 is | |
51 * used as a value bit by splitting the Lisp integer type into | |
52 * two subtypes, Lisp_Type_Int_Even and Lisp_Type_Int_Odd. By | |
53 * this trickery we get 31 bits for integers instead of 30. | |
54 * | |
55 * In the non-USE_MINIMAL_TAGBITS world, Lisp integers are 28 | |
56 * bits, or more properly (LONGBITS - GCTYPEBITS - 1) bits. | |
57 * | |
58 * For non-integral types, the value bits of Lisp_Object contain a | |
59 * pointer to structure containing the object. The pointer is | |
60 * obtained by masking off the type and mark bits. | |
61 * | |
62 * In the USE_MINIMAL_TAGBITS implementation, all | |
63 * pointer-based types are coalesced under a single type called | |
64 * Lisp_Type_Record. The type bits for this type are required | |
65 * by the implementation to be 00, just like the least | |
66 * significant bits of word-aligned struct pointers on 32-bit | |
67 * hardware. Because of this, Lisp_Object pointers don't have | |
68 * to be masked and are full-sized. | |
69 * | |
70 * In the non-USE_MINIMAL_TAGBITS implementation, the type and | |
71 * mark bits must be masked off and pointers are limited to 28 | |
72 * bits (really LONGBITS - GCTYPEBITS - 1 bits). | |
73 */ | |
74 | 27 |
75 #ifdef USE_MINIMAL_TAGBITS | 28 For the USE_MINIMAL_TAGBITS implementation: |
76 # define Qzero Lisp_Type_Int_Even | 29 |
77 # define VALMASK (((1UL << (VALBITS)) - 1L) << (GCTYPEBITS)) | 30 3 2 1 0 |
78 #else | 31 bit 10987654321098765432109876543210 |
79 # define Qzero Lisp_Type_Int | 32 -------------------------------- |
80 # define VALMASK ((1L << (VALBITS)) - 1L) | 33 VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVTT |
81 # define GCTYPEMASK ((1L << (GCTYPEBITS)) - 1L) | 34 |
82 #endif | 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 */ | |
83 | 107 |
84 typedef EMACS_INT Lisp_Object; | 108 typedef EMACS_INT Lisp_Object; |
85 | 109 |
86 #define Qnull_pointer 0 | |
87 | |
88 /* | |
89 * There are no mark bits in the USE_MINIMAL_TAGBITS implementation. | |
90 * Integers and characters don't need to be marked. All other types | |
91 * are lrecord-based, which means they get marked by incrementing | |
92 * their ->implementation pointer. | |
93 */ | |
94 #if GCMARKBITS > 0 | |
95 /* | |
96 * XMARKBIT accesses the markbit. Markbits are used only in particular | |
97 * slots of particular structure types. Other markbits are always | |
98 * zero. Outside of garbage collection, all mark bits are always zero. | |
99 */ | |
100 # define MARKBIT (1UL << (VALBITS)) | |
101 # define XMARKBIT(a) ((a) & (MARKBIT)) | |
102 | |
103 # define XMARK(a) ((void) ((a) |= (MARKBIT))) | |
104 # define XUNMARK(a) ((void) ((a) &= (~(MARKBIT)))) | |
105 #else | |
106 # define XUNMARK(a) DO_NOTHING | |
107 #endif | |
108 | |
109 /* | |
110 * Extract the type bits from a Lisp_Object. If using USE_MINIMAL_TAGBITS, | |
111 * the least significant two bits are the type bits. Otherwise the | |
112 * most significant GCTYPEBITS bits are the type bits. | |
113 * | |
114 * In the non-USE_MINIMAL_TAGBITS case, one needs to override this | |
115 * if there must be high bits set in data space. Masking the bits | |
116 * (doing the result of the below & ((1 << (GCTYPEBITS)) - 1) would | |
117 * work on all machines, but would penalize machines which don't | |
118 * need it) | |
119 */ | |
120 #ifdef USE_MINIMAL_TAGBITS | |
121 # define XTYPE(a) ((enum Lisp_Type) (((EMACS_UINT)(a)) & ~(VALMASK))) | |
122 #else | |
123 # define XTYPE(a) ((enum Lisp_Type) (((EMACS_UINT)(a)) >> ((VALBITS) + 1))) | |
124 #endif | |
125 | |
126 /* | |
127 * This applies only to the non-USE_MINIMAL_TAGBITS Lisp_Object. | |
128 * | |
129 * In the past, during garbage collection, XGCTYPE needed to be used | |
130 * for extracting types so that the mark bit was ignored. XGCTYPE | |
131 * did and exatr & operation to remove the mark bit. But the mark | |
132 * bit has been since moved so that the type bits could be extracted | |
133 * with a single shift operation, making XGCTYPE no more expensive | |
134 * than XTYPE, so the two operations are now equivalent. | |
135 */ | |
136 #ifndef XGCTYPE | |
137 # define XGCTYPE(a) XTYPE(a) | |
138 #endif | |
139 | |
140 #define EQ(x,y) ((x) == (y)) | |
141 | |
142 #ifdef USE_MINIMAL_TAGBITS | |
143 # define GC_EQ(x,y) EQ(x,y) | |
144 #else | |
145 # define GC_EQ(x,y) (XGCTYPE (x) == XGCTYPE (y) && XPNTR (x) == XPNTR (y)) | |
146 #endif | |
147 | |
148 /* | |
149 * Extract the value of a Lisp_Object as a signed integer. | |
150 * | |
151 * The right shifts below are non-portable because >> is allowed to | |
152 * sign extend or not signed extend signed integers depending on the | |
153 * compiler implementors preference. But this right-shifting of | |
154 * signed ints has been here forever, so the apparently reality is | |
155 * that all compilers of any consequence do sign extension, which is | |
156 * what is needed here. | |
157 */ | |
158 #ifndef XREALINT /* Some machines need to do this differently. */ | |
159 # ifdef USE_MINIMAL_TAGBITS | |
160 # define XREALINT(a) ((a) >> (LONGBITS-VALBITS-1)) | |
161 # else | |
162 # define XREALINT(a) (((a) << (LONGBITS-VALBITS)) >> (LONGBITS-VALBITS)) | |
163 # endif | |
164 #endif | |
165 | |
166 /* Extract the value of a Lisp integer as an unsigned integer. */ | |
167 #ifdef USE_MINIMAL_TAGBITS | |
168 # define XUINT(a) ((EMACS_UINT)(a) >> (LONGBITS-VALBITS-1)) | |
169 #else | |
170 # define XUINT(a) XPNTRVAL(a) | |
171 #endif | |
172 | |
173 /* | |
174 * Extract the pointer value bits of a pointer based type. | |
175 */ | |
176 #ifdef USE_MINIMAL_TAGBITS | |
177 # define XPNTRVAL(a) (a) /* This depends on Lisp_Type_Record == 0 */ | |
178 # define XCHARVAL(a) ((a) >> (LONGBITS-VALBITS)) | |
179 #else | |
180 # define XPNTRVAL(a) ((a) & VALMASK) | |
181 # define XCHARVAL(a) XPNTRVAL(a) | |
182 #endif | |
183 | |
184 #ifdef HAVE_SHM | |
185 /* In this representation, data is found in two widely separated segments. */ | |
186 extern int pure_size; | |
187 # define XPNTR(a) \ | |
188 (XPNTRVAL (a) | (XPNTRVAL (a) > pure_size ? DATA_SEG_BITS : PURE_SEG_BITS)) | |
189 # else /* not HAVE_SHM */ | |
190 # ifdef DATA_SEG_BITS | |
191 /* This case is used for the rt-pc. | |
192 In the diffs I was given, it checked for ptr = 0 | |
193 and did not adjust it in that case. | |
194 But I don't think that zero should ever be found | |
195 in a Lisp object whose data type says it points to something. */ | |
196 # define XPNTR(a) (XPNTRVAL (a) | DATA_SEG_BITS) | |
197 # else | |
198 # define XPNTR(a) XPNTRVAL (a) | |
199 # endif | |
200 #endif /* not HAVE_SHM */ | |
201 | |
202 #ifdef USE_MINIMAL_TAGBITS | 110 #ifdef USE_MINIMAL_TAGBITS |
203 | 111 |
204 /* XSETINT depends on Lisp_Type_Int_Even == 1 and Lisp_Type_Int_Odd == 3 */ | 112 # define XUNMARK(x) DO_NOTHING |
205 # define XSETINT(var, value) \ | 113 # define make_obj(vartype, x) ((Lisp_Object) (x)) |
206 ((void) ((var) = ((value) << (LONGBITS-VALBITS-1)) + 1)) | 114 # define make_int(x) ((Lisp_Object) (((x) << INT_GCBITS) + 1)) |
207 # define XSETCHAR(var, value) \ | 115 # define make_char(x) ((Lisp_Object) (((x) << GCBITS) + Lisp_Type_Char)) |
208 ((void) ((var) = ((value) << (LONGBITS-VALBITS)) + Lisp_Type_Char)) | 116 # define VALMASK (((1UL << VALBITS) - 1UL) << GCTYPEBITS) |
209 # define XSETOBJ(var, type_tag, value) \ | 117 # define XTYPE(x) ((enum Lisp_Type) (((EMACS_UINT)(x)) & ~VALMASK)) |
210 ((void) ((var) = ((EMACS_UINT) (value)))) | 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) | |
211 | 125 |
212 #else | 126 #else /* !USE_MINIMAL_TAGBITS */ |
213 | 127 |
214 # define XSETINT(a, b) XSETOBJ (a, Lisp_Type_Int, b) | 128 # define MARKBIT (1UL << VALBITS) |
215 # define XSETCHAR(var, value) XSETOBJ (var, Lisp_Type_Char, value) | 129 # define XMARKBIT(x) ((x) & MARKBIT) |
216 # define XSETOBJ(var, type_tag, value) \ | 130 # define XMARK(x) ((void) ((x) |= MARKBIT)) |
217 ((void) ((var) = (((EMACS_UINT) (type_tag) << ((VALBITS) + 1)) \ | 131 # define XUNMARK(x) ((void) ((x) &= ~MARKBIT)) |
218 + ((EMACS_INT) (value) & VALMASK)))) | 132 # define make_obj(vartype, value) \ |
219 #endif | 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) | |
220 | 146 |
221 /* Use this for turning a (void *) into a Lisp_Object, as when the | 147 #endif /* !USE_MINIMAL_TAGBITS */ |
222 Lisp_Object is passed into a toolkit callback function */ | 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 */ | |
223 #define VOID_TO_LISP(larg,varg) ((void) ((larg) = ((Lisp_Object) (varg)))) | 158 #define VOID_TO_LISP(larg,varg) ((void) ((larg) = ((Lisp_Object) (varg)))) |
224 #define CVOID_TO_LISP VOID_TO_LISP | 159 #define CVOID_TO_LISP VOID_TO_LISP |
225 | |
226 /* Use this for turning a Lisp_Object into a (void *), as when the | |
227 Lisp_Object is passed into a toolkit callback function */ | |
228 #define LISP_TO_VOID(larg) ((void *) (larg)) | 160 #define LISP_TO_VOID(larg) ((void *) (larg)) |
229 #define LISP_TO_CVOID(varg) ((CONST void *) (larg)) | 161 #define LISP_TO_CVOID(varg) ((CONST void *) (larg)) |
230 | 162 |
231 /* Convert a Lisp_Object into something that can't be used as an | 163 /* Convert a Lisp_Object into something that can't be used as an |
232 lvalue. Useful for type-checking. */ | 164 lvalue. Useful for type-checking. */ |