wingo pushed a commit to branch wip-whippet
in repository guile.

commit 62b23a8dc417ade0950e1a7506eab77f861b5e9d
Author: Andy Wingo <wi...@pobox.com>
AuthorDate: Mon Jun 30 14:58:44 2025 +0200

    Add smob-internal.h
    
    * libguile/smob-internal.h: New file.
    * libguile/Makefile.am (noinst_HEADERS): Add new file.
    * libguile/smob.c (scm_new_smob, scm_new_double_smob): Adapt.
---
 libguile/Makefile.am     |  1 +
 libguile/smob-internal.h | 98 ++++++++++++++++++++++++++++++++++++++++++++++++
 libguile/smob.c          | 21 ++---------
 3 files changed, 103 insertions(+), 17 deletions(-)

diff --git a/libguile/Makefile.am b/libguile/Makefile.am
index a69e24267..722054d7c 100644
--- a/libguile/Makefile.am
+++ b/libguile/Makefile.am
@@ -528,6 +528,7 @@ noinst_HEADERS = atomic.h                                   
\
                 programs.h                                     \
                 ports-internal.h                               \
                 regex-posix.h                                  \
+                smob-internal.h                                \
                 strings-internal.h                             \
                 syntax.h                                       \
                 threads-internal.h                             \
diff --git a/libguile/smob-internal.h b/libguile/smob-internal.h
new file mode 100644
index 000000000..831794b25
--- /dev/null
+++ b/libguile/smob-internal.h
@@ -0,0 +1,98 @@
+#ifndef SCM_SMOB_INTERNAL_H
+#define SCM_SMOB_INTERNAL_H
+
+/* Copyright 1995-1996,1998-2001,2004,2006,2009-2012,2015,2018,2025
+     Free Software Foundation, Inc.
+
+   This file is part of Guile.
+
+   Guile is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published
+   by the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   Guile is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+   License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with Guile.  If not, see
+   <https://www.gnu.org/licenses/>.  */
+
+
+
+#include "libguile/smob.h"
+
+
+
+struct scm_smob
+{
+  scm_t_bits tag_and_flags;
+};
+
+struct scm_single_smob
+{
+  struct scm_smob header;
+  scm_t_bits data_1;
+};
+
+struct scm_double_smob
+{
+  struct scm_smob header;
+  scm_t_bits data_1;
+  scm_t_bits data_2;
+  scm_t_bits data_3;
+};
+
+static inline int
+scm_is_smob (SCM x)
+{
+  return SCM_HAS_TYP7 (x, scm_tc7_smob);
+}
+
+static inline struct scm_smob *
+scm_to_smob (SCM x)
+{
+  if (!scm_is_smob (x))
+    abort ();
+  return (struct scm_smob *) SCM_UNPACK_POINTER (x);
+}
+
+static inline SCM
+scm_from_smob (struct scm_smob * x)
+{
+  return SCM_PACK_POINTER (x);
+}
+
+static inline struct scm_smob_descriptor *
+scm_i_smob_descriptor (struct scm_smob *x)
+{
+  return &scm_smobs[((x->tag_and_flags) & 0xff00) >> 8];
+}
+
+static inline int
+scm_smob_field_is_managed (const struct scm_smob_descriptor *desc, size_t i)
+{
+  if (i >= 32)
+    abort();
+
+  return ((1 << i) & desc->unmanaged_fields) == 0;
+}
+
+static inline int
+scm_smob_field_is_unmanaged (const struct scm_smob_descriptor *desc, size_t i)
+{
+  return !scm_smob_field_is_managed (desc, i);
+}
+
+static inline void*
+scm_smob_field_loc (struct scm_smob *smob, size_t i)
+{
+  uintptr_t addr = (uintptr_t) smob;
+  return (void *) (addr + sizeof (*smob) + i * sizeof (scm_t_bits));
+}
+
+SCM_INTERNAL void scm_i_finalize_smob (struct scm_thread *thread, SCM obj);
+
+#endif  /* SCM_SMOB_INTERNAL_H */
diff --git a/libguile/smob.c b/libguile/smob.c
index 2d4cbaf31..4f4d95551 100644
--- a/libguile/smob.c
+++ b/libguile/smob.c
@@ -38,6 +38,7 @@
 #include "ports.h"
 #include "programs.h"
 #include "threads-internal.h"
+#include "smob-internal.h"
 
 #include "smob.h"
 
@@ -277,20 +278,6 @@ 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)
@@ -298,7 +285,7 @@ scm_new_smob (scm_t_bits tc, scm_t_bits data)
   scm_t_bits smobnum = SCM_TC2SMOBNUM (tc);
   const scm_smob_descriptor* desc = &scm_smobs[smobnum];
   scm_thread *thr = SCM_I_CURRENT_THREAD;
-  struct scm_smob *ret;
+  struct scm_single_smob *ret;
   size_t sz = sizeof (*ret);
 
   if (desc->field_count)
@@ -315,7 +302,7 @@ scm_new_smob (scm_t_bits tc, scm_t_bits data)
   else
     ret = scm_allocate_sloppy (thr, sz);
 
-  ret->tag_and_flags = tc;
+  ret->header.tag_and_flags = tc;
   ret->data_1 = data;
 
   if (SCM_UNLIKELY (desc->free))
@@ -349,7 +336,7 @@ scm_new_double_smob (scm_t_bits tc, scm_t_bits data1,
   else
     ret = scm_allocate_sloppy (thr, sz);
 
-  ret->tag_and_flags = tc;
+  ret->header.tag_and_flags = tc;
   ret->data_1 = data1;
   ret->data_2 = data2;
   ret->data_3 = data3;

Reply via email to