Mercurial > hg > xemacs-beta
comparison src/lisp-disunion.h @ 398:74fd4e045ea6 r21-2-29
Import from CVS: tag r21-2-29
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:13:30 +0200 |
parents | 8626e4521993 |
children | 697ef44129c6 |
comparison
equal
deleted
inserted
replaced
397:f4aeb21a5bad | 398:74fd4e045ea6 |
---|---|
23 longer desirable 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 | 27 |
28 For the USE_MINIMAL_TAGBITS implementation: | |
29 | |
30 3 2 1 0 | 28 3 2 1 0 |
31 bit 10987654321098765432109876543210 | 29 bit 10987654321098765432109876543210 |
32 -------------------------------- | 30 -------------------------------- |
33 VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVTT | 31 VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVTT |
34 | 32 |
37 3 2 1 0 | 35 3 2 1 0 |
38 bit 10987654321098765432109876543210 | 36 bit 10987654321098765432109876543210 |
39 -------------------------------- | 37 -------------------------------- |
40 VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVT | 38 VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVT |
41 | 39 |
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 | 40 For integral Lisp types, i.e. integers and characters, the value |
54 bits are the Lisp object. | 41 bits are the Lisp object. |
55 | 42 |
56 The object is obtained by masking off the type and mark | 43 The object is obtained by masking off the type and mark bits. |
57 bits. In the USE_MINIMAL_TAGBITS implementation, bit 1 is | 44 Bit 1 is used as a value bit by splitting the Lisp integer type |
58 used as a value bit by splitting the Lisp integer type into | 45 into two subtypes, Lisp_Type_Int_Even and Lisp_Type_Int_Odd. By |
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. | 46 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 | 47 |
65 For non-integral types, the value bits of a Lisp_Object contain | 48 For non-integral types, the value bits of a Lisp_Object contain |
66 a pointer to a structure containing the object. The pointer is | 49 a pointer to a structure containing the object. The pointer is |
67 obtained by masking off the type and mark bits. | 50 obtained by masking off the type and mark bits. |
68 | 51 |
69 In the USE_MINIMAL_TAGBITS implementation, all | 52 All pointer-based types are coalesced under a single type called |
70 pointer-based types are coalesced under a single type called | |
71 Lisp_Type_Record. The type bits for this type are required | 53 Lisp_Type_Record. The type bits for this type are required |
72 by the implementation to be 00, just like the least | 54 by the implementation to be 00, just like the least |
73 significant bits of word-aligned struct pointers on 32-bit | 55 significant bits of word-aligned struct pointers on 32-bit |
74 hardware. Because of this, Lisp_Object pointers don't have | 56 hardware. Because of this, Lisp_Object pointers don't have |
75 to be masked and are full-sized. | 57 to be masked and are full-sized. |
76 | 58 |
77 In the non-USE_MINIMAL_TAGBITS implementation, the type and | 59 There are no mark bits. |
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 | 60 Integers and characters don't need to be marked. All other types |
83 are lrecord-based, which means they get marked by incrementing | 61 are lrecord-based, which means they get marked by incrementing |
84 their ->implementation pointer. | 62 their ->implementation pointer. |
85 | 63 |
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: | 64 Here is a brief description of the following macros: |
93 | 65 |
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 | 66 XTYPE The type bits of a Lisp_Object |
98 XPNTRVAL The value bits of a Lisp_Object storing a pointer | 67 XPNTRVAL The value bits of a Lisp_Object storing a pointer |
99 XCHARVAL The value bits of a Lisp_Object storing a Emchar | 68 XCHARVAL The value bits of a Lisp_Object storing a Emchar |
100 XREALINT The value bits of a Lisp_Object storing an integer, signed | 69 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 | 70 XUINT The value bits of a Lisp_Object storing an integer, unsigned |
102 INTP Non-zero if this Lisp_Object an integer? | 71 INTP Non-zero if this Lisp_Object an integer? |
103 Qzero Lisp Integer 0 | 72 Qzero Lisp Integer 0 |
104 EQ Non-zero if two Lisp_Objects are identical | 73 EQ Non-zero if two Lisp_Objects are identical */ |
105 GC_EQ Version of EQ used during garbage collection | 74 |
106 */ | |
107 | 75 |
108 typedef EMACS_INT Lisp_Object; | 76 typedef EMACS_INT Lisp_Object; |
109 | 77 |
110 #ifdef USE_MINIMAL_TAGBITS | 78 #define Lisp_Type_Int_Bit (Lisp_Type_Int_Even & Lisp_Type_Int_Odd) |
111 | 79 #define make_obj(vartype, x) ((Lisp_Object) (x)) |
112 # define Lisp_Type_Int_Bit (Lisp_Type_Int_Even & Lisp_Type_Int_Odd) | 80 #define make_int(x) ((Lisp_Object) (((x) << INT_GCBITS) | Lisp_Type_Int_Bit)) |
113 # define XUNMARK(x) DO_NOTHING | 81 #define make_char(x) ((Lisp_Object) (((x) << GCBITS) | Lisp_Type_Char)) |
114 # define make_obj(vartype, x) ((Lisp_Object) (x)) | 82 #define VALMASK (((1UL << VALBITS) - 1UL) << GCTYPEBITS) |
115 # define make_int(x) ((Lisp_Object) (((x) << INT_GCBITS) | Lisp_Type_Int_Bit)) | 83 #define XTYPE(x) ((enum Lisp_Type) (((EMACS_UINT)(x)) & ~VALMASK)) |
116 # define make_char(x) ((Lisp_Object) (((x) << GCBITS) | Lisp_Type_Char)) | 84 #define XPNTRVAL(x) (x) /* This depends on Lisp_Type_Record == 0 */ |
117 # define VALMASK (((1UL << VALBITS) - 1UL) << GCTYPEBITS) | 85 #define XCHARVAL(x) ((x) >> GCBITS) |
118 # define XTYPE(x) ((enum Lisp_Type) (((EMACS_UINT)(x)) & ~VALMASK)) | 86 #define XREALINT(x) ((x) >> INT_GCBITS) |
119 # define XPNTRVAL(x) (x) /* This depends on Lisp_Type_Record == 0 */ | 87 #define XUINT(x) ((EMACS_UINT)(x) >> INT_GCBITS) |
120 # define XCHARVAL(x) ((x) >> GCBITS) | 88 #define INTP(x) ((EMACS_UINT)(x) & Lisp_Type_Int_Bit) |
121 # define GC_EQ(x,y) EQ (x,y) | 89 #define INT_PLUS(x,y) ((x)+(y)-Lisp_Type_Int_Bit) |
122 # define XREALINT(x) ((x) >> INT_GCBITS) | 90 #define INT_MINUS(x,y) ((x)-(y)+Lisp_Type_Int_Bit) |
123 # define XUINT(x) ((EMACS_UINT)(x) >> INT_GCBITS) | 91 #define INT_PLUS1(x) INT_PLUS (x, make_int (1)) |
124 # define INTP(x) ((EMACS_UINT)(x) & Lisp_Type_Int_Bit) | 92 #define INT_MINUS1(x) INT_MINUS (x, make_int (1)) |
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 | |
146 #endif /* !USE_MINIMAL_TAGBITS */ | |
147 | 93 |
148 #define Qzero make_int (0) | 94 #define Qzero make_int (0) |
149 #define Qnull_pointer ((Lisp_Object) 0) | 95 #define Qnull_pointer ((Lisp_Object) 0) |
150 #define XGCTYPE(x) XTYPE(x) | |
151 #define EQ(x,y) ((x) == (y)) | 96 #define EQ(x,y) ((x) == (y)) |
152 #define XSETINT(var, value) ((void) ((var) = make_int (value))) | 97 #define XSETINT(var, value) ((void) ((var) = make_int (value))) |
153 #define XSETCHAR(var, value) ((void) ((var) = make_char (value))) | 98 #define XSETCHAR(var, value) ((void) ((var) = make_char (value))) |
154 #define XSETOBJ(var, vartype, value) ((void) ((var) = make_obj (vartype, value))) | 99 #define XSETOBJ(var, vartype, value) ((void) ((var) = make_obj (vartype, value))) |
155 | 100 |
156 /* Convert between a (void *) and a Lisp_Object, as when the | 101 /* Convert between a (void *) and a Lisp_Object, as when the |
157 Lisp_Object is passed to a toolkit callback function */ | 102 Lisp_Object is passed to a toolkit callback function */ |
158 #define VOID_TO_LISP(larg,varg) ((void) ((larg) = ((Lisp_Object) (varg)))) | 103 #define VOID_TO_LISP(larg,varg) ((void) ((larg) = ((Lisp_Object) (varg)))) |
159 #define CVOID_TO_LISP VOID_TO_LISP | 104 #define CVOID_TO_LISP VOID_TO_LISP |
160 #define LISP_TO_VOID(larg) ((void *) (larg)) | 105 #define LISP_TO_VOID(larg) ((void *) (larg)) |
161 #define LISP_TO_CVOID(varg) ((CONST void *) (larg)) | 106 #define LISP_TO_CVOID(varg) ((const void *) (larg)) |
162 | 107 |
163 /* Convert a Lisp_Object into something that can't be used as an | 108 /* Convert a Lisp_Object into something that can't be used as an |
164 lvalue. Useful for type-checking. */ | 109 lvalue. Useful for type-checking. */ |
165 #define NON_LVALUE(larg) ((larg) + 0) | 110 #define NON_LVALUE(larg) ((larg) + 0) |