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

commit 6389acf192df274de123b8a9ec97bbf6e4e27670
Author: Andy Wingo <wi...@pobox.com>
AuthorDate: Wed Jun 11 15:39:58 2025 +0200

    New internal functions to alloc subr closures
    
    * libguile/gsubr.c (scm_allocate_subr_code):
    (scm_make_subr_from_code): New functions.
    (create_subr): Refactor in terms of new functions.
    (scm_c_make_gsubr):
    (scm_c_define_gsubr):
    (scm_c_make_gsubr_with_generic):
    (scm_c_define_gsubr_with_generic): Adapt.
---
 libguile/gsubr-internal.h | 14 ++++++++++
 libguile/gsubr.c          | 66 +++++++++++++++++++++++++++--------------------
 2 files changed, 52 insertions(+), 28 deletions(-)

diff --git a/libguile/gsubr-internal.h b/libguile/gsubr-internal.h
index f5777883c..f3303d41d 100644
--- a/libguile/gsubr-internal.h
+++ b/libguile/gsubr-internal.h
@@ -58,6 +58,20 @@ SCM_INTERNAL SCM scm_apply_subr (struct scm_thread *thread,
                                  union scm_vm_stack_element *sp,
                                  uint32_t subr_idx, ptrdiff_t nargs);
 
+enum scm_subr_flags
+  {
+    SCM_F_SUBR_THREAD = 1,
+    SCM_F_SUBR_CLOSURE = 2
+  };
+
+SCM_INTERNAL const uint32_t*
+scm_allocate_subr_code (SCM name,
+                        unsigned int nreq, unsigned int nopt, unsigned int 
rest,
+                        void *fcn, uintptr_t subr_flags);
+SCM_INTERNAL struct scm_program*
+scm_make_subr_from_code (struct scm_thread *thread, const uint32_t *code,
+                         scm_t_bits program_flags, size_t nfree);
+
 SCM_INTERNAL void scm_init_gsubr (void);
 
 #endif  /* SCM_GSUBR_INTERNAL_H */
diff --git a/libguile/gsubr.c b/libguile/gsubr.c
index 662f1bb92..855107a01 100644
--- a/libguile/gsubr.c
+++ b/libguile/gsubr.c
@@ -30,6 +30,7 @@
 
 #include "foreign.h"
 #include "frames.h"
+#include "gc-inline.h"
 #include "instructions.h"
 #include "jit.h"
 #include "modules.h"
@@ -56,12 +57,6 @@ static const size_t expected_subr_count = 1500;
 
 static scm_i_pthread_mutex_t admin_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
 
-enum scm_subr_flags
-  {
-    SCM_F_SUBR_THREAD = 1,
-    SCM_F_SUBR_CLOSURE = 2
-  };
-
 struct scm_subr_data
 {
   void *proc;
@@ -334,36 +329,51 @@ get_subr_stub_code (uint32_t subr_idx,
     }
 }
 
+const uint32_t*
+scm_allocate_subr_code (SCM name,
+                        unsigned int nreq, unsigned int nopt, unsigned int 
rest,
+                        void *fcn, uintptr_t subr_flags)
+{
+  uint32_t idx = alloc_subr_idx (fcn, subr_flags);
+  record_subr_name (idx, name);
+  return get_subr_stub_code (idx, nreq, nopt, rest);
+}
+
+struct scm_program*
+scm_make_subr_from_code (struct scm_thread *thread, const uint32_t *code,
+                         scm_t_bits program_flags, size_t nfree)
+{
+  size_t bytes = sizeof(struct scm_program) + nfree * sizeof (SCM);
+  struct scm_program *proc = scm_inline_gc_malloc (thread, bytes);
+  proc->tag_flags_and_free_variable_count =
+    scm_tc7_program | program_flags | (nfree << 16);
+  proc->code = code;
+  return proc;
+}
+
 static SCM
-create_subr (int define, const char *name,
+create_subr (int define, const char *cname,
              unsigned int nreq, unsigned int nopt, unsigned int rest,
-             void *fcn, SCM *generic_loc, uintptr_t subr_flags)
+             void *fcn, SCM *generic_loc)
 {
-  SCM sname;
-  uint32_t idx;
-  scm_t_bits nfree = generic_loc ? 1 : 0;
-
-  idx = alloc_subr_idx (fcn, subr_flags);
-  sname = scm_from_utf8_symbol (name);
+  uintptr_t subr_flags = 0;
+  SCM name = cname ? scm_from_utf8_symbol (cname) : SCM_BOOL_F;
+  const uint32_t *code =
+    scm_allocate_subr_code (name, nreq, nopt, rest, fcn, subr_flags);
 
   scm_t_bits program_flags = SCM_F_PROGRAM_IS_PRIMITIVE;
   if (generic_loc)
     program_flags |= SCM_F_PROGRAM_IS_PRIMITIVE_GENERIC;
-
-  scm_t_bits tag = scm_tc7_program | (nfree << 16) | program_flags;
-
+  scm_t_bits nfree = generic_loc ? 1 : 0;
   struct scm_program *ret =
-    scm_gc_malloc (sizeof (struct scm_program) + nfree * sizeof(SCM),
-                   "foreign procedure");
-  ret->tag_flags_and_free_variable_count = tag;
-  ret->code = get_subr_stub_code (idx, nreq, nopt, rest);
-  record_subr_name (idx, sname);
+    scm_make_subr_from_code (SCM_I_CURRENT_THREAD, code, program_flags,
+                             nfree);
+
   if (generic_loc)
     scm_program_free_variable_set_x (ret, 0,
                                      scm_from_pointer (generic_loc, NULL));
-
   if (define)
-    scm_define (sname, scm_from_program (ret));
+    scm_define (name, scm_from_program (ret));
 
   return scm_from_program (ret);
 }
@@ -606,13 +616,13 @@ scm_apply_subr (struct scm_thread *t,
 SCM
 scm_c_make_gsubr (const char *name, int req, int opt, int rst, SCM (*fcn)())
 {
-  return create_subr (0, name, req, opt, rst, fcn, NULL, 0);
+  return create_subr (0, name, req, opt, rst, fcn, NULL);
 }
 
 SCM
 scm_c_define_gsubr (const char *name, int req, int opt, int rst, SCM (*fcn)())
 {
-  return create_subr (1, name, req, opt, rst, fcn, NULL, 0);
+  return create_subr (1, name, req, opt, rst, fcn, NULL);
 }
 
 SCM
@@ -623,7 +633,7 @@ scm_c_make_gsubr_with_generic (const char *name,
                               SCM (*fcn)(),
                               SCM *gf)
 {
-  return create_subr (0, name, req, opt, rst, fcn, gf, 0);
+  return create_subr (0, name, req, opt, rst, fcn, gf);
 }
 
 SCM
@@ -634,7 +644,7 @@ scm_c_define_gsubr_with_generic (const char *name,
                                 SCM (*fcn)(),
                                 SCM *gf)
 {
-  return create_subr (1, name, req, opt, rst, fcn, gf, 0);
+  return create_subr (1, name, req, opt, rst, fcn, gf);
 }
 
 void

Reply via email to