mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-07-02 15:40:38 +02:00
SCM always 64 bits wide
* libguile/tags.h: Update some comments. (scm_t_signed_bits, scm_t_bits): Bump to 64-bits for all platforms. (SCM_T_SIGNED_BITS_MAX, SCM_T_SIGNED_BITS_MIN, SCM_T_BITS_MAX): Adapt accordingly. (union SCM): For 32-bit the pointer will be in the low half of the bits. Define accessors to get at the low 32 bits. (SCM_TO_POINTER, SCM_FROM_POINTER): New defines, will replace SCM2PTR and PTR2SCM in common usage. (SCM_HEAP_POINTER, SCM_HEAP_OBJECT, SCM_SET_HEAP_OBJECT, SCM_HEAP_DATA) (SCM_SET_HEAP_DATA): New defines, will replace the SCM_GC_CELL macros. * libguile/gc.h: Remove comment about UNICOS. All pointer<->scm stuff is handled by tags.h now. (SCM2PTR, PTR2SCM): Define in terms of SCM_TO_POINTER and SCM_FROM_POINTER. (SCM_GC_CELL_OBJECT, SCM_GC_CELL_WORD, SCM_GC_SET_CELL_OBJECT) (SCM_GC_SET_CELL_WORD): Define in terms of the SCM_HEAP_* macros. * libguile/macros.c (scm_make_syntax_transformer): Cast a function pointer to scm_t_bits; a new warning.
This commit is contained in:
parent
6ab63d4446
commit
c2f56e4d89
3 changed files with 73 additions and 43 deletions
|
@ -35,21 +35,9 @@ typedef struct scm_t_cell
|
|||
SCM word_1;
|
||||
} scm_t_cell;
|
||||
|
||||
/* Cray machines have pointers that are incremented once for each
|
||||
* word, rather than each byte, the 3 most significant bits encode the
|
||||
* byte within the word. The following macros deal with this by
|
||||
* storing the native Cray pointers like the ones that looks like scm
|
||||
* expects. This is done for any pointers that point to a cell,
|
||||
* pointers to scm_vector elts, functions, &c are not munged.
|
||||
*/
|
||||
#ifdef _UNICOS
|
||||
# define SCM2PTR(x) ((scm_t_cell *) (SCM_UNPACK (x) >> 3))
|
||||
# define PTR2SCM(x) (SCM_PACK (((scm_t_bits) (x)) << 3))
|
||||
#else
|
||||
# define SCM2PTR(x) ((scm_t_cell *) (SCM_UNPACK (x)))
|
||||
# define PTR2SCM(x) (SCM_PACK ((scm_t_bits) (x)))
|
||||
#endif /* def _UNICOS */
|
||||
|
||||
#define SCM2PTR(x) SCM_TO_POINTER (x)
|
||||
#define PTR2SCM(x) SCM_FROM_POINTER (x)
|
||||
|
||||
|
||||
/* Low level cell data accessing macros. These macros should only be used
|
||||
|
@ -58,12 +46,11 @@ typedef struct scm_t_cell
|
|||
* in debug mode. In particular these macros will even work for free cells,
|
||||
* which should never be encountered by user code. */
|
||||
|
||||
#define SCM_GC_CELL_OBJECT(x, n) (((SCM *)SCM2PTR (x)) [n])
|
||||
#define SCM_GC_CELL_WORD(x, n) (SCM_UNPACK (SCM_GC_CELL_OBJECT ((x), (n))))
|
||||
#define SCM_GC_CELL_OBJECT(x, n) SCM_HEAP_OBJECT (x, n)
|
||||
#define SCM_GC_CELL_WORD(x, n) SCM_HEAP_DATA (x, n)
|
||||
|
||||
#define SCM_GC_SET_CELL_OBJECT(x, n, v) ((((SCM *)SCM2PTR (x)) [n]) = (v))
|
||||
#define SCM_GC_SET_CELL_WORD(x, n, v) \
|
||||
(SCM_GC_SET_CELL_OBJECT ((x), (n), SCM_PACK (v)))
|
||||
#define SCM_GC_SET_CELL_OBJECT(x, n, v) SCM_SET_HEAP_OBJECT (x, n, v)
|
||||
#define SCM_GC_SET_CELL_WORD(x, n, v) SCM_SET_HEAP_DATA (x, n, v)
|
||||
|
||||
#define SCM_GC_CELL_TYPE(x) (SCM_GC_CELL_OBJECT ((x), 0))
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ SCM_DEFINE (scm_make_syntax_transformer, "make-syntax-transformer", 3, 0, 0,
|
|||
SCM_VALIDATE_SYMBOL (2, type);
|
||||
|
||||
z = scm_words (scm_tc16_macro, 5);
|
||||
SCM_SET_SMOB_DATA_N (z, 1, prim);
|
||||
SCM_SET_SMOB_DATA_N (z, 1, (scm_t_bits)prim);
|
||||
SCM_SET_SMOB_OBJECT_N (z, 2, name);
|
||||
SCM_SET_SMOB_OBJECT_N (z, 3, type);
|
||||
SCM_SET_SMOB_OBJECT_N (z, 4, binding);
|
||||
|
|
|
@ -62,12 +62,12 @@
|
|||
* scm_t_bits:
|
||||
*/
|
||||
|
||||
typedef scm_t_intptr scm_t_signed_bits;
|
||||
typedef scm_t_uintptr scm_t_bits;
|
||||
typedef scm_t_int64 scm_t_signed_bits;
|
||||
typedef scm_t_uint64 scm_t_bits;
|
||||
|
||||
#define SCM_T_SIGNED_BITS_MAX SCM_T_INTPTR_MAX
|
||||
#define SCM_T_SIGNED_BITS_MIN SCM_T_INTPTR_MIN
|
||||
#define SCM_T_BITS_MAX SCM_T_UINTPTR_MAX
|
||||
#define SCM_T_SIGNED_BITS_MAX SCM_T_INT64_MAX
|
||||
#define SCM_T_SIGNED_BITS_MIN SCM_T_INT64_MIN
|
||||
#define SCM_T_BITS_MAX SCM_T_UINT64_MAX
|
||||
|
||||
|
||||
/* But as external interface, we define SCM.
|
||||
|
@ -75,6 +75,17 @@ typedef scm_t_uintptr scm_t_bits;
|
|||
union SCM
|
||||
{
|
||||
scm_t_bits as_bits;
|
||||
|
||||
/* If you set a field of the SCM union, it needs to set all the bits.
|
||||
The following types are not guaranteed to do so, so we put them in
|
||||
a sub-union, to indicate that they are for read access only. */
|
||||
union SCM_read_only {
|
||||
#if SCM_IS_BIG_ENDIAN
|
||||
struct { scm_t_uint32 high, low; } as_uint32;
|
||||
#else
|
||||
struct { scm_t_uint32 low, high; } as_uint32;
|
||||
#endif
|
||||
} read;
|
||||
};
|
||||
|
||||
typedef union SCM SCM;
|
||||
|
@ -110,29 +121,61 @@ typedef union SCM SCM;
|
|||
* being pointed to consists of at least two scm_t_bits variables and thus
|
||||
* can be used to hold pointers to malloc'ed memory of any size.
|
||||
*
|
||||
* The 'heap' is the memory area that is under control of Guile's garbage
|
||||
* collector. It holds 'single-cells' or 'double-cells', which consist of
|
||||
* either two or four scm_t_bits variables, respectively. It is guaranteed
|
||||
* that the address of a cell on the heap is 8-byte aligned. That is, since
|
||||
* non-immediates hold a cell address, the three least significant bits of a
|
||||
* non-immediate can be used to store additional information. The bits are
|
||||
* used to store information about the object's type and thus are called
|
||||
* tc3-bits, where tc stands for type-code.
|
||||
* The 'heap' is the memory area that is under control of Guile's
|
||||
* garbage collector. The size of the pointed-to memory will be at
|
||||
* least 8 bytes, and its address will be 8-byte aligned.
|
||||
*
|
||||
* For a given SCM value, the distinction whether it holds an immediate or
|
||||
* non-immediate object is based on the tc3-bits (see above) of its scm_t_bits
|
||||
* This eight-byte alignment means that for a non-immediate -- a heap
|
||||
* object -- that the three least significant bits of its address will
|
||||
* be zero. Guile can then use these bits as type tags. These lowest
|
||||
* three bits are called tc3-bits, where tc stands for type-code.
|
||||
*
|
||||
* For a given SCM value, the distinction whether it holds an immediate
|
||||
* or non-immediate object is based on the tc3-bits of its scm_t_bits
|
||||
* equivalent: If the tc3-bits equal #b000, then the SCM value holds a
|
||||
* non-immediate, and the scm_t_bits variable's value is just the pointer to
|
||||
* the heap cell.
|
||||
* non-immediate, and the scm_t_bits variable's value is just the
|
||||
* pointer to the heap cell.
|
||||
*
|
||||
* Summarized, the data of a scheme object that is represented by a SCM
|
||||
* variable consists of a) the SCM variable itself, b) in case of
|
||||
* non-immediates the data of the single-cell or double-cell the SCM object
|
||||
* points to, c) in case of non-immediates potentially additional data outside
|
||||
* of the heap (like for example malloc'ed data), and d) in case of
|
||||
* non-immediates potentially additional data inside of the heap, since data
|
||||
* stored in b) and c) may hold references to other cells.
|
||||
*
|
||||
* non-immediates the heap data that the SCM object points to, c) in
|
||||
* case of non-immediates potentially additional data outside of the
|
||||
* heap (like for example malloc'ed data), and d) in case of
|
||||
* non-immediates potentially additional data inside of the heap, since
|
||||
* data stored in b) and c) may hold references to other cells.
|
||||
*/
|
||||
|
||||
|
||||
/* Let's take a breather and define some helpers to access Scheme values
|
||||
from the heap.
|
||||
|
||||
Though C99 doesn't specify whether pointers are represented the same
|
||||
way in memory as integers are, it seems to be universal, besides
|
||||
UNICOS. We make that assumption, having checked at configure-time
|
||||
that it does indeed hold true on this platform. */
|
||||
|
||||
#if SCM_SIZEOF_VOID_P == 4
|
||||
#define SCM_TO_POINTER(x) ((void *)((x).read.as_uint32.low))
|
||||
#elif SCM_SIZEOF_VOID_P == 8
|
||||
#define SCM_TO_POINTER(x) ((void *)((x).as_bits))
|
||||
#else
|
||||
#error Unhandled word size.
|
||||
#endif
|
||||
|
||||
#define SCM_FROM_POINTER(x) SCM_PACK ((scm_t_bits)x)
|
||||
|
||||
#define SCM_HEAP_POINTER(x) ((SCM *) SCM_TO_POINTER (x))
|
||||
#define SCM_HEAP_OBJECT(x, n) \
|
||||
(SCM_HEAP_POINTER (x) [(n)])
|
||||
#define SCM_SET_HEAP_OBJECT(x, n, o) \
|
||||
SCM_HEAP_OBJECT (x, n) = (o)
|
||||
|
||||
#define SCM_HEAP_DATA(x, n) \
|
||||
(SCM_HEAP_OBJECT (x, n).as_bits)
|
||||
#define SCM_SET_HEAP_DATA(x, n, b) \
|
||||
SCM_HEAP_DATA (x, n) = (b)
|
||||
|
||||
/*
|
||||
*
|
||||
* Immediates
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue