+#define INLINE inline static
+
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#define TAG_MASK 7
#define TAG_BITS 3
#define TAG(cell) ((CELL)(cell) & TAG_MASK)
-#define RETAG(cell,tag) ((CELL)(cell) | (tag))
#define UNTAG(cell) ((CELL)(cell) & ~TAG_MASK)
+#define RETAG(cell,tag) (UNTAG(cell) | (tag))
/*** Tags ***/
#define FIXNUM_TYPE 0
#define BIGNUM_TYPE 1
-#define WORD_TYPE 2
+#define TUPLE_TYPE 2
#define OBJECT_TYPE 3
#define RATIO_TYPE 4
#define FLOAT_TYPE 5
#define COMPLEX_TYPE 6
-#define WRAPPER_TYPE 7
+
+/* Canonical F object */
+#define F_TYPE 7
+#define F F_TYPE
#define HEADER_TYPE 7 /* anything less than or equal to this is a tag */
-#define GC_COLLECTED 0 /* See gc.c */
+
+#define GC_COLLECTED 5 /* See gc.c */
/*** Header types ***/
#define ARRAY_TYPE 8
-
-/* Canonical F object */
-#define F_TYPE 9
-#define F RETAG(0,OBJECT_TYPE)
-
+#define WRAPPER_TYPE 9
#define HASHTABLE_TYPE 10
#define VECTOR_TYPE 11
#define STRING_TYPE 12
#define QUOTATION_TYPE 14
#define DLL_TYPE 15
#define ALIEN_TYPE 16
-#define TUPLE_TYPE 17
+#define WORD_TYPE 17
#define BYTE_ARRAY_TYPE 18
+#define BIT_ARRAY_TYPE 19
+#define FLOAT_ARRAY_TYPE 20
+#define CURRY_TYPE 21
+#define CALLSTACK_TYPE 22
+
+#define TYPE_COUNT 23
+
+INLINE bool immediate_p(CELL obj)
+{
+ return (TAG(obj) == FIXNUM_TYPE || obj == F);
+}
-#define TYPE_COUNT 19
+INLINE F_FIXNUM untag_fixnum_fast(CELL tagged)
+{
+ return ((F_FIXNUM)tagged) >> TAG_BITS;
+}
+INLINE CELL tag_fixnum(F_FIXNUM untagged)
+{
+ return RETAG(untagged << TAG_BITS,FIXNUM_TYPE);
+}
+
+INLINE void *untag_object(CELL tagged)
+{
+ return (void *)UNTAG(tagged);
+}
+
+typedef void (*XT)(CELL arg);
+
+/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
CELL header;
/* tagged */
CELL capacity;
} F_ARRAY;
+typedef F_ARRAY F_BYTE_ARRAY;
+
+typedef F_ARRAY F_BIT_ARRAY;
+
+typedef F_ARRAY F_FLOAT_ARRAY;
+
+/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
/* always tag_header(VECTOR_TYPE) */
CELL header;
CELL array;
} F_VECTOR;
+/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
CELL header;
/* tagged num of chars */
CELL hashcode;
} F_STRING;
+/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
/* always tag_header(SBUF_TYPE) */
CELL header;
CELL string;
} F_SBUF;
+/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
/* always tag_header(HASHTABLE_TYPE) */
CELL header;
CELL array;
} F_HASHTABLE;
-/* When a word is executed we jump to the value of the XT field. However this
-value is an unportable function pointer. Interpreted and primitive words will
-have their XT set to a value in the 'primitives' global (see primitives.c).
-Compiled words are marked as such and their XT, which point inside the code
-heap, are instead relocated on startup, and also considered a code GC root. */
+/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
/* TAGGED header */
CELL header;
CELL name;
/* TAGGED word vocabulary */
CELL vocabulary;
- /* TAGGED on-disk primitive number */
- CELL primitive;
- /* TAGGED parameter to xt; used for colon definitions */
+ /* TAGGED definition */
CELL def;
- /* TAGGED property hash for library code */
+ /* TAGGED property assoc for library code */
CELL props;
/* TAGGED t or f, depending on if the word is compiled or not */
CELL compiledp;
+ /* TAGGED call count for profiling */
+ CELL counter;
/* UNTAGGED execution token: jump here to execute word */
- CELL xt;
+ XT xt;
} F_WORD;
+/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
CELL header;
CELL object;
} F_WRAPPER;
+/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
CELL header;
CELL numerator;
CELL denominator;
} F_RATIO;
+/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
/* C sucks. */
union {
double n;
} F_FLOAT;
+/* Assembly code makes assumptions about the layout of this struct */
+typedef struct {
+ CELL header;
+ /* tagged */
+ CELL array;
+ /* untagged */
+ XT xt;
+} F_QUOTATION;
+
+/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
CELL header;
CELL real;
CELL imaginary;
} F_COMPLEX;
+/* Assembly code makes assumptions about the layout of this struct */
typedef struct {
CELL header;
/* tagged */
CELL alien;
+ /* tagged */
+ CELL expired;
/* untagged */
CELL displacement;
- /* untagged */
- bool expired;
} F_ALIEN;
typedef struct {
/* OS-specific handle */
void* dll;
} F_DLL;
+
+typedef struct {
+ CELL header;
+ /* tagged */
+ CELL obj;
+ /* tagged */
+ CELL quot;
+} F_CURRY;
+
+typedef struct {
+ CELL header;
+ /* tagged */
+ CELL length;
+ /* untagged */
+ CELL bottom;
+} F_CALLSTACK;