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))