From d8c1ea4049c7e91f24c6ced8a06113dca106b908 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Fri, 20 Jun 2025 13:03:06 +0200 Subject: [PATCH] Convert smobs to use scm_allocate_* * libguile/smob.c (scm_new_smob, scm_new_double_smob): Use scm_allocate_pointerless, scm_allocate_tagged, or scm_allocate_sloppy, as appropriate. --- libguile/smob.c | 72 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/libguile/smob.c b/libguile/smob.c index 601e33e6b..e6c1c82eb 100644 --- a/libguile/smob.c +++ b/libguile/smob.c @@ -277,17 +277,51 @@ scm_i_finalize_smob (struct scm_thread *thread, SCM smob) free_smob (smob); } +struct scm_smob +{ + scm_t_bits tag_and_flags; + scm_t_bits data_1; +}; + +struct scm_double_smob +{ + scm_t_bits tag_and_flags; + scm_t_bits data_1; + scm_t_bits data_2; + scm_t_bits data_3; +}; + /* Return a SMOB with typecode TC. */ SCM scm_new_smob (scm_t_bits tc, scm_t_bits data) { scm_t_bits smobnum = SCM_TC2SMOBNUM (tc); - SCM ret = scm_cell (tc, data); + const scm_smob_descriptor* desc = &scm_smobs[smobnum]; + scm_thread *thr = SCM_I_CURRENT_THREAD; + struct scm_smob *ret; + size_t sz = sizeof (*ret); - if (SCM_UNLIKELY (scm_smobs[smobnum].free)) - scm_i_add_smob_finalizer (SCM_I_CURRENT_THREAD, ret); + if (desc->field_count) + { + if (desc->field_count != 1) + abort (); + uint32_t all_fields_unmanaged = -1; + all_fields_unmanaged >>= 32 - desc->field_count; + if (desc->unmanaged_fields == all_fields_unmanaged) + ret = scm_allocate_pointerless (thr, sz); + else + ret = scm_allocate_tagged (thr, sz); + } + else + ret = scm_allocate_sloppy (thr, sz); - return ret; + ret->tag_and_flags = tc; + ret->data_1 = data; + + if (SCM_UNLIKELY (desc->free)) + scm_i_add_smob_finalizer (SCM_I_CURRENT_THREAD, SCM_PACK_POINTER (ret)); + + return SCM_PACK_POINTER (ret); } /* Return a SMOB with typecode TC. */ @@ -296,12 +330,34 @@ scm_new_double_smob (scm_t_bits tc, scm_t_bits data1, scm_t_bits data2, scm_t_bits data3) { scm_t_bits smobnum = SCM_TC2SMOBNUM (tc); - SCM ret = scm_double_cell (tc, data1, data2, data3); + const scm_smob_descriptor* desc = &scm_smobs[smobnum]; + scm_thread *thr = SCM_I_CURRENT_THREAD; + struct scm_double_smob *ret; + size_t sz = sizeof (*ret); - if (SCM_UNLIKELY (scm_smobs[smobnum].free)) - scm_i_add_smob_finalizer (SCM_I_CURRENT_THREAD, ret); + if (desc->field_count) + { + if (!(desc->field_count == 2 || desc->field_count == 3)) + abort (); + uint32_t all_fields_unmanaged = -1; + all_fields_unmanaged >>= 32 - desc->field_count; + if (desc->unmanaged_fields == all_fields_unmanaged) + ret = scm_allocate_pointerless (thr, sz); + else + ret = scm_allocate_tagged (thr, sz); + } + else + ret = scm_allocate_sloppy (thr, sz); - return ret; + ret->tag_and_flags = tc; + ret->data_1 = data1; + ret->data_2 = data2; + ret->data_3 = data3; + + if (SCM_UNLIKELY (desc->free)) + scm_i_add_smob_finalizer (SCM_I_CURRENT_THREAD, SCM_PACK_POINTER (ret)); + + return SCM_PACK_POINTER (ret); }