diff --git a/libguile/smob.c b/libguile/smob.c index 8b8091c04..e7e75cf14 100644 --- a/libguile/smob.c +++ b/libguile/smob.c @@ -164,13 +164,14 @@ scm_smob_trampoline (unsigned int nreq, unsigned int nopt, scm_t_bits -scm_make_smob_type (char const *name, size_t size) -#define FUNC_NAME "scm_make_smob_type" +scm_make_managed_smob_type (char const *name, size_t nfields) +#define FUNC_NAME "scm_make_smob_type_with_gc_info" { - long new_smob; + if (nfields > 32) + scm_misc_error (FUNC_NAME, "maximum 32 managed fields", SCM_EOL); scm_i_pthread_mutex_lock (&scm_i_misc_mutex); - new_smob = scm_numsmob; + long new_smob = scm_numsmob; if (scm_numsmob != MAX_SMOB_COUNT) ++scm_numsmob; scm_i_pthread_mutex_unlock (&scm_i_misc_mutex); @@ -179,7 +180,7 @@ scm_make_smob_type (char const *name, size_t size) scm_misc_error (FUNC_NAME, "maximum number of smobs exceeded", SCM_EOL); scm_smobs[new_smob].name = name; - scm_smobs[new_smob].size = size; + scm_smobs[new_smob].field_count = nfields; /* Make a class object if Goops is present. */ if (SCM_UNPACK (scm_i_smob_class[0]) != 0) @@ -189,6 +190,22 @@ scm_make_smob_type (char const *name, size_t size) } #undef FUNC_NAME +scm_t_bits +scm_make_smob_type (char const *name, size_t size) +{ + scm_t_bits tc = scm_make_managed_smob_type (name, 0); + scm_smobs[SCM_TC2SMOBNUM (tc)].size = size; + return tc; +} + +void +scm_set_smob_field_is_unmanaged (scm_t_bits tc, size_t idx) +{ + struct scm_smob_descriptor *desc = &scm_smobs[SCM_TC2SMOBNUM (tc)]; + if (idx >= desc->field_count) + abort (); + scm_smobs[SCM_TC2SMOBNUM (tc)].unmanaged_fields |= 1U << idx; +} void scm_set_smob_free (scm_t_bits tc, size_t (*free) (SCM)) diff --git a/libguile/smob.h b/libguile/smob.h index 22d925b8b..091f5c66a 100644 --- a/libguile/smob.h +++ b/libguile/smob.h @@ -40,6 +40,8 @@ typedef struct scm_smob_descriptor SCM (*equalp) (SCM, SCM); scm_t_subr apply; SCM apply_trampoline; + size_t field_count; + uint32_t unmanaged_fields; } scm_smob_descriptor; @@ -193,6 +195,10 @@ SCM_API int scm_smob_print (SCM exp, SCM port, scm_print_state *pstate); */ SCM_API scm_t_bits scm_make_smob_type (char const *name, size_t size); +SCM_API scm_t_bits scm_make_managed_smob_type (char const *name, + size_t nfields); + +SCM_API void scm_set_smob_field_is_unmanaged (scm_t_bits tc, size_t idx); SCM_API void scm_set_smob_free (scm_t_bits tc, size_t (*free) (SCM)); SCM_API void scm_set_smob_print (scm_t_bits tc,