diff options
| author | 2025-10-20 11:04:47 +0200 | |
|---|---|---|
| committer | 2025-10-20 11:04:47 +0200 | |
| commit | 21be6c1317078691de33c658dfd77755c9f43592 (patch) | |
| tree | c592dc837c3de5272799e9412f542bb9931a25d7 | |
| parent | a587564cef96ff5cce1c31a6445858f0f6553b1d (diff) | |
refactor vec_of(T) and misc
| -rw-r--r-- | c/lex.c | 21 | ||||
| -rw-r--r-- | c/lex.h | 1 | ||||
| -rw-r--r-- | common.h | 74 | ||||
| -rw-r--r-- | ir/ir.c | 2 | ||||
| -rw-r--r-- | mem.c | 83 |
5 files changed, 103 insertions, 78 deletions
@@ -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 */ @@ -101,6 +101,7 @@ struct lexer { enum initlexer { LXOK, LXFILESEEN, + LXFILESKIP, LXERR, }; @@ -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))) @@ -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]; @@ -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 * |