1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-07-02 07:40:30 +02:00

Add new API for declaring managed SMOB fields

* libguile/smob.h:
* libguile/smob.c (scm_make_managed_smob_type): New API, to declare that
a SMOB has a certain number of fields, all of which will be traced by
the GC.  0 indicates "unknown", and will disable evacuation.
(scm_make_smob_type): Call scm_make_managed_smob_type with 0 nfields.
(scm_set_smob_field_is_unmanaged): New API to indicate that a field is
unmanaged (and should not be traced by GC).
This commit is contained in:
Andy Wingo 2025-06-18 14:55:48 +02:00
parent bc43d4f9a7
commit c74499a7e5
2 changed files with 28 additions and 5 deletions

View file

@ -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))

View file

@ -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,