summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libguile/smob.c19
-rw-r--r--libguile/smob.h13
2 files changed, 28 insertions, 4 deletions
diff --git a/libguile/smob.c b/libguile/smob.c
index b0e95fe2f..66b7696ed 100644
--- a/libguile/smob.c
+++ b/libguile/smob.c
@@ -37,6 +37,10 @@
#include "libguile/smob.h"
+#include <gc/gc.h>
+#include <gc/gc_mark.h>
+
+
/* scm_smobs scm_numsmob
@@ -488,8 +492,6 @@ free_print (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED)
/* Marking SMOBs using user-supplied mark procedures. */
-#include <gc/gc.h>
-#include <gc/gc_mark.h>
/* The freelist and GC kind used for SMOB types that provide a custom mark
procedure. */
@@ -599,6 +601,19 @@ scm_i_new_smob_with_mark_proc (scm_t_bits tc, scm_t_bits data1,
return cell;
}
+
+/* Finalize SMOB by calling its SMOB type's free function, if any. */
+SCM
+scm_i_finalize_smob (SCM smob, SCM data)
+{
+ size_t (* free_smob) (SCM);
+
+ free_smob = scm_smobs[SCM_SMOBNUM (smob)].free;
+ if (free_smob)
+ free_smob (smob);
+
+ return SCM_UNSPECIFIED;
+}
void
diff --git a/libguile/smob.h b/libguile/smob.h
index 0a0da8324..780265f1e 100644
--- a/libguile/smob.h
+++ b/libguile/smob.h
@@ -54,10 +54,14 @@ SCM_API SCM scm_i_new_smob_with_mark_proc (scm_t_bits tc,
#define SCM_NEWSMOB(z, tc, data) \
do \
{ \
- z = (scm_smobs[SCM_TC2SMOBNUM (tc)].mark \
+ register scm_t_bits _smobnum = SCM_TC2SMOBNUM (tc); \
+ z = (scm_smobs[_smobnum].mark \
? scm_i_new_smob_with_mark_proc ((tc), (scm_t_bits)(data), \
0, 0) \
: scm_cell (tc, (scm_t_bits)(data))); \
+ if (scm_smobs[_smobnum].free) \
+ scm_gc_register_finalizer ((z), scm_i_finalize_smob, \
+ SCM_BOOL_F, 0); \
} \
while (0)
@@ -79,13 +83,17 @@ while (0)
#define SCM_NEWSMOB3(z, tc, data1, data2, data3) \
do \
{ \
- z = (scm_smobs[SCM_TC2SMOBNUM (tc)].mark \
+ register scm_t_bits _smobnum = SCM_TC2SMOBNUM (tc); \
+ z = (scm_smobs[_smobnum].mark \
? scm_i_new_smob_with_mark_proc (tc, (scm_t_bits)(data1), \
(scm_t_bits)(data2), \
(scm_t_bits)(data3)) \
: scm_double_cell ((tc), (scm_t_bits)(data1), \
(scm_t_bits)(data2), \
(scm_t_bits)(data3))); \
+ if (scm_smobs[_smobnum].free) \
+ scm_gc_register_finalizer ((z), scm_i_finalize_smob, \
+ SCM_BOOL_F, 0); \
} \
while (0)
@@ -131,6 +139,7 @@ SCM_API long scm_numsmob;
SCM_API scm_smob_descriptor scm_smobs[];
SCM_API void scm_i_set_smob_flags (SCM x, scm_t_bits data);
+SCM_API SCM scm_i_finalize_smob (SCM smob, SCM data);