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:
parent
bc43d4f9a7
commit
c74499a7e5
2 changed files with 28 additions and 5 deletions
|
@ -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))
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue