Mercurial > hg > xemacs-beta
comparison src/lrecord.h @ 420:41dbb7a9d5f2 r21-2-18
Import from CVS: tag r21-2-18
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:24:09 +0200 |
parents | 697ef44129c6 |
children | 11054d720c21 |
comparison
equal
deleted
inserted
replaced
419:66615b78f1a5 | 420:41dbb7a9d5f2 |
---|---|
58 the opaque type. */ | 58 the opaque type. */ |
59 | 59 |
60 struct lrecord_header | 60 struct lrecord_header |
61 { | 61 { |
62 /* index into lrecord_implementations_table[] */ | 62 /* index into lrecord_implementations_table[] */ |
63 unsigned char type; | 63 unsigned type :8; |
64 struct { | 64 /* 1 if the object is marked during GC. */ |
65 /* 1 if the object is marked during GC. */ | 65 unsigned mark :1; |
66 unsigned mark :1; | 66 /* 1 if the object resides in read-only space */ |
67 /* 1 if the object resides in read-only space */ | 67 unsigned c_readonly : 1; |
68 unsigned c_readonly : 1; | 68 /* 1 if the object is readonly from lisp */ |
69 /* 1 if the object is readonly from lisp */ | 69 unsigned lisp_readonly : 1; |
70 unsigned lisp_readonly : 1; | |
71 } flags; | |
72 }; | 70 }; |
73 | 71 |
74 struct lrecord_implementation; | 72 struct lrecord_implementation; |
75 int lrecord_type_index (CONST struct lrecord_implementation *implementation); | 73 int lrecord_type_index (CONST struct lrecord_implementation *implementation); |
76 | 74 |
77 # define set_lheader_implementation(header,imp) do { \ | 75 # define set_lheader_implementation(header,imp) do { \ |
78 struct lrecord_header* SLI_header = (header); \ | 76 struct lrecord_header* SLI_header = (header); \ |
79 (SLI_header)->type = lrecord_type_index (imp); \ | 77 (SLI_header)->type = lrecord_type_index (imp); \ |
80 (SLI_header)->flags.mark = 0; \ | 78 (SLI_header)->mark = 0; \ |
81 (SLI_header)->flags.c_readonly = 0; \ | 79 (SLI_header)->c_readonly = 0; \ |
82 (SLI_header)->flags.lisp_readonly = 0; \ | 80 (SLI_header)->lisp_readonly = 0; \ |
83 } while (0) | 81 } while (0) |
84 | 82 |
85 struct lcrecord_header | 83 struct lcrecord_header |
86 { | 84 { |
87 struct lrecord_header lheader; | 85 struct lrecord_header lheader; |
154 /* This can be NULL, meaning use the Lisp_Object itself as the hash; | 152 /* This can be NULL, meaning use the Lisp_Object itself as the hash; |
155 but *only* if the `equal' function is EQ (if two objects are | 153 but *only* if the `equal' function is EQ (if two objects are |
156 `equal', they *must* hash to the same value or the hashing won't | 154 `equal', they *must* hash to the same value or the hashing won't |
157 work). */ | 155 work). */ |
158 unsigned long (*hash) (Lisp_Object, int); | 156 unsigned long (*hash) (Lisp_Object, int); |
157 | |
158 /* External data layout description */ | |
159 const struct lrecord_description *description; | |
160 | |
159 Lisp_Object (*getprop) (Lisp_Object obj, Lisp_Object prop); | 161 Lisp_Object (*getprop) (Lisp_Object obj, Lisp_Object prop); |
160 int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val); | 162 int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val); |
161 int (*remprop) (Lisp_Object obj, Lisp_Object prop); | 163 int (*remprop) (Lisp_Object obj, Lisp_Object prop); |
162 Lisp_Object (*plist) (Lisp_Object obj); | 164 Lisp_Object (*plist) (Lisp_Object obj); |
163 | 165 |
182 (lrecord_implementations_table[XRECORD_LHEADER (obj)->type]) | 184 (lrecord_implementations_table[XRECORD_LHEADER (obj)->type]) |
183 #define LHEADER_IMPLEMENTATION(lh) (lrecord_implementations_table[(lh)->type]) | 185 #define LHEADER_IMPLEMENTATION(lh) (lrecord_implementations_table[(lh)->type]) |
184 | 186 |
185 extern int gc_in_progress; | 187 extern int gc_in_progress; |
186 | 188 |
187 #define MARKED_RECORD_P(obj) (gc_in_progress && XRECORD_LHEADER (obj)->flags.mark) | 189 #define MARKED_RECORD_P(obj) (gc_in_progress && XRECORD_LHEADER (obj)->mark) |
188 #define MARKED_RECORD_HEADER_P(lheader) ((lheader)->flags.mark) | 190 #define MARKED_RECORD_HEADER_P(lheader) ((lheader)->mark) |
189 #define MARK_RECORD_HEADER(lheader) ((void) ((lheader)->flags.mark = 1)) | 191 #define MARK_RECORD_HEADER(lheader) ((void) ((lheader)->mark = 1)) |
190 #define UNMARK_RECORD_HEADER(lheader) ((void) ((lheader)->flags.mark = 0)) | 192 #define UNMARK_RECORD_HEADER(lheader) ((void) ((lheader)->mark = 0)) |
191 | 193 |
192 #define UNMARKABLE_RECORD_HEADER_P(lheader) \ | 194 #define UNMARKABLE_RECORD_HEADER_P(lheader) \ |
193 (LHEADER_IMPLEMENTATION (lheader)->marker == this_one_is_unmarkable) | 195 (LHEADER_IMPLEMENTATION (lheader)->marker == this_one_is_unmarkable) |
194 | 196 |
195 #define C_READONLY_RECORD_HEADER_P(lheader) ((lheader)->flags.c_readonly) | 197 #define C_READONLY_RECORD_HEADER_P(lheader) ((lheader)->c_readonly) |
196 #define LISP_READONLY_RECORD_HEADER_P(lheader) ((lheader)->flags.lisp_readonly) | 198 #define LISP_READONLY_RECORD_HEADER_P(lheader) ((lheader)->lisp_readonly) |
197 #define SET_C_READONLY_RECORD_HEADER(lheader) \ | 199 #define SET_C_READONLY_RECORD_HEADER(lheader) \ |
198 ((void) ((lheader)->flags.c_readonly = (lheader)->flags.lisp_readonly = 1)) | 200 ((void) ((lheader)->c_readonly = (lheader)->lisp_readonly = 1)) |
199 #define SET_LISP_READONLY_RECORD_HEADER(lheader) \ | 201 #define SET_LISP_READONLY_RECORD_HEADER(lheader) \ |
200 ((void) ((lheader)->flags.lisp_readonly = 1)) | 202 ((void) ((lheader)->lisp_readonly = 1)) |
203 | |
204 /* External description stuff | |
205 | |
206 A lrecord external description is an array of values. The first | |
207 value of each line is a type, the second the offset in the lrecord | |
208 structure. Following values are parameters, their presence, type | |
209 and number is type-dependant. | |
210 | |
211 The description ends with a "XD_END" record. | |
212 | |
213 Some example descriptions : | |
214 static const struct lrecord_description cons_description[] = { | |
215 { XD_LISP_OBJECT, offsetof(struct Lisp_Cons, car), 2 }, | |
216 { XD_END } | |
217 }; | |
218 | |
219 Which means "two lisp objects starting at the 'car' element" | |
220 | |
221 static const struct lrecord_description string_description[] = { | |
222 { XD_STRING_DATA, offsetof(Lisp_String, data) }, | |
223 { XD_LISP_OBJECT, offsetof(Lisp_String, plist), 1 }, | |
224 { XD_END } | |
225 }; | |
226 "A string data pointer at 'data', one lisp object at 'plist'" | |
227 | |
228 The existing types : | |
229 XD_LISP_OBJECT | |
230 Lisp objects. The third element is the count. This is also the type to use | |
231 for pointers to other lrecords. | |
232 | |
233 XD_STRING_DATA | |
234 Pointer to string data. | |
235 | |
236 XD_OPAQUE_PTR | |
237 Pointer to undumpable data. Must be NULL when dumping. | |
238 | |
239 XD_STRUCT_PTR | |
240 Pointer to described struct. Parameters are number of structures and | |
241 struct_description. | |
242 | |
243 XD_OPAQUE_DATA_PTR | |
244 Pointer to dumpable opaque data. Parameter is the size of the data. | |
245 Pointed data must be relocatable without changes. | |
246 | |
247 XD_SIZE_T | |
248 size_t value. Used for counts. | |
249 | |
250 XD_INT | |
251 int value. Used for counts. | |
252 | |
253 XD_LONG | |
254 long value. Used for counts. | |
255 | |
256 XD_END | |
257 Special type indicating the end of the array. | |
258 | |
259 | |
260 Special macros: | |
261 XD_INDIRECT(line) | |
262 Usable where a "count" or "size" is requested. Gives the value of the element | |
263 which is at line number 'line' in the description (count starts at zero). | |
264 | |
265 XD_PARENT_INDIRECT(line) | |
266 Same as XD_INDIRECT but the element number refers to the parent structure. | |
267 Usable only in struct descriptions. | |
268 */ | |
269 | |
270 enum lrecord_description_type { | |
271 XD_LISP_OBJECT, | |
272 XD_STRING_DATA, | |
273 XD_OPAQUE_PTR, | |
274 XD_STRUCT_PTR, | |
275 XD_OPAQUE_DATA_PTR, | |
276 XD_SIZE_T, | |
277 XD_INT, | |
278 XD_LONG, | |
279 XD_END | |
280 }; | |
281 | |
282 struct lrecord_description { | |
283 enum lrecord_description_type type; | |
284 int offset; | |
285 EMACS_INT data1; | |
286 const struct struct_description *data2; | |
287 }; | |
288 | |
289 struct struct_description { | |
290 size_t size; | |
291 const struct lrecord_description *description; | |
292 }; | |
293 | |
294 #define XD_INDIRECT(count) (-1-(count)) | |
295 #define XD_PARENT_INDIRECT(count) (-1000-(count)) | |
296 | |
297 #define XD_DYNARR_DESC(base_type, sub_desc) \ | |
298 { XD_STRUCT_PTR, offsetof(base_type, base), XD_INDIRECT(1), sub_desc }, \ | |
299 { XD_INT, offsetof(base_type, max) } | |
201 | 300 |
202 /* Declaring the following structures as const puts them in the | 301 /* Declaring the following structures as const puts them in the |
203 text (read-only) segment, which makes debugging inconvenient | 302 text (read-only) segment, which makes debugging inconvenient |
204 because this segment is not mapped when processing a core- | 303 because this segment is not mapped when processing a core- |
205 dump file */ | 304 dump file */ |
218 # define DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) | 317 # define DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) |
219 #else | 318 #else |
220 # define DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) | 319 # define DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) |
221 #endif | 320 #endif |
222 | 321 |
223 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,structtype) \ | 322 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \ |
224 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,0,0,0,0,structtype) | 323 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) |
225 | 324 |
226 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,structtype) \ | 325 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,props,structtype) \ |
227 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,sizeof(structtype),0,1,structtype) | 326 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,props,sizeof(structtype),0,1,structtype) |
228 | 327 |
229 #define DEFINE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,structtype) \ | 328 #define DEFINE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \ |
230 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,0,0,0,0,structtype) | 329 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) |
231 | 330 |
232 #define DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,structtype) \ | 331 #define DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,props,structtype) \ |
233 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,sizeof (structtype),0,0,structtype) | 332 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,props,sizeof (structtype),0,0,structtype) |
234 | 333 |
235 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,sizer,structtype) \ | 334 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ |
236 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,0,0,0,0,sizer,structtype) | 335 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype) |
237 | 336 |
238 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,sizer,structtype) \ | 337 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,props,sizer,structtype) \ |
239 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,0,sizer,0,structtype) \ | 338 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,props,0,sizer,0,structtype) \ |
240 | 339 |
241 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,size,sizer,basic_p,structtype) \ | 340 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,props,size,sizer,basic_p,structtype) \ |
242 DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) \ | 341 DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) \ |
243 static int lrecord_##c_name##_lrecord_type_index; \ | 342 static int lrecord_##c_name##_lrecord_type_index; \ |
244 CONST_IF_NOT_DEBUG struct lrecord_implementation lrecord_##c_name = \ | 343 CONST_IF_NOT_DEBUG struct lrecord_implementation lrecord_##c_name = \ |
245 { name, marker, printer, nuker, equal, hash, \ | 344 { name, marker, printer, nuker, equal, hash, desc, \ |
246 getprop, putprop, remprop, props, size, sizer, \ | 345 getprop, putprop, remprop, props, size, sizer, \ |
247 &(lrecord_##c_name##_lrecord_type_index), basic_p } \ | 346 &(lrecord_##c_name##_lrecord_type_index), basic_p } \ |
248 | 347 |
249 #define LRECORDP(a) (XTYPE ((a)) == Lisp_Type_Record) | 348 #define LRECORDP(a) (XTYPE ((a)) == Lisp_Type_Record) |
250 #define XRECORD_LHEADER(a) ((struct lrecord_header *) XPNTR (a)) | 349 #define XRECORD_LHEADER(a) ((struct lrecord_header *) XPNTR (a)) |