@@ -15,7 +15,8 @@
1515// Closures
1616
1717typedef enum {
18− CON, INT, BIGINT, FLOAT, STRING, BITS8, BITS16, BITS32, BITS64, UNIT, PTR, FWD
18+ CON, INT, BIGINT, FLOAT, STRING, STROFFSET,
19+ BITS8, BITS16, BITS32, BITS64, UNIT, PTR, FWD
1920} ClosureType;
2021
2122typedef struct Closure *VAL;
@@ -25,6 +26,11 @@ typedef struct {
2526 VAL args[];
2627} con;
2728
29+typedef struct {
30+ VAL str;
31+ int offset;
32+} StrOffset;
33+
2834typedef struct Closure {
2935// Use top 16 bits of ty for saying which heap value is in
3036// Bottom 16 bits for closure type
@@ -34,6 +40,7 @@ typedef struct Closure {
3440 int i;
3541 double f;
3642 char* str;
43+ StrOffset* str_offset;
3744 void* ptr;
3845 uint8_t bits8;
3946 uint16_t bits16;
@@ -92,7 +99,7 @@ typedef void(*func)(VM*, VAL*);
9299
93100// Retrieving values
94101
95−#define GETSTR(x) (((VAL)(x))->info.str)
102+#define GETSTR(x) (ISSTR(x) ? (((VAL)(x))->info.str) : GETSTROFF(x))
96103#define GETPTR(x) (((VAL)(x))->info.ptr)
97104#define GETFLOAT(x) (((VAL)(x))->info.f)
98105
@@ -119,6 +126,7 @@ typedef intptr_t i_int;
119126#define MKINT(x) ((void*)((x)<<1)+1)
120127#define GETINT(x) ((i_int)(x)>>1)
121128#define ISINT(x) ((((i_int)x)&1) == 1)
129+#define ISSTR(x) (((VAL)(x))->ty == STRING)
122130
123131#define INTOP(op,x,y) MKINT((i_int)((((i_int)x)>>1) op (((i_int)y)>>1)))
124132#define UINTOP(op,x,y) MKINT((i_int)((((uintptr_t)x)>>1) op (((uintptr_t)y)>>1)))
@@ -151,9 +159,12 @@ VAL MKB64(VM* vm, uint64_t b);
151159
152160// following versions don't take a lock when allocating
153161VAL MKFLOATc(VM* vm, double val);
162+VAL MKSTROFFc(VM* vm, StrOffset* off);
154163VAL MKSTRc(VM* vm, char* str);
155164VAL MKPTRc(VM* vm, void* ptr);
156165
166+char* GETSTROFF(VAL stroff);
167+
157168// #define SETTAG(x, a) (x)->info.c.tag = (a)
158169#define SETARG(x, i, a) ((x)->info.c.args)[i] = ((VAL)(a))
159170#define GETARG(x, i) ((x)->info.c.args)[i]