* objects.c, objects.h (scm_mcache_lookup_cmethod): Moved here
[bpt/guile.git] / libguile / smob.c
CommitLineData
7dc6e754 1/* Copyright (C) 1995,1996,1998 Free Software Foundation, Inc.
0f2d19dd
JB
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
0f2d19dd
JB
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
82892bed 40 * If you do not wish that, delete this exception notice. */
0f2d19dd
JB
41\f
42
43#include <stdio.h>
44#include "_scm.h"
20e6290e 45
d7ec6b9f
MD
46#include "objects.h"
47
0f2d19dd
JB
48#ifdef HAVE_MALLOC_H
49#include <malloc.h>
50#endif
51
9dd5943c
MD
52#include "smob.h"
53
0f2d19dd
JB
54\f
55
56/* scm_smobs scm_numsmob
57 * implement a dynamicly resized array of smob records.
58 * Indexes into this table are used when generating type
59 * tags for smobjects (if you know a tag you can get an index and conversely).
60 */
4e6e2119 61int scm_numsmob;
9dd5943c 62scm_smob_descriptor *scm_smobs;
0f2d19dd 63
9dd5943c
MD
64/* {Mark}
65 */
66
67/* This function is vestigial. It used to be the mark function's
68 responsibility to set the mark bit on the smob or port, but now the
69 generic marking routine in gc.c takes care of that, and a zero
70 pointer for a mark function means "don't bother". So you never
71 need scm_mark0.
72
73 However, we leave it here because it's harmless to call it, and
74 people out there have smob code that uses it, and there's no reason
75 to make their links fail. */
76
77SCM
78scm_mark0 (ptr)
79 SCM ptr;
80{
81 return SCM_BOOL_F;
82}
83
84SCM
85scm_markcdr (ptr)
86 SCM ptr;
87{
88 return SCM_CDR (ptr);
89}
90
91/* {Free}
92 */
93
94scm_sizet
95scm_free0 (ptr)
96 SCM ptr;
97{
98 return 0;
99}
100
101scm_sizet
102scm_smob_free (SCM obj)
103{
104 scm_must_free ((char *) SCM_CDR (obj));
105 return scm_smobs[SCM_SMOBNUM (obj)].size;
106}
107
108/* {Print}
109 */
110
111int
112scm_smob_print (SCM exp, SCM port, scm_print_state *pstate)
113{
114 int n = SCM_SMOBNUM (exp);
115 scm_puts ("#<", port);
2c16a78a 116 scm_puts (SCM_SMOBNAME (n) ? SCM_SMOBNAME (n) : "smob", port);
9dd5943c
MD
117 scm_putc (' ', port);
118 scm_intprint (scm_smobs[n].size ? SCM_CDR (exp) : exp, 16, port);
119 scm_putc ('>', port);
120 return 1;
121}
1cc91f1b 122
0f2d19dd 123long
9dd5943c 124scm_make_smob_type (char *name, scm_sizet size)
0f2d19dd
JB
125{
126 char *tmp;
127 if (255 <= scm_numsmob)
128 goto smoberr;
129 SCM_DEFER_INTS;
9dd5943c
MD
130 SCM_SYSCALL (tmp = (char *) realloc ((char *) scm_smobs,
131 (1 + scm_numsmob)
132 * sizeof (scm_smob_descriptor)));
0f2d19dd
JB
133 if (tmp)
134 {
9dd5943c
MD
135 scm_smobs = (scm_smob_descriptor *) tmp;
136 scm_smobs[scm_numsmob].name = name;
137 scm_smobs[scm_numsmob].size = size;
138 scm_smobs[scm_numsmob].mark = 0;
139 scm_smobs[scm_numsmob].free = (size == 0 ? scm_free0 : scm_smob_free);
140 scm_smobs[scm_numsmob].print = scm_smob_print;
141 scm_smobs[scm_numsmob].equalp = 0;
0f2d19dd
JB
142 scm_numsmob++;
143 }
144 SCM_ALLOW_INTS;
145 if (!tmp)
9dd5943c
MD
146 smoberr:scm_wta (SCM_MAKINUM ((long) scm_numsmob),
147 (char *) SCM_NALLOC, "scm_make_smob_type");
d7ec6b9f
MD
148 /* Make a class object if Goops is present. */
149 if (scm_smob_class)
150 scm_smob_class[scm_numsmob - 1]
151 = scm_make_extended_class (SCM_SMOBNAME (scm_numsmob - 1));
0f2d19dd
JB
152 return scm_tc7_smob + (scm_numsmob - 1) * 256;
153}
154
23a62151
MD
155long
156scm_make_smob_type_mfpe (char *name, scm_sizet size,
157 SCM (*mark) (SCM),
158 scm_sizet (*free) (SCM),
159 int (*print) (SCM, SCM, scm_print_state *),
160 SCM (*equalp) (SCM, SCM))
161{
162 long answer = scm_make_smob_type (name, size);
163 scm_set_smob_mfpe (answer, mark, free, print, equalp);
164 return answer;
165}
166
9dd5943c
MD
167void
168scm_set_smob_mark (long tc, SCM (*mark) (SCM))
169{
170 scm_smobs[SCM_TC2SMOBNUM (tc)].mark = mark;
171}
172
173void
174scm_set_smob_free (long tc, scm_sizet (*free) (SCM))
175{
176 scm_smobs[SCM_TC2SMOBNUM (tc)].free = free;
177}
178
179void
180scm_set_smob_print (long tc, int (*print) (SCM, SCM, scm_print_state*))
181{
182 scm_smobs[SCM_TC2SMOBNUM (tc)].print = print;
183}
184
185void
186scm_set_smob_equalp (long tc, SCM (*equalp) (SCM, SCM))
187{
188 scm_smobs[SCM_TC2SMOBNUM (tc)].equalp = equalp;
189}
190
23a62151
MD
191void
192scm_set_smob_mfpe (long tc,
193 SCM (*mark) (SCM),
194 scm_sizet (*free) (SCM),
195 int (*print) (SCM, SCM, scm_print_state *),
196 SCM (*equalp) (SCM, SCM))
197{
198 if (mark) scm_set_smob_mark (tc, mark);
199 if (free) scm_set_smob_free (tc, free);
200 if (print) scm_set_smob_print (tc, print);
201 if (equalp) scm_set_smob_equalp (tc, equalp);
202}
203
204/* Deprecated function - use scm_make_smob_type, or scm_make_smob_type_mfpe
205 instead. */
9dd5943c
MD
206long
207scm_newsmob (const scm_smobfuns *smob)
208{
209 long tc = scm_make_smob_type (0, 0);
210 scm_set_smob_mark (tc, smob->mark);
211 scm_set_smob_free (tc, smob->free);
212 scm_set_smob_print (tc, smob->print);
213 scm_set_smob_equalp (tc, smob->equalp);
214 return tc;
215}
216
217
218SCM
219scm_make_smob (long tc)
220{
221 int n = SCM_TC2SMOBNUM (tc);
222 scm_sizet size = scm_smobs[n].size;
223 SCM z;
224 SCM_NEWCELL (z);
225 if (size != 0)
226 {
227#if 0
228 SCM_ASSERT (scm_smobs[n].mark == 0,
229 0,
230 "forbidden operation for smobs with GC data, use SCM_NEWSMOB",
231 SCM_SMOBNAME (n));
232#endif
233 SCM_SET_SMOB_DATA (z, scm_must_malloc (size, SCM_SMOBNAME (n)));
234 }
235 SCM_SETCAR (z, tc);
236 return z;
237}
238
ceef3208 239\f
0f2d19dd
JB
240/* {Initialization for i/o types, float, bignum, the type of free cells}
241 */
242
ceef3208
JB
243static int
244freeprint (SCM exp,
245 SCM port,
246 scm_print_state *pstate)
247{
248 char buf[100];
249
250 sprintf (buf, "#<freed cell %p; GC missed a reference>", (void *) exp);
251 scm_puts (buf, port);
252
253 return 1;
254}
255
256
0f2d19dd
JB
257void
258scm_smob_prehistory ()
0f2d19dd
JB
259{
260 scm_numsmob = 0;
9dd5943c
MD
261 scm_smobs = ((scm_smob_descriptor *)
262 malloc (7 * sizeof (scm_smob_descriptor)));
263
264 /* WARNING: These scm_make_smob_type calls must be done in this order */
23a62151
MD
265 scm_make_smob_type_mfpe ("free", 0,
266 NULL, NULL, freeprint, NULL);
267
268 scm_make_smob_type_mfpe ("flo", 0, /* freed in gc */
269 NULL, NULL, scm_floprint, scm_floequal);
270
271 scm_make_smob_type_mfpe ("bigpos", 0, /* freed in gc */
272 NULL, NULL, scm_bigprint, scm_bigequal);
273
274 scm_make_smob_type_mfpe ("bigneg", 0,
275 NULL, NULL, scm_bigprint, scm_bigequal);
0f2d19dd 276}