aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-10-20 11:04:47 +0200
committerlemon <lsof@mailbox.org>2025-10-20 11:04:47 +0200
commit21be6c1317078691de33c658dfd77755c9f43592 (patch)
treec592dc837c3de5272799e9412f542bb9931a25d7
parenta587564cef96ff5cce1c31a6445858f0f6553b1d (diff)
refactor vec_of(T) and misc
-rw-r--r--c/lex.c21
-rw-r--r--c/lex.h1
-rw-r--r--common.h74
-rw-r--r--ir/ir.c2
-rw-r--r--mem.c83
5 files changed, 103 insertions, 78 deletions
diff --git a/c/lex.c b/c/lex.c
index 951bb5a..135972a 100644
--- a/c/lex.c
+++ b/c/lex.c
@@ -1199,7 +1199,10 @@ advancemacro(struct lexer *lx, struct token *tk)
assert(lx->macstk);
rl = lx->macstk->rlist;
if (lx->macstk->idx == rl.n) {
- if (lx->macstk->stop) return tk->t = TKEOF;
+ if (lx->macstk->stop) {
+ tk->t = TKEOF;
+ return 1;
+ }
popmac(lx);
return 0;
}
@@ -1208,7 +1211,7 @@ advancemacro(struct lexer *lx, struct token *tk)
tk->span.ex = lx->macstk->exspan;
if (tryexpand(lx, tk))
return 0;
- return tk->t;
+ return 1;
}
static struct token epeektk;
@@ -1538,13 +1541,16 @@ ppelse(struct lexer *lx, const struct span *span)
enum { MAXINCLUDE = 200 };
static bool
-tryinclude(struct lexer *lx, const struct span *span, const char *path)
+tryinclude(struct lexer *lx, const struct span *span, char *path)
{
struct lexer new;
const char *err;
switch (initlexer(&new, &err, path)) {
default: assert(0);
case LXERR: return 0;
+ case LXFILESEEN:
+ xbfree(path);
+ /* fallthru */
case LXOK:
new.save = xmalloc(sizeof *new.save);
memcpy(new.save, lx, sizeof *lx);
@@ -1553,7 +1559,8 @@ tryinclude(struct lexer *lx, const struct span *span, const char *path)
if (++includedepth == MAXINCLUDE)
fatal(span, "Maximum nested include depth of %d reached", includedepth);
break;
- case LXFILESEEN:
+ case LXFILESKIP:
+ xbfree(path);
break;
}
return 1;
@@ -1913,15 +1920,15 @@ initlexer(struct lexer *lx, const char **err, const char *file)
fileid = openfile(err, &f, file);
if (fileid < 0)
return LXERR;
- if (isoncefile(fileid) && isfileseen(fileid))
- return LXFILESEEN;
+ if (isfileseen(fileid) && isoncefile(fileid))
+ return LXFILESKIP;
memset(lx, 0, sizeof *lx);
lx->fileid = fileid;
markfileseen(fileid);
lx->dat = f->p;
lx->ndat = f->n;
lx->tmparena = &tmparena;
- return LXOK;
+ return getfilename(fileid) != file ? LXFILESEEN : LXOK;
}
/* callback to let lexer release temp memory for arena allocated token data */
diff --git a/c/lex.h b/c/lex.h
index 4ea7327..60a28bf 100644
--- a/c/lex.h
+++ b/c/lex.h
@@ -101,6 +101,7 @@ struct lexer {
enum initlexer {
LXOK,
LXFILESEEN,
+ LXFILESKIP,
LXERR,
};
diff --git a/common.h b/common.h
index 949b496..6f01da0 100644
--- a/common.h
+++ b/common.h
@@ -346,18 +346,6 @@ void targ_init(const char *);
/** MEM **/
/*********/
-struct arena {
- uint cap : 31,
- dyn : 1;
- uint n;
- struct arena *prev;
- uchar mem[];
-};
-
-extern struct arena *globarena;
-
-#define vec_of(T) struct { T *p; int _cap; uint n; }
-
/* libc *alloc wrappers */
void *xmalloc(size_t n, const char *);
void *xcalloc(size_t n, const char *);
@@ -393,6 +381,18 @@ xbgrow_(void **p, size_t n)
memset((char*)*(p)+tmp, 0, xbcap_(*(p))-tmp); \
} while (0)
+
+/** arenas **/
+struct arena {
+ uint cap : 31,
+ dyn : 1;
+ uint n;
+ struct arena *prev;
+ uchar mem[];
+};
+
+extern struct arena *globarena;
+
struct arena *newarena(uint chunksiz);
void *alloc(struct arena **, uint siz, uint align);
void *allocz(struct arena **, uint siz, uint align);
@@ -403,25 +403,27 @@ alloccopy(struct arena **arena, const void *src, uint siz, uint align)
}
void freearena(struct arena **);
-void vinit_(void **p, int *pcap, void *inlbuf, int cap, uint siz);
-void vpush_(void **p, int *pcap, uint *pn, uint siz);
-void *vpushn_(void **p, int *pcap, uint *pn, uint siz, const void *dat, uint ndat);
-void vresize_(void **p, int *pcap, uint *pn, uint siz, uint N);
-#define VINIT(inlbuf, Cap) { (inlbuf), (Cap) }
-#define vfree(v) ((v)->_cap < 0 ? free((v)->p) : (void)0, memset((v), 0, sizeof*(v)))
-#define vinit(v, inlbuf, Cap) (vfree(v), vinit_((void **)&(v)->p, &(v)->_cap, inlbuf, (Cap), sizeof *(v)->p))
-#define vpush(v, x) (vpush_((void **)&(v)->p, &(v)->_cap, &(v)->n, sizeof *(v)->p), \
- (v)->p[(v)->n++] = (x))
-#define vpushn(v, xs, N) vpushn_((void **)&(v)->p, &(v)->_cap, &(v)->n, sizeof *(v)->p, xs, N)
-#define vresize(v, N) vresize_((void **)&(v)->p, &(v)->_cap, &(v)->n, sizeof *(v)->p, N)
-
-struct bitset { uvlong u; };
-enum { BSNBIT = 8 * sizeof(uvlong) };
-#define BSSIZE(nbit) ((nbit) / BSNBIT + ((nbit) % BSNBIT != 0))
-
-struct imapbase { short *k; struct bitset *bs; uint n, N; };
-/* map of short -> T */
+/** vec **/
+struct vecbase { void *p; uint n; uint cap : 31, dyn : 1; };
+#define vec_of(T) union { \
+ struct { T *p; uint n; }; \
+ struct vecbase _vb; \
+}
+void vinit_(struct vecbase *, void *inlbuf, uint cap, uint siz);
+void vpush_(struct vecbase *, uint siz);
+void *vpushn_(struct vecbase *, uint siz, const void *dat, uint ndat);
+void vresize_(struct vecbase *, uint siz, uint N);
+#define VINIT(inlbuf, Cap) { ._vb.p = (inlbuf), ._vb.cap = (Cap) }
+#define vfree(v) ((v)->_vb.dyn ? free((v)->p) : (void)0, memset((v), 0, sizeof*(v)))
+#define vinit(v, inlbuf, Cap) (vfree(v), vinit_(&(v)->_vb, inlbuf, (Cap), sizeof *(v)->p))
+#define vpush(v, x) (vpush_(&(v)->_vb, sizeof *(v)->p), (v)->p[(v)->n++] = (x))
+#define vpushn(v, xs, N) vpushn_(&(v)->_vb, sizeof *(v)->p, xs, N)
+#define vresize(v, N) vresize_(&(v)->_vb, sizeof *(v)->p, N)
+
+/** map of short -> T **/
#define imap_of(T) struct { T *v; int tmp; struct imapbase mb; }
+struct imapbase { short *k; struct bitset *bs; uint n, N; };
+
void imap_init_(struct imapbase *, void **v, uint vsiz, uint N);
int imap_get_(struct imapbase *, short k);
int imap_set_(struct imapbase *, void **v, uint vsiz, short k);
@@ -445,9 +447,10 @@ int imap_set_(struct imapbase *, void **v, uint vsiz, short k);
} while (0)
-struct pmapbase { void **k; uint n, N; };
-/* map of non-null ptr -> T */
+/** map of non-null ptr -> T **/
#define pmap_of(T) struct { T *v; int tmp; struct pmapbase mb; }
+struct pmapbase { void **k; uint n, N; };
+
void pmap_init_(struct pmapbase *, void **v, uint vsiz, uint N);
int pmap_get_(struct pmapbase *, const void *k);
int pmap_set_(struct pmapbase *, void **v, uint vsiz, const void *k);
@@ -460,6 +463,12 @@ int pmap_set_(struct pmapbase *, void **v, uint vsiz, const void *k);
for (int _i = 0; _i < (m)->mb.N && ((kx) = (m)->mb.k[_i], (pvx) = &(m)->v[_i], 1); ++_i) \
if (kx)
+/** bitset **/
+struct bitset { uvlong u; };
+enum { BSNBIT = 8 * sizeof(uvlong) };
+#define BSSIZE(nbit) ((nbit) / BSNBIT + ((nbit) % BSNBIT != 0))
+
+
static inline bool
bstest(const struct bitset *bs, uint i)
{
@@ -513,6 +522,7 @@ bsiter(uint *i, struct bitset bs[/*siz*/], uint siz)
}
#define bs_each(T, var, bs, siz) for (T (var) = 0; bsiter(&(var), (bs), (siz)); ++(var))
+/** register set **/
typedef uvlong regset;
#define rsset(pS, r) (*(pS) |= 1ull << (r))
#define rsclr(pS, r) (*(pS) &=~ (1ull << (r)))
diff --git a/ir/ir.c b/ir/ir.c
index 0132a97..967870f 100644
--- a/ir/ir.c
+++ b/ir/ir.c
@@ -347,7 +347,7 @@ insertinstr(struct block *blk, int idx, struct instr ins)
if (idx == blk->ins.n) vpush(&blk->ins, new);
else {
assert(idx >= 0 && idx < blk->ins.n);
- vpush_((void **)&blk->ins.p, &blk->ins._cap, &blk->ins.n, sizeof *blk->ins.p);
+ vpush_(&blk->ins._vb, sizeof *blk->ins.p);
vresize(&blk->ins, blk->ins.n);
for (int i = blk->ins.n++; i > idx; --i)
blk->ins.p[i] = blk->ins.p[i - 1];
diff --git a/mem.c b/mem.c
index fad5523..1c43630 100644
--- a/mem.c
+++ b/mem.c
@@ -3,18 +3,20 @@
#include <errno.h>
#include <stdint.h>
-#define ALLOCERR(f) do { \
- efmt("%s: %s\n", f, strerror(errno)); \
- ioflush(&bstdout); \
- ioflush(&bstderr); \
- abort(); \
-} while (0)
+static void
+allocerr(const char *f)
+{
+ efmt("%s: %s\n", f, strerror(errno));
+ ioflush(&bstdout);
+ ioflush(&bstderr);
+ abort();
+}
void *
(xmalloc)(size_t n, const char *f)
{
void *p = malloc(n);
- if (!p) ALLOCERR(f);
+ if (!p) allocerr(f);
return p;
}
@@ -22,7 +24,7 @@ void *
(xcalloc)(size_t n, const char *f)
{
void *p = calloc(n, 1);
- if (!p) ALLOCERR(f);
+ if (!p) allocerr(f);
return p;
}
@@ -30,63 +32,68 @@ void *
(xrealloc)(void *p, size_t n, const char *f)
{
p = p ? realloc(p, n) : malloc(n);
- if (!p) ALLOCERR(f);
+ if (!p) allocerr(f);
return p;
}
/* vec: when _cap < 0, buf is dynamic allocated, otherwise an user provided buf */
void
-vinit_(void **p, int *pcap, void *inlbuf, int cap, uint siz)
+vinit_(struct vecbase *v, void *inlbuf, uint cap, uint siz)
{
- assert(!*p);
- *pcap = cap;
+ assert(!v->p);
+ v->cap = cap;
if (inlbuf) {
- *p = inlbuf;
+ v->p = inlbuf;
+ v->dyn = 0;
} else if (cap) {
- *p = xrealloc(0, cap*siz);
- *pcap = -cap;
+ v->p = xmalloc(cap*siz);
+ v->dyn = 1;
}
}
void
-vpush_(void **p, int *pcap, uint *pn, uint siz)
+vpush_(struct vecbase *v, uint siz)
{
- if (*pcap >= 0 && *pn >= *pcap) { /* empty or inline buffer */
- int cap = *pcap ? *pcap * 2 : 8;
- void *old = *p;
- *p = xrealloc(NULL, cap * siz);
- if (old) memcpy(*p, old, *pcap * siz);
- *pcap = -cap;
- } else if (*pcap < 0 && *pn >= -*pcap) { /* dyn buf */
- *p = xrealloc(*p, -(*pcap *= 2) * siz);
- } else return;
- while (*pn >= -*pcap)
- *p = xrealloc(*p, -(*pcap *= 2) * siz);
- assert(-(volatile int)*pcap > *pn && "overflow");
+ if (v->n < v->cap) return;
+ if (!v->dyn && v->n >= v->cap) { /* empty or inline buffer */
+ int cap = v->cap ? v->cap * 2 : 8;
+ void *old = v->p;
+ v->p = xmalloc(cap * siz);
+ if (old) memcpy(v->p, old, v->cap * siz);
+ v->cap = cap;
+ v->dyn = 1;
+ } else if (v->dyn && v->n >= v->cap) { /* dyn buf */
+ v->p = xrealloc(v->p, (v->cap *= 2) * siz);
+ }
+ while (v->n >= v->cap)
+ v->p = xrealloc(v->p, (v->cap *= 2) * siz);
+ assert(v->cap > v->n && "overflow");
}
void *
-vpushn_(void **p, int *pcap, uint *pn, uint siz, const void *dat, uint ndat)
+vpushn_(struct vecbase *v, uint siz, const void *dat, uint ndat)
{
void *beg;
- *pn += ndat;
- while (*pn >= (*pcap < 0 ? -*pcap : *pcap))
- vpush_(p, pcap, pn, siz);
- beg = (char *)*p + (*pn - ndat) * siz;
+ if (!ndat) return v->p;
+ v->n += ndat;
+ while (v->n >= v->cap)
+ vpush_(v, siz);
+ beg = (char *)v->p + (v->n - ndat) * siz;
+ assert(dat);
memcpy(beg, dat, ndat * siz);
return beg;
}
void
-vresize_(void **p, int *pcap, uint *pn, uint siz, uint N)
+vresize_(struct vecbase *v, uint siz, uint N)
{
- while ((*pcap < 0 ? -*pcap : *pcap) < N) {
- vpush_(p, pcap, pn, siz);
- *pn = *pcap < 0 ? -*pcap : *pcap;
+ while (v->cap < N) {
+ vpush_(v, siz);
+ v->n = v->cap;
}
- *pn = N;
+ v->n = N;
}
struct arena *