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

Move foreign pointers off scm_words

* libguile/foreign.h: Give pointers a struct type.  Adapt to use it
internally.
* libguile/foreign.c: Allocate pointers with scm_allocate_tagged.
This commit is contained in:
Andy Wingo 2025-06-24 09:27:44 +02:00
parent 61af4d201a
commit 0a5d2ffb1a
2 changed files with 73 additions and 31 deletions

View file

@ -52,11 +52,59 @@ typedef enum scm_t_foreign_type scm_t_foreign_type;
typedef void (*scm_t_pointer_finalizer) (void *);
#define SCM_POINTER_P(x) (SCM_HAS_TYP7 (x, scm_tc7_pointer))
struct scm_pointer
{
scm_t_bits tag_and_size;
uintptr_t address;
/* Pointers can be allocated with a number of extra tail words. These
are useful when you have a pointer derived from an object; you need
the object to stay alive as long as the derived pointer is alive.
Storing the object in a slot of the derived pointer will allow for
this. */
SCM gc_objects[];
};
static inline int
scm_is_pointer (SCM x)
{
return SCM_HAS_TYP7 (x, scm_tc7_pointer);
}
// Most of these SCM-to-C-struct / C-struct-to-SCM functions are named
// "scm_to_foo" / "scm_from_foo", but here in the FFI we run afoul of
// the already-existing, already-well-named scm_to_pointer and
// scm_from_pointer. Let's just prefix with "scm_i_" instead.
static inline struct scm_pointer *
scm_i_to_pointer (SCM x)
{
if (!scm_is_pointer (x))
abort ();
return (struct scm_pointer *) SCM_UNPACK_POINTER (x);
}
static inline SCM
scm_i_from_pointer (struct scm_pointer *x)
{
return SCM_PACK_POINTER (x);
}
static inline void*
scm_pointer_value (struct scm_pointer *p)
{
return (void *) p->address;
}
static inline size_t
scm_pointer_gc_object_count (struct scm_pointer *p)
{
return p->tag_and_size >> 16;
}
#define SCM_POINTER_P(x) (scm_is_pointer (x))
#define SCM_VALIDATE_POINTER(pos, x) \
SCM_MAKE_VALIDATE (pos, x, POINTER_P)
#define SCM_POINTER_VALUE(x) \
((void *) SCM_CELL_WORD_1 (x))
#define SCM_POINTER_VALUE(x) (scm_pointer_value (scm_i_to_pointer (x)))
SCM_API void *scm_to_pointer (SCM pointer);
SCM_API SCM scm_from_pointer (void *, scm_t_pointer_finalizer);