Mercurial > hg > xemacs-beta
comparison src/lrecord.h @ 5117:3742ea8250b5 ben-lisp-object ben-lisp-object-final-ws-year-2005
Checking in final CVS version of workspace 'ben-lisp-object'
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Sat, 26 Dec 2009 00:20:27 -0600 |
parents | d30cd499e445 |
children | e0db3c197671 |
comparison
equal
deleted
inserted
replaced
5116:e56f73345619 | 5117:3742ea8250b5 |
---|---|
80 the opaque type. --ben | 80 the opaque type. --ben |
81 */ | 81 */ |
82 #endif /* not MC_ALLOC */ | 82 #endif /* not MC_ALLOC */ |
83 | 83 |
84 #ifdef MC_ALLOC | 84 #ifdef MC_ALLOC |
85 #define ALLOC_LISP_OBJECT(type) alloc_lrecord (&lrecord_##type) | |
86 #define ALLOC_SIZED_LISP_OBJECT(size, type) \ | |
87 alloc_sized_lrecord (size, &lrecord_##type) | |
85 #define ALLOC_LCRECORD_TYPE alloc_lrecord_type | 88 #define ALLOC_LCRECORD_TYPE alloc_lrecord_type |
86 #define COPY_SIZED_LCRECORD copy_sized_lrecord | 89 #define COPY_SIZED_LCRECORD copy_sized_lrecord |
87 #define COPY_LCRECORD copy_lrecord | 90 #define COPY_LCRECORD copy_lrecord |
88 #define LISPOBJ_STORAGE_SIZE(ptr, size, stats) \ | 91 #define LISPOBJ_STORAGE_SIZE(ptr, size, stats) \ |
89 mc_alloced_storage_size (size, stats) | 92 mc_alloced_storage_size (size, stats) |
90 #define ZERO_LCRECORD zero_lrecord | 93 #define ZERO_LCRECORD zero_lrecord |
91 #define LCRECORD_HEADER lrecord_header | 94 #define LCRECORD_HEADER lrecord_header |
92 #define BASIC_ALLOC_LCRECORD alloc_lrecord | |
93 #define FREE_LCRECORD free_lrecord | 95 #define FREE_LCRECORD free_lrecord |
94 #else | 96 #else |
97 #define ALLOC_LISP_OBJECT(type) alloc_lcrecord (&lrecord_##type) | |
98 #define ALLOC_SIZED_LISP_OBJECT(size, type) \ | |
99 old_alloc_sized_lcrecord (size, &lrecord_##type) | |
95 #define ALLOC_LCRECORD_TYPE old_alloc_lcrecord_type | 100 #define ALLOC_LCRECORD_TYPE old_alloc_lcrecord_type |
96 #define COPY_SIZED_LCRECORD old_copy_sized_lcrecord | 101 #define COPY_SIZED_LCRECORD old_copy_sized_lcrecord |
97 #define COPY_LCRECORD old_copy_lcrecord | 102 #define COPY_LCRECORD old_copy_lcrecord |
98 #define LISPOBJ_STORAGE_SIZE malloced_storage_size | 103 #define LISPOBJ_STORAGE_SIZE malloced_storage_size |
99 #define ZERO_LCRECORD old_zero_lcrecord | 104 #define ZERO_LCRECORD old_zero_lcrecord |
100 #define LCRECORD_HEADER old_lcrecord_header | 105 #define LCRECORD_HEADER old_lcrecord_header |
101 #define BASIC_ALLOC_LCRECORD old_basic_alloc_lcrecord | |
102 #define FREE_LCRECORD old_free_lcrecord | 106 #define FREE_LCRECORD old_free_lcrecord |
103 #endif | 107 #endif |
104 | 108 |
105 BEGIN_C_DECLS | 109 BEGIN_C_DECLS |
106 | 110 |
176 { | 180 { |
177 struct lrecord_header lheader; | 181 struct lrecord_header lheader; |
178 | 182 |
179 /* The `next' field is normally used to chain all lcrecords together | 183 /* The `next' field is normally used to chain all lcrecords together |
180 so that the GC can find (and free) all of them. | 184 so that the GC can find (and free) all of them. |
181 `old_basic_alloc_lcrecord' threads lcrecords together. | 185 `old_alloc_sized_lcrecord' threads lcrecords together. |
182 | 186 |
183 The `next' field may be used for other purposes as long as some | 187 The `next' field may be used for other purposes as long as some |
184 other mechanism is provided for letting the GC do its work. | 188 other mechanism is provided for letting the GC do its work. |
185 | 189 |
186 For example, the event and marker object types allocate members | 190 For example, the event and marker object types allocate members |
328 Yes, this currently means there is logic duplication. Eventually the | 332 Yes, this currently means there is logic duplication. Eventually the |
329 mark methods will be removed. */ | 333 mark methods will be removed. */ |
330 Lisp_Object (*marker) (Lisp_Object); | 334 Lisp_Object (*marker) (Lisp_Object); |
331 | 335 |
332 /* `printer' converts the object to a printed representation. | 336 /* `printer' converts the object to a printed representation. |
333 This can be NULL; in this case default_object_printer() will be | 337 This can be NULL; in this case internal_object_printer() will be |
334 used instead. */ | 338 used instead. */ |
335 void (*printer) (Lisp_Object, Lisp_Object printcharfun, int escapeflag); | 339 void (*printer) (Lisp_Object, Lisp_Object printcharfun, int escapeflag); |
336 | 340 |
337 /* `finalizer' is called at GC time when the object is about to | 341 /* `finalizer' is called at GC time when the object is about to |
338 be freed, and at dump time (FOR_DISKSAVE will be non-zero in this | 342 be freed, and at dump time (FOR_DISKSAVE will be non-zero in this |
365 Lisp_Object (*getprop) (Lisp_Object obj, Lisp_Object prop); | 369 Lisp_Object (*getprop) (Lisp_Object obj, Lisp_Object prop); |
366 int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val); | 370 int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val); |
367 int (*remprop) (Lisp_Object obj, Lisp_Object prop); | 371 int (*remprop) (Lisp_Object obj, Lisp_Object prop); |
368 Lisp_Object (*plist) (Lisp_Object obj); | 372 Lisp_Object (*plist) (Lisp_Object obj); |
369 | 373 |
370 #ifdef MC_ALLOC | 374 /* Only one of `static_size' and `size_in_bytes_method' is non-0. If |
371 /* Only one of `static_size' and `size_in_bytes_method' is non-0. */ | 375 `static_size' is 0, this type is not instantiable by |
372 #else /* not MC_ALLOC */ | 376 ALLOC_LISP_OBJECT(). If both are 0 (this should never happen), this |
373 /* Only one of `static_size' and `size_in_bytes_method' is non-0. | 377 object cannot be instantiated; you will get an abort() if you try.*/ |
374 If both are 0, this type is not instantiable by | |
375 old_basic_alloc_lcrecord(). */ | |
376 #endif /* not MC_ALLOC */ | |
377 Bytecount static_size; | 378 Bytecount static_size; |
378 Bytecount (*size_in_bytes_method) (const void *header); | 379 Bytecount (*size_in_bytes_method) (const void *header); |
379 | 380 |
380 /* The (constant) index into lrecord_implementations_table */ | 381 /* The (constant) index into lrecord_implementations_table */ |
381 enum lrecord_type lrecord_type_index; | 382 enum lrecord_type lrecord_type_index; |
1086 #define XD_DYNARR_DESC(base_type, sub_desc) \ | 1087 #define XD_DYNARR_DESC(base_type, sub_desc) \ |
1087 { XD_BLOCK_PTR, offsetof (base_type, base), XD_INDIRECT(1, 0), {sub_desc} },\ | 1088 { XD_BLOCK_PTR, offsetof (base_type, base), XD_INDIRECT(1, 0), {sub_desc} },\ |
1088 { XD_INT, offsetof (base_type, cur) }, \ | 1089 { XD_INT, offsetof (base_type, cur) }, \ |
1089 { XD_INT_RESET, offsetof (base_type, max), XD_INDIRECT(1, 0) } \ | 1090 { XD_INT_RESET, offsetof (base_type, max), XD_INDIRECT(1, 0) } \ |
1090 | 1091 |
1091 /* DEFINE_LRECORD_IMPLEMENTATION is for objects with constant size. | 1092 /* DEFINE_LISP_OBJECT is for objects with constant size. |
1092 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION is for objects whose size varies. | 1093 |
1094 DEFINE_SIZABLE_LISP_OBJECT is for objects whose size varies. | |
1095 | |
1096 DEFINE_FROB_BLOCK_LISP_OBJECT is for objects that are allocated in | |
1097 large blocks ("frob blocks"), which are parceled up individually. Such | |
1098 objects need special handling in alloc.c. This does not apply to | |
1099 MC_ALLOC, because it does this automatically. | |
1100 | |
1101 DEFINE_*_WITH_PROPS is for objects which support the unified property | |
1102 interface using `get', `put', `remprop' and `object-plist'. | |
1103 | |
1104 DEFINE_EXTERNAL_* is for objects defined in an external module. | |
1105 | |
1106 MAKE_LISP_OBJECT is what underlies all of these; it defines | |
1107 | |
1093 */ | 1108 */ |
1094 | 1109 |
1095 #if defined (ERROR_CHECK_TYPES) | 1110 #if defined (ERROR_CHECK_TYPES) |
1096 # define DECLARE_ERROR_CHECK_TYPES(c_name, structtype) | 1111 # define DECLARE_ERROR_CHECK_TYPES(c_name, structtype) |
1097 #else | 1112 #else |
1098 # define DECLARE_ERROR_CHECK_TYPES(c_name, structtype) | 1113 # define DECLARE_ERROR_CHECK_TYPES(c_name, structtype) |
1099 #endif | 1114 #endif |
1100 | 1115 |
1101 | 1116 #error MUST STILL SUPPORT THIS::: |
1102 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ | |
1103 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) | |
1104 | |
1105 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ | |
1106 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof(structtype),0,1,structtype) | |
1107 | 1117 |
1108 #define DEFINE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ | 1118 #define DEFINE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ |
1109 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) | 1119 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) |
1110 | 1120 |
1111 #define DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ | 1121 #error and variations |
1112 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype) | 1122 |
1113 | 1123 #define DEFINE_INTERNAL_LISP_OBJECT(name,c_name,dumpable,structtype,desc,marker) ... |
1114 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ | 1124 |
1115 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype) | 1125 #define DEFINE_FROB_BLOCK_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ |
1116 | 1126 DEFINE_FROB_BLOCK_LISP_OBJECT_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) |
1117 #define DEFINE_BASIC_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ | 1127 |
1118 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,1,structtype) | 1128 #define DEFINE_FROB_BLOCK_LISP_OBJECT_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ |
1119 | 1129 MAKE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof(structtype),0,1,structtype) |
1120 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ | 1130 |
1121 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) | 1131 #define DEFINE_INTERNAL_LISP_OBJECT(name,c_name,structtype,desc,dumpable,marker) \ |
1132 DEFINE_LISP_OBJECT_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,) | |
1133 | |
1134 #define DEFINE_LISP_OBJECT(name,c_name,structtype,desc,dumpable,marker,printer,equal,hash,nuker) \ | |
1135 DEFINE_LISP_OBJECT_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,) | |
1136 | |
1137 #define DEFINE_LISP_OBJECT_WITH_PROPS(name,c_name,structtype,dumpable,desc,marker,printer,equal,hash,nuker,getprop,putprop,remprop,plist) \ | |
1138 MAKE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype) | |
1139 | |
1140 #define DEFINE_SIZABLE_LISP_OBJECT(name,c_name,structtype,sizer,desc,dumpable,marker,printer,equal,hash,nuker) \ | |
1141 DEFINE_SIZABLE_LISP_OBJECT_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype) | |
1142 | |
1143 #define DEFINE_SIZABLE_LISP_OBJECT_WITH_PROPS(name,c_name,structtype,sizer,desc,dumpable,marker,printer,equal,hash,nuker,getprop,putprop,remprop,plist) \ | |
1144 MAKE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) | |
1122 | 1145 |
1123 #ifdef MC_ALLOC | 1146 #ifdef MC_ALLOC |
1124 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ | 1147 #define MAKE_LISP_OBJECT(name,c_name,structtype,sizer,desc,dumpable,marker,printer,equal,hash,nuker,getprop,putprop,remprop,plist,frob_block) \ |
1125 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ | 1148 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ |
1126 const struct lrecord_implementation lrecord_##c_name = \ | 1149 const struct lrecord_implementation lrecord_##c_name = \ |
1127 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ | 1150 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ |
1128 getprop, putprop, remprop, plist, size, sizer, \ | 1151 getprop, putprop, remprop, plist, size, sizer, \ |
1129 lrecord_type_##c_name } | 1152 lrecord_type_##c_name } |
1130 #else /* not MC_ALLOC */ | 1153 #else /* not MC_ALLOC */ |
1131 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ | 1154 #define MAKE_LISP_OBJECT(name,c_name,structtype,sizer,desc,dumpable,marker,printer,equal,hash,nuker,getprop,putprop,remprop,plist,frob_block) \ |
1132 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ | 1155 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ |
1133 const struct lrecord_implementation lrecord_##c_name = \ | 1156 const struct lrecord_implementation lrecord_##c_name = \ |
1134 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ | 1157 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ |
1135 getprop, putprop, remprop, plist, size, sizer, \ | 1158 getprop, putprop, remprop, plist, size, sizer, \ |
1136 lrecord_type_##c_name, basic_p } | 1159 lrecord_type_##c_name, frob_block } |
1137 #endif /* not MC_ALLOC */ | 1160 #endif /* not MC_ALLOC */ |
1138 | 1161 |
1139 #define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ | 1162 #define DEFINE_EXTERNAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ |
1140 DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) | 1163 DEFINE_EXTERNAL_LISP_OBJECT_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) |
1141 | 1164 |
1142 #define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ | 1165 #define DEFINE_EXTERNAL_LISP_OBJECT_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ |
1143 MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype) | 1166 MAKE_EXTERNAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype) |
1144 | 1167 |
1145 #define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ | 1168 #define DEFINE_EXTERNAL_SIZABLE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ |
1146 DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype) | 1169 DEFINE_EXTERNAL_SIZABLE_LISP_OBJECT_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype) |
1147 | 1170 |
1148 #define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ | 1171 #define DEFINE_EXTERNAL_SIZABLE_LISP_OBJECT_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ |
1149 MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) | 1172 MAKE_EXTERNAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) |
1150 | 1173 |
1151 #ifdef MC_ALLOC | 1174 #ifdef MC_ALLOC |
1152 #define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ | 1175 #define MAKE_EXTERNAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ |
1153 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ | 1176 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ |
1154 int lrecord_type_##c_name; \ | 1177 int lrecord_type_##c_name; \ |
1155 struct lrecord_implementation lrecord_##c_name = \ | 1178 struct lrecord_implementation lrecord_##c_name = \ |
1156 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ | 1179 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ |
1157 getprop, putprop, remprop, plist, size, sizer, \ | 1180 getprop, putprop, remprop, plist, size, sizer, \ |
1158 lrecord_type_last_built_in_type } | 1181 lrecord_type_last_built_in_type } |
1159 #else /* not MC_ALLOC */ | 1182 #else /* not MC_ALLOC */ |
1160 #define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ | 1183 #define MAKE_EXTERNAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ |
1161 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ | 1184 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ |
1162 int lrecord_type_##c_name; \ | 1185 int lrecord_type_##c_name; \ |
1163 struct lrecord_implementation lrecord_##c_name = \ | 1186 struct lrecord_implementation lrecord_##c_name = \ |
1164 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ | 1187 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ |
1165 getprop, putprop, remprop, plist, size, sizer, \ | 1188 getprop, putprop, remprop, plist, size, sizer, \ |
1167 #endif /* not MC_ALLOC */ | 1190 #endif /* not MC_ALLOC */ |
1168 | 1191 |
1169 #ifdef USE_KKCC | 1192 #ifdef USE_KKCC |
1170 extern MODULE_API const struct memory_description *lrecord_memory_descriptions[]; | 1193 extern MODULE_API const struct memory_description *lrecord_memory_descriptions[]; |
1171 | 1194 |
1172 #define INIT_LRECORD_IMPLEMENTATION(type) do { \ | 1195 #define INIT_LISP_OBJECT(type) do { \ |
1173 lrecord_implementations_table[lrecord_type_##type] = &lrecord_##type; \ | 1196 lrecord_implementations_table[lrecord_type_##type] = &lrecord_##type; \ |
1174 lrecord_memory_descriptions[lrecord_type_##type] = \ | 1197 lrecord_memory_descriptions[lrecord_type_##type] = \ |
1175 lrecord_implementations_table[lrecord_type_##type]->description; \ | 1198 lrecord_implementations_table[lrecord_type_##type]->description; \ |
1176 } while (0) | 1199 } while (0) |
1177 #else /* not USE_KKCC */ | 1200 #else /* not USE_KKCC */ |
1178 extern MODULE_API Lisp_Object (*lrecord_markers[]) (Lisp_Object); | 1201 extern MODULE_API Lisp_Object (*lrecord_markers[]) (Lisp_Object); |
1179 | 1202 |
1180 #define INIT_LRECORD_IMPLEMENTATION(type) do { \ | 1203 #define INIT_LISP_OBJECT(type) do { \ |
1181 lrecord_implementations_table[lrecord_type_##type] = &lrecord_##type; \ | 1204 lrecord_implementations_table[lrecord_type_##type] = &lrecord_##type; \ |
1182 lrecord_markers[lrecord_type_##type] = \ | 1205 lrecord_markers[lrecord_type_##type] = \ |
1183 lrecord_implementations_table[lrecord_type_##type]->marker; \ | 1206 lrecord_implementations_table[lrecord_type_##type]->marker; \ |
1184 } while (0) | 1207 } while (0) |
1185 #endif /* not USE_KKCC */ | 1208 #endif /* not USE_KKCC */ |
1186 | 1209 |
1187 #define INIT_EXTERNAL_LRECORD_IMPLEMENTATION(type) do { \ | 1210 #define INIT_EXTERNAL_LISP_OBJECT(type) do { \ |
1188 lrecord_type_##type = lrecord_type_count++; \ | 1211 lrecord_type_##type = lrecord_type_count++; \ |
1189 lrecord_##type.lrecord_type_index = lrecord_type_##type; \ | 1212 lrecord_##type.lrecord_type_index = lrecord_type_##type; \ |
1190 INIT_LRECORD_IMPLEMENTATION(type); \ | 1213 INIT_LISP_OBJECT(type); \ |
1191 } while (0) | 1214 } while (0) |
1192 | 1215 |
1193 #ifdef HAVE_SHLIB | 1216 #ifdef HAVE_SHLIB |
1194 /* Allow undefining types in order to support module unloading. */ | 1217 /* Allow undefining types in order to support module unloading. */ |
1195 | 1218 |
1196 #ifdef USE_KKCC | 1219 #ifdef USE_KKCC |
1197 #define UNDEF_LRECORD_IMPLEMENTATION(type) do { \ | 1220 #define UNDEF_LISP_OBJECT(type) do { \ |
1198 lrecord_implementations_table[lrecord_type_##type] = NULL; \ | 1221 lrecord_implementations_table[lrecord_type_##type] = NULL; \ |
1199 lrecord_memory_descriptions[lrecord_type_##type] = NULL; \ | 1222 lrecord_memory_descriptions[lrecord_type_##type] = NULL; \ |
1200 } while (0) | 1223 } while (0) |
1201 #else /* not USE_KKCC */ | 1224 #else /* not USE_KKCC */ |
1202 #define UNDEF_LRECORD_IMPLEMENTATION(type) do { \ | 1225 #define UNDEF_LISP_OBJECT(type) do { \ |
1203 lrecord_implementations_table[lrecord_type_##type] = NULL; \ | 1226 lrecord_implementations_table[lrecord_type_##type] = NULL; \ |
1204 lrecord_markers[lrecord_type_##type] = NULL; \ | 1227 lrecord_markers[lrecord_type_##type] = NULL; \ |
1205 } while (0) | 1228 } while (0) |
1206 #endif /* not USE_KKCC */ | 1229 #endif /* not USE_KKCC */ |
1207 | 1230 |
1208 #define UNDEF_EXTERNAL_LRECORD_IMPLEMENTATION(type) do { \ | 1231 #define UNDEF_EXTERNAL_LISP_OBJECT(type) do { \ |
1209 if (lrecord_##type.lrecord_type_index == lrecord_type_count - 1) { \ | 1232 if (lrecord_##type.lrecord_type_index == lrecord_type_count - 1) { \ |
1210 /* This is the most recently defined type. Clean up nicely. */ \ | 1233 /* This is the most recently defined type. Clean up nicely. */ \ |
1211 lrecord_type_##type = lrecord_type_count--; \ | 1234 lrecord_type_##type = lrecord_type_count--; \ |
1212 } /* Else we can't help leaving a hole with this implementation. */ \ | 1235 } /* Else we can't help leaving a hole with this implementation. */ \ |
1213 UNDEF_LRECORD_IMPLEMENTATION(type); \ | 1236 UNDEF_LISP_OBJECT(type); \ |
1214 } while (0) | 1237 } while (0) |
1215 | 1238 |
1216 #endif /* HAVE_SHLIB */ | 1239 #endif /* HAVE_SHLIB */ |
1217 | 1240 |
1218 #define LRECORDP(a) (XTYPE (a) == Lisp_Type_Record) | 1241 #define LRECORDP(a) (XTYPE (a) == Lisp_Type_Record) |
1239 4. Create the data layout description for your object. See | 1262 4. Create the data layout description for your object. See |
1240 toolbar_button_description below; the comment above in `struct lrecord', | 1263 toolbar_button_description below; the comment above in `struct lrecord', |
1241 describing the purpose of the descriptions; and comments elsewhere in | 1264 describing the purpose of the descriptions; and comments elsewhere in |
1242 this file describing the exact syntax of the description structures. | 1265 this file describing the exact syntax of the description structures. |
1243 | 1266 |
1244 6. Define your object with DEFINE_LRECORD_IMPLEMENTATION() or some | 1267 6. Define your object with DEFINE_LISP_OBJECT() or some |
1245 variant. | 1268 variant. |
1246 | 1269 |
1247 7. Include the header file in the .c file where you defined the object. | 1270 7. Include the header file in the .c file where you defined the object. |
1248 | 1271 |
1249 8. Put a call to INIT_LRECORD_IMPLEMENTATION() for the object in the | 1272 8. Put a call to INIT_LISP_OBJECT() for the object in the |
1250 .c file's syms_of_foo() function. | 1273 .c file's syms_of_foo() function. |
1251 | 1274 |
1252 9. Add a type enum for the object to enum lrecord_type, earlier in this | 1275 9. Add a type enum for the object to enum lrecord_type, earlier in this |
1253 file. | 1276 file. |
1254 | 1277 |
1334 mark_object (data->callback); | 1357 mark_object (data->callback); |
1335 mark_object (data->enabled_p); | 1358 mark_object (data->enabled_p); |
1336 return data->help_string; | 1359 return data->help_string; |
1337 } | 1360 } |
1338 | 1361 |
1339 [[ If your object should never escape to Lisp, declare its print method | 1362 DEFINE_NONDUMPABLE_LISP_OBJECT ("toolbar-button", toolbar_button, |
1340 as internal_object_printer instead of 0. ]] | 1363 mark_toolbar_button, |
1341 | 1364 external_object_printer, 0, 0, 0, |
1342 DEFINE_LRECORD_IMPLEMENTATION ("toolbar-button", toolbar_button, | 1365 toolbar_button_description, |
1343 0, mark_toolbar_button, 0, 0, 0, 0, | 1366 struct toolbar_button); |
1344 toolbar_button_description, | |
1345 struct toolbar_button); | |
1346 | 1367 |
1347 ... | 1368 ... |
1348 | 1369 |
1349 void | 1370 void |
1350 syms_of_toolbar (void) | 1371 syms_of_toolbar (void) |
1351 { | 1372 { |
1352 INIT_LRECORD_IMPLEMENTATION (toolbar_button); | 1373 INIT_LISP_OBJECT (toolbar_button); |
1353 | 1374 |
1354 ...; | 1375 ...; |
1355 } | 1376 } |
1356 | 1377 |
1357 ------------------------------ in inline.c ----------------------------- | 1378 ------------------------------ in inline.c ----------------------------- |
1376 | 1397 |
1377 /* | 1398 /* |
1378 | 1399 |
1379 Note: Object types defined in external dynamically-loaded modules (not | 1400 Note: Object types defined in external dynamically-loaded modules (not |
1380 part of the XEmacs main source code) should use DECLARE_EXTERNAL_LRECORD | 1401 part of the XEmacs main source code) should use DECLARE_EXTERNAL_LRECORD |
1381 and DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION rather than DECLARE_LRECORD | 1402 and DEFINE_EXTERNAL_LISP_OBJECT rather than DECLARE_LRECORD |
1382 and DEFINE_LRECORD_IMPLEMENTATION. The EXTERNAL versions declare and | 1403 and DEFINE_LISP_OBJECT. The EXTERNAL versions declare and |
1383 allocate an enumerator for the type being defined. | 1404 allocate an enumerator for the type being defined. |
1384 | 1405 |
1385 */ | 1406 */ |
1386 | 1407 |
1387 | 1408 |
1518 #define CHECK_NONRECORD(x, lisp_enum, predicate) do { \ | 1539 #define CHECK_NONRECORD(x, lisp_enum, predicate) do { \ |
1519 if (XTYPE (x) != lisp_enum) \ | 1540 if (XTYPE (x) != lisp_enum) \ |
1520 dead_wrong_type_argument (predicate, x); \ | 1541 dead_wrong_type_argument (predicate, x); \ |
1521 } while (0) | 1542 } while (0) |
1522 | 1543 |
1544 /* How to allocate a Lisp object: | |
1545 | |
1546 - For most objects, simply call ALLOC_LISP_OBJECT (type), where TYPE is | |
1547 the name of the type (e.g. toolbar_button). Such objects can be freed | |
1548 manually using FREE_LCRECORD. | |
1549 | |
1550 - For objects whose size can vary (and hence which have a | |
1551 size_in_bytes_method rather than a static_size), call | |
1552 ALLOC_SIZED_LISP_OBJECT (size, type), where TYPE is the | |
1553 name of the type. NOTE: You cannot call FREE_LCRECORD() on such | |
1554 on object! (At least when not MC_ALLOC) | |
1555 | |
1556 - Basic lrecords (of which there are a limited number, which exist only | |
1557 when not MC_ALLOC, and which have special handling in alloc.c) need | |
1558 special handling; if you don't understand this, just ignore it. | |
1559 | |
1560 - Some lrecords, which are used totally internally, use the | |
1561 noseeum-* functions for the reason of debugging. | |
1562 */ | |
1563 | |
1523 #ifndef MC_ALLOC | 1564 #ifndef MC_ALLOC |
1524 /*-------------------------- lcrecord-list -----------------------------*/ | 1565 /*-------------------------- lcrecord-list -----------------------------*/ |
1525 | 1566 |
1526 struct lcrecord_list | 1567 struct lcrecord_list |
1527 { | 1568 { |
1558 they only handle blocks of a particular, fixed size. Thus, objects that | 1599 they only handle blocks of a particular, fixed size. Thus, objects that |
1559 can be of varying sizes need to do various tricks. These considerations | 1600 can be of varying sizes need to do various tricks. These considerations |
1560 in particular dictate the various types of management: | 1601 in particular dictate the various types of management: |
1561 | 1602 |
1562 -- "Auto-managed" means that you just go ahead and allocate the lcrecord | 1603 -- "Auto-managed" means that you just go ahead and allocate the lcrecord |
1563 whenever you want, using old_alloc_lcrecord_type(), and the appropriate | 1604 whenever you want, using ALLOC_LISP_OBJECT(), and the appropriate |
1564 lcrecord-list manager is automatically created. To free, you just call | 1605 lcrecord-list manager is automatically created. To free, you just call |
1565 "FREE_LCRECORD()" and the appropriate lcrecord-list manager is | 1606 "FREE_LCRECORD()" and the appropriate lcrecord-list manager is |
1566 automatically located and called. The limitation here of course is that | 1607 automatically located and called. The limitation here of course is that |
1567 all your objects are of the same size. (#### Eventually we should have a | 1608 all your objects are of the same size. (#### Eventually we should have a |
1568 more sophisticated system that tracks the sizes seen and creates one | 1609 more sophisticated system that tracks the sizes seen and creates one |
1581 lcrecord-lists, no way to free them. This may be suitable when the | 1622 lcrecord-lists, no way to free them. This may be suitable when the |
1582 lcrecords are variable-sized and (a) you're too lazy to write the code | 1623 lcrecords are variable-sized and (a) you're too lazy to write the code |
1583 to hand-manage them, or (b) the objects you create are always or almost | 1624 to hand-manage them, or (b) the objects you create are always or almost |
1584 always Lisp-visible, and thus there's no point in freeing them (and it | 1625 always Lisp-visible, and thus there's no point in freeing them (and it |
1585 wouldn't be safe to do so). You just create them with | 1626 wouldn't be safe to do so). You just create them with |
1586 BASIC_ALLOC_LCRECORD(), and that's it. | 1627 ALLOC_SIZED_LISP_OBJECT(), and that's it. |
1587 | 1628 |
1588 --ben | 1629 --ben |
1589 | 1630 |
1590 Here is an in-depth look at the steps required to create a allocate an | 1631 Here is an in-depth look at the steps required to create a allocate an |
1591 lcrecord using the hand-managed style. Since this is the most | 1632 lcrecord using the hand-managed style. Since this is the most |
1594 lcrecord really entails, and what are the precautions: | 1635 lcrecord really entails, and what are the precautions: |
1595 | 1636 |
1596 1) Create an lcrecord-list object using make_lcrecord_list(). This is | 1637 1) Create an lcrecord-list object using make_lcrecord_list(). This is |
1597 often done at initialization. Remember to staticpro_nodump() this | 1638 often done at initialization. Remember to staticpro_nodump() this |
1598 object! The arguments to make_lcrecord_list() are the same as would be | 1639 object! The arguments to make_lcrecord_list() are the same as would be |
1599 passed to BASIC_ALLOC_LCRECORD(). | 1640 passed to ALLOC_SIZED_LISP_OBJECT(). |
1600 | 1641 |
1601 2) Instead of calling BASIC_ALLOC_LCRECORD(), call alloc_managed_lcrecord() | 1642 2) Instead of calling ALLOC_SIZED_LISP_OBJECT(), call |
1602 and pass the lcrecord-list earlier created. | 1643 alloc_managed_lcrecord() and pass the lcrecord-list earlier created. |
1603 | 1644 |
1604 3) When done with the lcrecord, call free_managed_lcrecord(). The | 1645 3) When done with the lcrecord, call free_managed_lcrecord(). The |
1605 standard freeing caveats apply: ** make sure there are no pointers to | 1646 standard freeing caveats apply: ** make sure there are no pointers to |
1606 the object anywhere! ** | 1647 the object anywhere! ** |
1607 | 1648 |
1608 4) Calling free_managed_lcrecord() is just like kissing the | 1649 4) Calling free_managed_lcrecord() is just like kissing the |
1609 lcrecord goodbye as if it were garbage-collected. This means: | 1650 lcrecord goodbye as if it were garbage-collected. This means: |
1610 -- the contents of the freed lcrecord are undefined, and the | 1651 -- the contents of the freed lcrecord are undefined, and the |
1611 contents of something produced by alloc_managed_lcrecord() | 1652 contents of something produced by alloc_managed_lcrecord() |
1612 are undefined, just like for BASIC_ALLOC_LCRECORD(). | 1653 are undefined, just like for ALLOC_SIZED_LISP_OBJECT(). |
1613 -- the mark method for the lcrecord's type will *NEVER* be called | 1654 -- the mark method for the lcrecord's type will *NEVER* be called |
1614 on freed lcrecords. | 1655 on freed lcrecords. |
1615 -- the finalize method for the lcrecord's type will be called | 1656 -- the finalize method for the lcrecord's type will be called |
1616 at the time that free_managed_lcrecord() is called. | 1657 at the time that free_managed_lcrecord() is called. |
1617 */ | 1658 */ |
1618 | 1659 |
1619 /* UNMANAGED MODEL: */ | 1660 /* UNMANAGED MODEL: */ |
1620 void *old_basic_alloc_lcrecord (Bytecount size, | 1661 Lisp_Object old_alloc_lcrecord (const struct lrecord_implementation *); |
1621 const struct lrecord_implementation *); | 1662 Lisp_Object old_alloc_sized_lcrecord (Bytecount size, |
1663 const struct lrecord_implementation *); | |
1622 | 1664 |
1623 /* HAND-MANAGED MODEL: */ | 1665 /* HAND-MANAGED MODEL: */ |
1624 Lisp_Object make_lcrecord_list (Elemcount size, | 1666 Lisp_Object make_lcrecord_list (Elemcount size, |
1625 const struct lrecord_implementation | 1667 const struct lrecord_implementation |
1626 *implementation); | 1668 *implementation); |
1627 Lisp_Object alloc_managed_lcrecord (Lisp_Object lcrecord_list); | 1669 Lisp_Object alloc_managed_lcrecord (Lisp_Object lcrecord_list); |
1628 void free_managed_lcrecord (Lisp_Object lcrecord_list, Lisp_Object lcrecord); | 1670 void free_managed_lcrecord (Lisp_Object lcrecord_list, Lisp_Object lcrecord); |
1629 | 1671 |
1630 /* AUTO-MANAGED MODEL: */ | 1672 /* AUTO-MANAGED MODEL: */ |
1631 MODULE_API void * | 1673 MODULE_API Lisp_Object |
1632 alloc_automanaged_lcrecord (Bytecount size, | 1674 alloc_automanaged_lcrecord (Bytecount size, |
1633 const struct lrecord_implementation *); | 1675 const struct lrecord_implementation *); |
1634 | 1676 |
1635 #define old_alloc_lcrecord_type(type, lrecord_implementation) \ | 1677 #define old_alloc_lcrecord_type(type, imp) \ |
1636 ((type *) alloc_automanaged_lcrecord (sizeof (type), lrecord_implementation)) | 1678 ((type *) XPNTR (alloc_automanaged_lcrecord (sizeof (type), imp))) |
1637 | 1679 |
1638 void old_free_lcrecord (Lisp_Object rec); | 1680 void old_free_lcrecord (Lisp_Object rec); |
1639 | 1681 |
1640 | 1682 |
1641 /* Copy the data from one lcrecord structure into another, but don't | 1683 /* Copy the data from one lcrecord structure into another, but don't |
1655 | 1697 |
1656 #define old_zero_lcrecord(lcr) old_zero_sized_lcrecord (lcr, sizeof (*(lcr))) | 1698 #define old_zero_lcrecord(lcr) old_zero_sized_lcrecord (lcr, sizeof (*(lcr))) |
1657 | 1699 |
1658 #else /* MC_ALLOC */ | 1700 #else /* MC_ALLOC */ |
1659 | 1701 |
1660 /* How to allocate a lrecord: | 1702 Lisp_Object alloc_sized_lrecord (Bytecount size, |
1661 | 1703 const struct lrecord_implementation *imp); |
1662 - If the size of the lrecord is fix, say it equals its size of its | 1704 Lisp_Object noseeum_alloc_sized_lrecord (Bytecount size, |
1663 struct, then use alloc_lrecord_type. | 1705 const struct lrecord_implementation *); |
1664 | 1706 Lisp_Object alloc_lrecord (const struct lrecord_implementation *imp); |
1665 - If the size varies, i.e. it is not equal to the size of its | 1707 |
1666 struct, use alloc_lrecord and specify the amount of storage you | 1708 #define alloc_lrecord_type(type, imp) \ |
1667 need for the object. | 1709 ((type *) XPNTR (alloc_sized_lrecord (sizeof (type), imp))) |
1668 | |
1669 - Some lrecords, which are used totally internally, use the | |
1670 noseeum-* functions for the reason of debugging. | |
1671 | |
1672 - To free a Lisp_Object manually, use free_lrecord. */ | |
1673 | |
1674 void *alloc_lrecord (Bytecount size, | |
1675 const struct lrecord_implementation *); | |
1676 | |
1677 #define alloc_lrecord_type(type, lrecord_implementation) \ | |
1678 ((type *) alloc_lrecord (sizeof (type), lrecord_implementation)) | |
1679 | 1710 |
1680 void *noseeum_alloc_lrecord (Bytecount size, | 1711 void *noseeum_alloc_lrecord (Bytecount size, |
1681 const struct lrecord_implementation *); | 1712 const struct lrecord_implementation *); |
1682 | 1713 |
1683 #define noseeum_alloc_lrecord_type(type, lrecord_implementation) \ | 1714 #define noseeum_alloc_lrecord_type(type, imp) \ |
1684 ((type *) noseeum_alloc_lrecord (sizeof (type), lrecord_implementation)) | 1715 ((type *) XPNTR (noseeum_alloc_sized_lrecord (sizeof (type), imp))) |
1685 | 1716 |
1686 void free_lrecord (Lisp_Object rec); | 1717 void free_lrecord (Lisp_Object rec); |
1687 | 1718 |
1688 | 1719 |
1689 /* Copy the data from one lrecord structure into another, but don't | 1720 /* Copy the data from one lrecord structure into another, but don't |