1 /* Copyright (C) 1995,1996,1998,1999,2000,2001, 2003 Free Software Foundation, Inc.
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
8 * This library 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 GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "libguile/_scm.h"
29 #include "libguile/objects.h"
30 #include "libguile/ports.h"
36 #include "libguile/smob.h"
40 /* scm_smobs scm_numsmob
41 * implement a fixed sized array of smob records.
42 * Indexes into this table are used when generating type
43 * tags for smobjects (if you know a tag you can get an index and conversely).
46 #define MAX_SMOB_COUNT 256
48 scm_smob_descriptor scm_smobs
[MAX_SMOB_COUNT
];
53 /* This function is vestigial. It used to be the mark function's
54 responsibility to set the mark bit on the smob or port, but now the
55 generic marking routine in gc.c takes care of that, and a zero
56 pointer for a mark function means "don't bother". So you never
59 However, we leave it here because it's harmless to call it, and
60 people out there have smob code that uses it, and there's no reason
61 to make their links fail. */
64 scm_mark0 (SCM ptr SCM_UNUSED
)
70 /* Dirk::FIXME: The name markcdr is misleading, since the term cdr should only
71 be used for real pairs. */
74 return SCM_CELL_OBJECT_1 (ptr
);
81 scm_free0 (SCM ptr SCM_UNUSED
)
87 scm_smob_free (SCM obj
)
89 long n
= SCM_SMOBNUM (obj
);
90 if (scm_smobs
[n
].size
> 0)
91 scm_gc_free ((void *) SCM_CELL_WORD_1 (obj
),
92 scm_smobs
[n
].size
, SCM_SMOBNAME (n
));
100 scm_smob_print (SCM exp
, SCM port
, scm_print_state
*pstate SCM_UNUSED
)
102 long n
= SCM_SMOBNUM (exp
);
103 scm_puts ("#<", port
);
104 scm_puts (SCM_SMOBNAME (n
) ? SCM_SMOBNAME (n
) : "smob", port
);
105 scm_putc (' ', port
);
106 if (scm_smobs
[n
].size
)
107 scm_intprint (SCM_CELL_WORD_1 (exp
), 16, port
);
109 scm_intprint (SCM_UNPACK (exp
), 16, port
);
110 scm_putc ('>', port
);
117 #define SCM_SMOB_APPLY0(SMOB) \
118 SCM_SMOB_DESCRIPTOR (SMOB).apply (SMOB)
119 #define SCM_SMOB_APPLY1(SMOB, A1) \
120 SCM_SMOB_DESCRIPTOR (SMOB).apply (SMOB, A1)
121 #define SCM_SMOB_APPLY2(SMOB, A1, A2) \
122 SCM_SMOB_DESCRIPTOR (SMOB).apply (SMOB, A1, A2)
123 #define SCM_SMOB_APPLY3(SMOB, A1, A2, A3) \
124 SCM_SMOB_DESCRIPTOR (SMOB).apply (SMOB, A1, A2, A3)
127 scm_smob_apply_0_010 (SCM smob
)
129 return SCM_SMOB_APPLY1 (smob
, SCM_UNDEFINED
);
133 scm_smob_apply_0_020 (SCM smob
)
135 return SCM_SMOB_APPLY2 (smob
, SCM_UNDEFINED
, SCM_UNDEFINED
);
139 scm_smob_apply_0_030 (SCM smob
)
141 return SCM_SMOB_APPLY3 (smob
, SCM_UNDEFINED
, SCM_UNDEFINED
, SCM_UNDEFINED
);
145 scm_smob_apply_0_001 (SCM smob
)
147 return SCM_SMOB_APPLY1 (smob
, SCM_EOL
);
151 scm_smob_apply_0_011 (SCM smob
)
153 return SCM_SMOB_APPLY2 (smob
, SCM_UNDEFINED
, SCM_EOL
);
157 scm_smob_apply_0_021 (SCM smob
)
159 return SCM_SMOB_APPLY3 (smob
, SCM_UNDEFINED
, SCM_UNDEFINED
, SCM_EOL
);
163 scm_smob_apply_0_error (SCM smob
)
165 scm_wrong_num_args (smob
);
169 scm_smob_apply_1_020 (SCM smob
, SCM a1
)
171 return SCM_SMOB_APPLY2 (smob
, a1
, SCM_UNDEFINED
);
175 scm_smob_apply_1_030 (SCM smob
, SCM a1
)
177 return SCM_SMOB_APPLY3 (smob
, a1
, SCM_UNDEFINED
, SCM_UNDEFINED
);
181 scm_smob_apply_1_001 (SCM smob
, SCM a1
)
183 return SCM_SMOB_APPLY1 (smob
, scm_list_1 (a1
));
187 scm_smob_apply_1_011 (SCM smob
, SCM a1
)
189 return SCM_SMOB_APPLY2 (smob
, a1
, SCM_EOL
);
193 scm_smob_apply_1_021 (SCM smob
, SCM a1
)
195 return SCM_SMOB_APPLY3 (smob
, a1
, SCM_UNDEFINED
, SCM_EOL
);
199 scm_smob_apply_1_error (SCM smob
, SCM a1 SCM_UNUSED
)
201 scm_wrong_num_args (smob
);
205 scm_smob_apply_2_030 (SCM smob
, SCM a1
, SCM a2
)
207 return SCM_SMOB_APPLY3 (smob
, a1
, a2
, SCM_UNDEFINED
);
211 scm_smob_apply_2_001 (SCM smob
, SCM a1
, SCM a2
)
213 return SCM_SMOB_APPLY1 (smob
, scm_list_2 (a1
, a2
));
217 scm_smob_apply_2_011 (SCM smob
, SCM a1
, SCM a2
)
219 return SCM_SMOB_APPLY2 (smob
, a1
, scm_list_1 (a2
));
223 scm_smob_apply_2_021 (SCM smob
, SCM a1
, SCM a2
)
225 return SCM_SMOB_APPLY3 (smob
, a1
, a2
, SCM_EOL
);
229 scm_smob_apply_2_error (SCM smob
, SCM a1 SCM_UNUSED
, SCM a2 SCM_UNUSED
)
231 scm_wrong_num_args (smob
);
235 scm_smob_apply_3_030 (SCM smob
, SCM a1
, SCM a2
, SCM rst
)
237 if (!SCM_NULLP (SCM_CDR (rst
)))
238 scm_wrong_num_args (smob
);
239 return SCM_SMOB_APPLY3 (smob
, a1
, a2
, SCM_CAR (rst
));
243 scm_smob_apply_3_001 (SCM smob
, SCM a1
, SCM a2
, SCM rst
)
245 return SCM_SMOB_APPLY1 (smob
, scm_cons2 (a1
, a2
, rst
));
249 scm_smob_apply_3_011 (SCM smob
, SCM a1
, SCM a2
, SCM rst
)
251 return SCM_SMOB_APPLY2 (smob
, a1
, scm_cons (a2
, rst
));
255 scm_smob_apply_3_021 (SCM smob
, SCM a1
, SCM a2
, SCM rst
)
257 return SCM_SMOB_APPLY3 (smob
, a1
, a2
, rst
);
261 scm_smob_apply_3_error (SCM smob
,
266 scm_wrong_num_args (smob
);
272 scm_make_smob_type (char *name
, size_t size
)
273 #define FUNC_NAME "scm_make_smob_type"
277 SCM_ENTER_A_SECTION
; /* scm_numsmob */
278 new_smob
= scm_numsmob
;
279 if (scm_numsmob
!= MAX_SMOB_COUNT
)
283 if (new_smob
== MAX_SMOB_COUNT
)
284 scm_misc_error (FUNC_NAME
, "maximum number of smobs exceeded", SCM_EOL
);
286 scm_smobs
[new_smob
].name
= name
;
289 scm_smobs
[new_smob
].size
= size
;
290 scm_smobs
[new_smob
].free
= scm_smob_free
;
293 /* Make a class object if Goops is present. */
295 scm_smob_class
[new_smob
] = scm_make_extended_class (name
, 0);
297 return scm_tc7_smob
+ new_smob
* 256;
303 scm_set_smob_mark (scm_t_bits tc
, SCM (*mark
) (SCM
))
305 scm_smobs
[SCM_TC2SMOBNUM (tc
)].mark
= mark
;
309 scm_set_smob_free (scm_t_bits tc
, size_t (*free
) (SCM
))
311 scm_smobs
[SCM_TC2SMOBNUM (tc
)].free
= free
;
315 scm_set_smob_print (scm_t_bits tc
, int (*print
) (SCM
, SCM
, scm_print_state
*))
317 scm_smobs
[SCM_TC2SMOBNUM (tc
)].print
= print
;
321 scm_set_smob_equalp (scm_t_bits tc
, SCM (*equalp
) (SCM
, SCM
))
323 scm_smobs
[SCM_TC2SMOBNUM (tc
)].equalp
= equalp
;
327 scm_set_smob_apply (scm_t_bits tc
, SCM (*apply
) (),
328 unsigned int req
, unsigned int opt
, unsigned int rst
)
330 SCM (*apply_0
) (SCM
);
331 SCM (*apply_1
) (SCM
, SCM
);
332 SCM (*apply_2
) (SCM
, SCM
, SCM
);
333 SCM (*apply_3
) (SCM
, SCM
, SCM
, SCM
);
334 int type
= SCM_GSUBR_MAKTYPE (req
, opt
, rst
);
336 if (rst
> 1 || req
+ opt
+ rst
> 3)
338 puts ("Unsupported smob application type");
344 case SCM_GSUBR_MAKTYPE (0, 0, 0):
345 apply_0
= apply
; break;
346 case SCM_GSUBR_MAKTYPE (0, 1, 0):
347 apply_0
= scm_smob_apply_0_010
; break;
348 case SCM_GSUBR_MAKTYPE (0, 2, 0):
349 apply_0
= scm_smob_apply_0_020
; break;
350 case SCM_GSUBR_MAKTYPE (0, 3, 0):
351 apply_0
= scm_smob_apply_0_030
; break;
352 case SCM_GSUBR_MAKTYPE (0, 0, 1):
353 apply_0
= scm_smob_apply_0_001
; break;
354 case SCM_GSUBR_MAKTYPE (0, 1, 1):
355 apply_0
= scm_smob_apply_0_011
; break;
356 case SCM_GSUBR_MAKTYPE (0, 2, 1):
357 apply_0
= scm_smob_apply_0_021
; break;
359 apply_0
= scm_smob_apply_0_error
; break;
364 case SCM_GSUBR_MAKTYPE (1, 0, 0):
365 case SCM_GSUBR_MAKTYPE (0, 1, 0):
366 apply_1
= apply
; break;
367 case SCM_GSUBR_MAKTYPE (1, 1, 0):
368 case SCM_GSUBR_MAKTYPE (0, 2, 0):
369 apply_1
= scm_smob_apply_1_020
; break;
370 case SCM_GSUBR_MAKTYPE (1, 2, 0):
371 case SCM_GSUBR_MAKTYPE (0, 3, 0):
372 apply_1
= scm_smob_apply_1_030
; break;
373 case SCM_GSUBR_MAKTYPE (0, 0, 1):
374 apply_1
= scm_smob_apply_1_001
; break;
375 case SCM_GSUBR_MAKTYPE (1, 0, 1):
376 case SCM_GSUBR_MAKTYPE (0, 1, 1):
377 apply_1
= scm_smob_apply_1_011
; break;
378 case SCM_GSUBR_MAKTYPE (1, 1, 1):
379 case SCM_GSUBR_MAKTYPE (0, 2, 1):
380 apply_1
= scm_smob_apply_1_021
; break;
382 apply_1
= scm_smob_apply_1_error
; break;
387 case SCM_GSUBR_MAKTYPE (2, 0, 0):
388 case SCM_GSUBR_MAKTYPE (1, 1, 0):
389 case SCM_GSUBR_MAKTYPE (0, 2, 0):
390 apply_2
= apply
; break;
391 case SCM_GSUBR_MAKTYPE (2, 1, 0):
392 case SCM_GSUBR_MAKTYPE (1, 2, 0):
393 case SCM_GSUBR_MAKTYPE (0, 3, 0):
394 apply_2
= scm_smob_apply_2_030
; break;
395 case SCM_GSUBR_MAKTYPE (0, 0, 1):
396 apply_2
= scm_smob_apply_2_001
; break;
397 case SCM_GSUBR_MAKTYPE (1, 0, 1):
398 case SCM_GSUBR_MAKTYPE (0, 1, 1):
399 apply_2
= scm_smob_apply_2_011
; break;
400 case SCM_GSUBR_MAKTYPE (2, 0, 1):
401 case SCM_GSUBR_MAKTYPE (1, 1, 1):
402 case SCM_GSUBR_MAKTYPE (0, 2, 1):
403 apply_2
= scm_smob_apply_2_021
; break;
405 apply_2
= scm_smob_apply_2_error
; break;
410 case SCM_GSUBR_MAKTYPE (3, 0, 0):
411 case SCM_GSUBR_MAKTYPE (2, 1, 0):
412 case SCM_GSUBR_MAKTYPE (1, 2, 0):
413 case SCM_GSUBR_MAKTYPE (0, 3, 0):
414 apply_3
= scm_smob_apply_3_030
; break;
415 case SCM_GSUBR_MAKTYPE (0, 0, 1):
416 apply_3
= scm_smob_apply_3_001
; break;
417 case SCM_GSUBR_MAKTYPE (1, 0, 1):
418 case SCM_GSUBR_MAKTYPE (0, 1, 1):
419 apply_3
= scm_smob_apply_3_011
; break;
420 case SCM_GSUBR_MAKTYPE (2, 0, 1):
421 case SCM_GSUBR_MAKTYPE (1, 1, 1):
422 case SCM_GSUBR_MAKTYPE (0, 2, 1):
423 apply_3
= scm_smob_apply_3_021
; break;
425 apply_3
= scm_smob_apply_3_error
; break;
428 scm_smobs
[SCM_TC2SMOBNUM (tc
)].apply
= apply
;
429 scm_smobs
[SCM_TC2SMOBNUM (tc
)].apply_0
= apply_0
;
430 scm_smobs
[SCM_TC2SMOBNUM (tc
)].apply_1
= apply_1
;
431 scm_smobs
[SCM_TC2SMOBNUM (tc
)].apply_2
= apply_2
;
432 scm_smobs
[SCM_TC2SMOBNUM (tc
)].apply_3
= apply_3
;
433 scm_smobs
[SCM_TC2SMOBNUM (tc
)].gsubr_type
= type
;
436 scm_i_inherit_applicable (scm_smob_class
[SCM_TC2SMOBNUM (tc
)]);
440 scm_make_smob (scm_t_bits tc
)
442 long n
= SCM_TC2SMOBNUM (tc
);
443 size_t size
= scm_smobs
[n
].size
;
444 scm_t_bits data
= (size
> 0
445 ? (scm_t_bits
) scm_gc_malloc (size
, SCM_SMOBNAME (n
))
447 return scm_cell (tc
, data
);
451 /* {Initialization for i/o types, float, bignum, the type of free cells}
455 free_print (SCM exp
, SCM port
, scm_print_state
*pstate SCM_UNUSED
)
458 sprintf (buf
, "#<freed cell %p; GC missed a reference>",
459 (void *) SCM_UNPACK (exp
));
460 scm_puts (buf
, port
);
462 #if (SCM_DEBUG_CELL_ACCESSES == 1)
463 if (scm_debug_cell_accesses_p
)
472 scm_smob_prehistory ()
478 for (i
= 0; i
< MAX_SMOB_COUNT
; ++i
)
480 scm_smobs
[i
].name
= 0;
481 scm_smobs
[i
].size
= 0;
482 scm_smobs
[i
].mark
= 0;
483 scm_smobs
[i
].free
= 0;
484 scm_smobs
[i
].print
= scm_smob_print
;
485 scm_smobs
[i
].equalp
= 0;
486 scm_smobs
[i
].apply
= 0;
487 scm_smobs
[i
].apply_0
= 0;
488 scm_smobs
[i
].apply_1
= 0;
489 scm_smobs
[i
].apply_2
= 0;
490 scm_smobs
[i
].apply_3
= 0;
491 scm_smobs
[i
].gsubr_type
= 0;
494 /* WARNING: These scm_make_smob_type calls must be done in this order */
495 tc
= scm_make_smob_type ("free", 0);
496 scm_set_smob_print (tc
, free_print
);
498 tc
= scm_make_smob_type ("big", 0); /* freed in gc */
499 scm_set_smob_print (tc
, scm_bigprint
);
500 scm_set_smob_equalp (tc
, scm_bigequal
);
502 tc
= scm_make_smob_type ("real", 0); /* freed in gc */
503 scm_set_smob_print (tc
, scm_print_real
);
504 scm_set_smob_equalp (tc
, scm_real_equalp
);
506 tc
= scm_make_smob_type ("complex", 0); /* freed in gc */
507 scm_set_smob_print (tc
, scm_print_complex
);
508 scm_set_smob_equalp (tc
, scm_complex_equalp
);