Mercurial > hg > xemacs-beta
annotate src/opaque.c @ 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 | 1e7cc382eb16 |
children | e0db3c197671 |
rev | line source |
---|---|
428 | 1 /* Opaque Lisp objects. |
2 Copyright (C) 1993, 1994, 1995 Sun Microsystems, Inc. | |
800 | 3 Copyright (C) 1995, 1996, 2002 Ben Wing. |
428 | 4 |
5 This file is part of XEmacs. | |
6 | |
7 XEmacs is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 2, or (at your option) any | |
10 later version. | |
11 | |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with XEmacs; see the file COPYING. If not, write to | |
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 Boston, MA 02111-1307, USA. */ | |
21 | |
22 /* Synched up with: Not in FSF. */ | |
23 | |
24 /* Written by Ben Wing, October 1993. */ | |
25 | |
26 /* "Opaque" is used internally to hold keep track of allocated memory | |
27 so it gets GC'd properly, and to store arbitrary data in places | |
28 where a Lisp_Object is required and which may get GC'd. (e.g. as | |
29 the argument to record_unwind_protect()). Once created in C, | |
30 opaque objects cannot be resized. | |
31 | |
32 OPAQUE OBJECTS SHOULD NEVER ESCAPE TO THE LISP LEVEL. Some code | |
33 depends on this. As such, opaque objects are a generalization | |
34 of the Qunbound marker. | |
35 */ | |
36 | |
37 #include <config.h> | |
38 #include "lisp.h" | |
39 #include "opaque.h" | |
40 | |
2720 | 41 #ifndef MC_ALLOC |
428 | 42 Lisp_Object Vopaque_ptr_free_list; |
2720 | 43 #endif /* not MC_ALLOC */ |
428 | 44 |
45 /* Should never, ever be called. (except by an external debugger) */ | |
46 static void | |
2286 | 47 print_opaque (Lisp_Object obj, Lisp_Object printcharfun, |
48 int UNUSED (escapeflag)) | |
428 | 49 { |
442 | 50 const Lisp_Opaque *p = XOPAQUE (obj); |
428 | 51 |
800 | 52 write_fmt_string |
53 (printcharfun, | |
54 "#<INTERNAL OBJECT (XEmacs bug?) (opaque, size=%lu) 0x%lx>", | |
55 (long)(p->size), (unsigned long) p); | |
428 | 56 } |
57 | |
665 | 58 inline static Bytecount |
59 aligned_sizeof_opaque (Bytecount opaque_size) | |
456 | 60 { |
826 | 61 return MAX_ALIGN_SIZE (offsetof (Lisp_Opaque, data) + opaque_size); |
456 | 62 } |
63 | |
665 | 64 static Bytecount |
442 | 65 sizeof_opaque (const void *header) |
428 | 66 { |
456 | 67 return aligned_sizeof_opaque (((const Lisp_Opaque *) header)->size); |
428 | 68 } |
69 | |
70 /* Return an opaque object of size SIZE. | |
71 If DATA is OPAQUE_CLEAR, the object's data is memset to '\0' bytes. | |
72 If DATA is OPAQUE_UNINIT, the object's data is uninitialized. | |
73 Else the object's data is initialized by copying from DATA. */ | |
74 Lisp_Object | |
665 | 75 make_opaque (const void *data, Bytecount size) |
428 | 76 { |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
77 Lisp_Object obj = |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
78 ALLOC_SIZED_LISP_OBJECT (aligned_sizeof_opaque (size), opaque); |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
79 Lisp_Opaque *p = XOPAQUE (obj); |
428 | 80 p->size = size; |
81 | |
82 if (data == OPAQUE_CLEAR) | |
83 memset (p->data, '\0', size); | |
84 else if (data == OPAQUE_UNINIT) | |
85 DO_NOTHING; | |
86 else | |
87 memcpy (p->data, data, size); | |
88 | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
89 return obj; |
428 | 90 } |
91 | |
92 /* This will not work correctly for opaques with subobjects! */ | |
93 | |
94 static int | |
2286 | 95 equal_opaque (Lisp_Object obj1, Lisp_Object obj2, int UNUSED (depth)) |
428 | 96 { |
665 | 97 Bytecount size; |
428 | 98 return ((size = XOPAQUE_SIZE (obj1)) == XOPAQUE_SIZE (obj2) && |
99 !memcmp (XOPAQUE_DATA (obj1), XOPAQUE_DATA (obj2), size)); | |
100 } | |
101 | |
102 /* This will not work correctly for opaques with subobjects! */ | |
103 | |
2515 | 104 static Hashcode |
2286 | 105 hash_opaque (Lisp_Object obj, int UNUSED (depth)) |
428 | 106 { |
107 if (XOPAQUE_SIZE (obj) == sizeof (unsigned long)) | |
2515 | 108 return *((Hashcode *) XOPAQUE_DATA (obj)); |
428 | 109 else |
110 return memory_hash (XOPAQUE_DATA (obj), XOPAQUE_SIZE (obj)); | |
111 } | |
112 | |
1204 | 113 static const struct memory_description opaque_description[] = { |
428 | 114 { XD_END } |
115 }; | |
116 | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
117 DEFINE_SIZABLE_LISP_OBJECT ("opaque", opaque, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
118 0, print_opaque, 0, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
119 equal_opaque, hash_opaque, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
120 opaque_description, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
121 sizeof_opaque, Lisp_Opaque); |
428 | 122 |
123 /* stuff to handle opaque pointers */ | |
124 | |
125 /* Should never, ever be called. (except by an external debugger) */ | |
126 static void | |
2286 | 127 print_opaque_ptr (Lisp_Object obj, Lisp_Object printcharfun, |
128 int UNUSED (escapeflag)) | |
428 | 129 { |
442 | 130 const Lisp_Opaque_Ptr *p = XOPAQUE_PTR (obj); |
428 | 131 |
800 | 132 write_fmt_string |
133 (printcharfun, | |
134 "#<INTERNAL OBJECT (XEmacs bug?) (opaque-ptr, adr=0x%lx) 0x%lx>", | |
135 (long)(p->ptr), (unsigned long) p); | |
428 | 136 } |
137 | |
138 static int | |
2286 | 139 equal_opaque_ptr (Lisp_Object obj1, Lisp_Object obj2, int UNUSED (depth)) |
428 | 140 { |
141 return (XOPAQUE_PTR (obj1)->ptr == XOPAQUE_PTR (obj2)->ptr); | |
142 } | |
143 | |
2515 | 144 static Hashcode |
2286 | 145 hash_opaque_ptr (Lisp_Object obj, int UNUSED (depth)) |
428 | 146 { |
2515 | 147 return (Hashcode) XOPAQUE_PTR (obj)->ptr; |
428 | 148 } |
149 | |
1575 | 150 static const struct memory_description opaque_ptr_description[] = { |
151 { XD_END } | |
152 }; | |
153 | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
154 DEFINE_NONDUMPABLE_LISP_OBJECT ("opaque-ptr", opaque_ptr, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
155 0, print_opaque_ptr, 0, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
156 equal_opaque_ptr, hash_opaque_ptr, |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
157 opaque_ptr_description, Lisp_Opaque_Ptr); |
428 | 158 |
159 Lisp_Object | |
160 make_opaque_ptr (void *val) | |
161 { | |
2720 | 162 #ifdef MC_ALLOC |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
163 Lisp_Object res = ALLOC_LISP_OBJECT (opaque_ptr); |
2720 | 164 #else /* not MC_ALLOC */ |
1204 | 165 Lisp_Object res = alloc_managed_lcrecord (Vopaque_ptr_free_list); |
2720 | 166 #endif /* not MC_ALLOC */ |
428 | 167 set_opaque_ptr (res, val); |
168 return res; | |
169 } | |
170 | |
171 /* Be very very careful with this. Same admonitions as with | |
172 free_cons() apply. */ | |
173 | |
174 void | |
175 free_opaque_ptr (Lisp_Object ptr) | |
176 { | |
2720 | 177 #ifdef MC_ALLOC |
178 free_lrecord (ptr); | |
179 #else /* not MC_ALLOC */ | |
428 | 180 free_managed_lcrecord (Vopaque_ptr_free_list, ptr); |
2720 | 181 #endif /* not MC_ALLOC */ |
428 | 182 } |
183 | |
2720 | 184 #ifndef MC_ALLOC |
428 | 185 void |
1204 | 186 reinit_opaque_early (void) |
428 | 187 { |
647 | 188 Vopaque_ptr_free_list = make_lcrecord_list (sizeof (Lisp_Opaque_Ptr), |
189 &lrecord_opaque_ptr); | |
428 | 190 staticpro_nodump (&Vopaque_ptr_free_list); |
191 } | |
2720 | 192 #endif /* not MC_ALLOC */ |
428 | 193 |
194 void | |
195 init_opaque_once_early (void) | |
196 { | |
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
197 INIT_LISP_OBJECT (opaque); |
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3017
diff
changeset
|
198 INIT_LISP_OBJECT (opaque_ptr); |
442 | 199 |
2720 | 200 #ifndef MC_ALLOC |
1204 | 201 reinit_opaque_early (); |
2720 | 202 #endif /* not MC_ALLOC */ |
428 | 203 } |