Mercurial > hg > xemacs-beta
comparison src/opaque.c @ 428:3ecd8885ac67 r21-2-22
Import from CVS: tag r21-2-22
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:28:15 +0200 |
parents | |
children | 8de8e3f6228a |
comparison
equal
deleted
inserted
replaced
427:0a0253eac470 | 428:3ecd8885ac67 |
---|---|
1 /* Opaque Lisp objects. | |
2 Copyright (C) 1993, 1994, 1995 Sun Microsystems, Inc. | |
3 Copyright (C) 1995, 1996 Ben Wing. | |
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 | |
41 Lisp_Object Vopaque_ptr_free_list; | |
42 | |
43 /* Should never, ever be called. (except by an external debugger) */ | |
44 static void | |
45 print_opaque (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
46 { | |
47 CONST Lisp_Opaque *p = XOPAQUE (obj); | |
48 char buf[200]; | |
49 | |
50 sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (opaque, size=%lu) 0x%lx>", | |
51 (long)(p->size), (unsigned long) p); | |
52 write_c_string (buf, printcharfun); | |
53 } | |
54 | |
55 static size_t | |
56 sizeof_opaque (CONST void *header) | |
57 { | |
58 CONST Lisp_Opaque *p = (CONST Lisp_Opaque *) header; | |
59 return offsetof (Lisp_Opaque, data) + p->size; | |
60 } | |
61 | |
62 /* Return an opaque object of size SIZE. | |
63 If DATA is OPAQUE_CLEAR, the object's data is memset to '\0' bytes. | |
64 If DATA is OPAQUE_UNINIT, the object's data is uninitialized. | |
65 Else the object's data is initialized by copying from DATA. */ | |
66 Lisp_Object | |
67 make_opaque (size_t size, CONST void *data) | |
68 { | |
69 Lisp_Opaque *p = (Lisp_Opaque *) | |
70 alloc_lcrecord (offsetof (Lisp_Opaque, data) + size, &lrecord_opaque); | |
71 p->size = size; | |
72 | |
73 if (data == OPAQUE_CLEAR) | |
74 memset (p->data, '\0', size); | |
75 else if (data == OPAQUE_UNINIT) | |
76 DO_NOTHING; | |
77 else | |
78 memcpy (p->data, data, size); | |
79 | |
80 { | |
81 Lisp_Object val; | |
82 XSETOPAQUE (val, p); | |
83 return val; | |
84 } | |
85 } | |
86 | |
87 /* This will not work correctly for opaques with subobjects! */ | |
88 | |
89 static int | |
90 equal_opaque (Lisp_Object obj1, Lisp_Object obj2, int depth) | |
91 { | |
92 size_t size; | |
93 return ((size = XOPAQUE_SIZE (obj1)) == XOPAQUE_SIZE (obj2) && | |
94 !memcmp (XOPAQUE_DATA (obj1), XOPAQUE_DATA (obj2), size)); | |
95 } | |
96 | |
97 /* This will not work correctly for opaques with subobjects! */ | |
98 | |
99 static unsigned long | |
100 hash_opaque (Lisp_Object obj, int depth) | |
101 { | |
102 if (XOPAQUE_SIZE (obj) == sizeof (unsigned long)) | |
103 return *((unsigned long *) XOPAQUE_DATA (obj)); | |
104 else | |
105 return memory_hash (XOPAQUE_DATA (obj), XOPAQUE_SIZE (obj)); | |
106 } | |
107 | |
108 static const struct lrecord_description opaque_description[] = { | |
109 { XD_END } | |
110 }; | |
111 | |
112 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("opaque", opaque, | |
113 0, print_opaque, 0, | |
114 equal_opaque, hash_opaque, | |
115 opaque_description, | |
116 sizeof_opaque, Lisp_Opaque); | |
117 | |
118 /* stuff to handle opaque pointers */ | |
119 | |
120 /* Should never, ever be called. (except by an external debugger) */ | |
121 static void | |
122 print_opaque_ptr (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
123 { | |
124 CONST Lisp_Opaque_Ptr *p = XOPAQUE_PTR (obj); | |
125 char buf[200]; | |
126 | |
127 sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (opaque_ptr, adr=0x%lx) 0x%lx>", | |
128 (long)(p->ptr), (unsigned long) p); | |
129 write_c_string (buf, printcharfun); | |
130 } | |
131 | |
132 static int | |
133 equal_opaque_ptr (Lisp_Object obj1, Lisp_Object obj2, int depth) | |
134 { | |
135 return (XOPAQUE_PTR (obj1)->ptr == XOPAQUE_PTR (obj2)->ptr); | |
136 } | |
137 | |
138 static unsigned long | |
139 hash_opaque_ptr (Lisp_Object obj, int depth) | |
140 { | |
141 return (unsigned long) XOPAQUE_PTR (obj)->ptr; | |
142 } | |
143 | |
144 DEFINE_LRECORD_IMPLEMENTATION ("opaque_ptr", opaque_ptr, | |
145 0, print_opaque_ptr, 0, | |
146 equal_opaque_ptr, hash_opaque_ptr, 0, | |
147 Lisp_Opaque_Ptr); | |
148 | |
149 Lisp_Object | |
150 make_opaque_ptr (void *val) | |
151 { | |
152 Lisp_Object res = allocate_managed_lcrecord(Vopaque_ptr_free_list); | |
153 set_opaque_ptr (res, val); | |
154 return res; | |
155 } | |
156 | |
157 /* Be very very careful with this. Same admonitions as with | |
158 free_cons() apply. */ | |
159 | |
160 void | |
161 free_opaque_ptr (Lisp_Object ptr) | |
162 { | |
163 free_managed_lcrecord (Vopaque_ptr_free_list, ptr); | |
164 } | |
165 | |
166 void | |
167 reinit_opaque_once_early (void) | |
168 { | |
169 Vopaque_ptr_free_list = make_lcrecord_list (sizeof (Lisp_Opaque_Ptr), &lrecord_opaque_ptr); | |
170 staticpro_nodump (&Vopaque_ptr_free_list); | |
171 } | |
172 | |
173 void | |
174 init_opaque_once_early (void) | |
175 { | |
176 reinit_opaque_once_early (); | |
177 } |