lama_byterun/runtime/runtime_common.h

96 lines
2.7 KiB
C
Raw Normal View History

#ifndef __LAMA_RUNTIME_COMMON__
#define __LAMA_RUNTIME_COMMON__
#include <stddef.h>
#include <inttypes.h>
#include <limits.h>
// this flag makes GC behavior a bit different for testing purposes.
//#define DEBUG_VERSION
//#define FULL_INVARIANT_CHECKS
#if defined(__x86_64__) || defined(__ppc64__)
#define X86_64
#endif
typedef size_t ptrt; // pointer type, because can hold a pointer on a corresponding platform
#ifdef X86_64
typedef int64_t aint; // adaptive int
typedef uint64_t auint; // adaptive unsigned int
#define PRIdAI PRId64
#define SCNdAI SCNd64
#else
typedef int32_t aint; // adaptive int
typedef uint32_t auint; // adaptive unsigned int
#define PRIdAI PRId32
#define SCNdAI SCNd32
#endif
2023-05-31 11:01:11 +02:00
#define STRING_TAG 0x00000001
#define ARRAY_TAG 0x00000003
#define SEXP_TAG 0x00000005
#define CLOSURE_TAG 0x00000007
#define UNBOXED_TAG 0x00000009 // Not actually a data_header; used to return from LkindOf
#ifdef X86_64
#define LEN_MASK (UINT64_MAX^7)
#else
#define LEN_MASK (UINT32_MAX^7)
#endif
#define LEN(x) (ptrt)(((ptrt)x & LEN_MASK) >> 3)
#define TAG(x) (x & 7)
#ifndef DEBUG_VERSION
# define DATA_HEADER_SZ (sizeof(auint) + sizeof(ptrt))
2023-05-31 11:01:11 +02:00
#else
# define DATA_HEADER_SZ (sizeof(auint) + sizeof(ptrt) + sizeof(auint))
#endif
#define MEMBER_SIZE sizeof(ptrt)
2023-05-31 11:01:11 +02:00
#define TO_DATA(x) ((data *)((char *)(x)-DATA_HEADER_SZ))
2023-08-09 20:16:51 +02:00
#define TO_SEXP(x) ((sexp *)((char *)(x)-DATA_HEADER_SZ))
#define UNBOXED(x) (((aint)(x)) & 1)
#define UNBOX(x) (((aint)(x)) >> 1)
#define BOX(x) ((((aint)(x)) << 1) | 1)
#define BYTES_TO_WORDS(bytes) (((bytes) - 1) / sizeof(size_t) + 1)
2023-05-31 11:01:11 +02:00
#define WORDS_TO_BYTES(words) ((words) * sizeof(size_t))
// CAREFUL WITH DOUBLE EVALUATION!
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
typedef struct {
2023-05-31 11:01:11 +02:00
// store tag in the last three bits to understand what structure this is, other bits are filled with
// other utility info (i.e., size for array, number of fields for s-expression)
auint data_header;
#ifdef DEBUG_VERSION
2023-05-31 11:01:11 +02:00
size_t id;
#endif
2023-05-31 11:01:11 +02:00
// last bit is used as MARK-BIT, the rest are used to store address where object should move
// last bit can be used because due to alignment we can assume that last two bits are always 0's
ptrt forward_address;
2024-06-26 15:11:18 +02:00
char contents[];
} data;
typedef struct {
2023-08-09 20:16:51 +02:00
// store tag in the last three bits to understand what structure this is, other bits are filled with
// other utility info (i.e., size for array, number of fields for s-expression)
auint data_header;
2023-08-09 20:16:51 +02:00
#ifdef DEBUG_VERSION
2023-08-09 20:16:51 +02:00
size_t id;
#endif
// last bit is used as MARK-BIT, the rest are used to store address where object should move
// last bit can be used because due to alignment we can assume that last two bits are always 0's
ptrt forward_address;
auint tag;
2024-06-26 15:11:18 +02:00
char contents[];
} sexp;
2023-05-31 11:01:11 +02:00
#endif