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

Dynstack uses inline functions instead of macros

* libguile/control.c:
* libguile/dynstack.c:
* libguile/dynstack.h:
* libguile/vm.c: Move SCM_DYNSTACK_TAG etc to be inline functions.
Adapt all callers.
This commit is contained in:
Andy Wingo 2025-06-30 14:16:52 +02:00
parent 985c1d16f2
commit 2b3b843f82
4 changed files with 158 additions and 93 deletions

View file

@ -69,18 +69,36 @@ typedef struct scm_dynstack
The tag is a combination of the type of the dynstack item, some flags
associated with the item, and the length of the item. See
SCM_MAKE_DYNSTACK_TAG below for the details.
scm_make_dynstack_tag below for the details.
This arrangement makes it possible to have variable-length dynstack
items, and yet be able to traverse them forwards or backwards. */
#define SCM_DYNSTACK_HEADER_LEN 2
#define SCM_DYNSTACK_PREV_OFFSET(top) ((top)[-2])
#define SCM_DYNSTACK_SET_PREV_OFFSET(top, offset) (top)[-2] = (offset)
static inline ptrdiff_t
scm_dynstack_prev_offset (scm_t_bits *top)
{
return top[-2];
}
#define SCM_DYNSTACK_TAG(top) ((top)[-1])
#define SCM_DYNSTACK_SET_TAG(top, tag) (top)[-1] = (tag)
static inline void
scm_dynstack_set_prev_offset (scm_t_bits *top, ptrdiff_t offset)
{
top[-2] = offset;
}
static inline scm_t_bits
scm_dynstack_tag (scm_t_bits *top)
{
return top[-1];
}
static inline void
scm_dynstack_set_tag (scm_t_bits *top, scm_t_bits tag)
{
top[-1] = tag;
}
typedef enum {
SCM_DYNSTACK_TYPE_NONE = 0,
@ -98,37 +116,84 @@ typedef enum {
#define SCM_DYNSTACK_TAG_FLAGS_SHIFT 4
#define SCM_DYNSTACK_TAG_LEN_SHIFT 8
#define SCM_MAKE_DYNSTACK_TAG(type, flags, len) \
((type) | (flags) | ((len) << SCM_DYNSTACK_TAG_LEN_SHIFT))
static inline scm_t_bits
scm_make_dynstack_tag (scm_t_dynstack_item_type type, scm_t_bits flags,
size_t len)
{
if (type & ~SCM_DYNSTACK_TAG_TYPE_MASK)
abort ();
if (flags & ~SCM_DYNSTACK_TAG_FLAGS_MASK)
abort ();
scm_t_bits ret = type;
ret |= flags;
ret |= (len << SCM_DYNSTACK_TAG_LEN_SHIFT);
return ret;
}
static inline scm_t_dynstack_item_type
scm_dynstack_tag_type (scm_t_bits tag)
{
return tag & SCM_DYNSTACK_TAG_TYPE_MASK;
}
#define SCM_DYNSTACK_TAG_TYPE(tag) \
((tag) & SCM_DYNSTACK_TAG_TYPE_MASK)
#define SCM_DYNSTACK_TAG_FLAGS(tag) \
((tag) & SCM_DYNSTACK_TAG_FLAGS_MASK)
#define SCM_DYNSTACK_TAG_LEN(tag) \
((tag) >> SCM_DYNSTACK_TAG_LEN_SHIFT)
static inline scm_t_bits
scm_dynstack_tag_flags (scm_t_bits tag)
{
return tag & SCM_DYNSTACK_TAG_FLAGS_MASK;
}
#define SCM_DYNSTACK_PREV(top) \
(SCM_DYNSTACK_PREV_OFFSET (top) \
? ((top) - SCM_DYNSTACK_PREV_OFFSET (top)) : NULL)
#define SCM_DYNSTACK_NEXT(top) \
(SCM_DYNSTACK_TAG (top) \
? ((top) + SCM_DYNSTACK_TAG_LEN (SCM_DYNSTACK_TAG (top)) \
+ SCM_DYNSTACK_HEADER_LEN) \
: NULL)
static inline size_t
scm_dynstack_tag_len (scm_t_bits tag)
{
return tag >> SCM_DYNSTACK_TAG_LEN_SHIFT;
}
#define SCM_DYNSTACK_FIRST(dynstack) \
((dynstack)->base + SCM_DYNSTACK_HEADER_LEN)
static inline scm_t_bits *
scm_dynstack_prev (scm_t_bits *top)
{
ptrdiff_t offset = scm_dynstack_prev_offset (top);
return offset ? top - offset : NULL;
}
#define SCM_DYNSTACK_CAPACITY(dynstack) \
((dynstack)->limit - (dynstack)->base)
#define SCM_DYNSTACK_SPACE(dynstack) \
((dynstack)->limit - (dynstack)->top)
#define SCM_DYNSTACK_HEIGHT(dynstack) \
((dynstack)->top - (dynstack)->base)
static inline scm_t_bits *
scm_dynstack_next (scm_t_bits *top)
{
scm_t_bits tag = scm_dynstack_tag (top);
return tag
? top + scm_dynstack_tag_len (tag) + SCM_DYNSTACK_HEADER_LEN
: NULL;
}
#define SCM_DYNSTACK_HAS_SPACE(dynstack, n) \
(SCM_DYNSTACK_SPACE (dynstack) >= n + SCM_DYNSTACK_HEADER_LEN)
static inline scm_t_bits *
scm_dynstack_first (struct scm_dynstack *dynstack)
{
return dynstack->base + SCM_DYNSTACK_HEADER_LEN;
}
static inline size_t
scm_dynstack_capacity (struct scm_dynstack *dynstack)
{
return dynstack->limit - dynstack->base;
}
static inline size_t
scm_dynstack_space (struct scm_dynstack *dynstack)
{
return dynstack->limit - dynstack->top;
}
static inline size_t
scm_dynstack_height (struct scm_dynstack *dynstack)
{
return dynstack->top - dynstack->base;
}
static inline int
scm_dynstack_has_space (struct scm_dynstack *dynstack, size_t n)
{
return scm_dynstack_space (dynstack) >= n + SCM_DYNSTACK_HEADER_LEN;
}
typedef enum {
SCM_F_DYNSTACK_FRAME_REWINDABLE = (1 << SCM_DYNSTACK_TAG_FLAGS_SHIFT)