diff options
| author | 2022-10-11 10:34:22 +0200 | |
|---|---|---|
| committer | 2022-10-11 10:34:22 +0200 | |
| commit | e712e8fdce6b6fec0d647f8b645ca943a6c830d0 (patch) | |
| tree | 23732fbe6c92ee85d3a943ff09e4ddf44350e17f /pez.c | |
| parent | 7a138f44719f0217775298928ee2d828d74dd917 (diff) | |
use inline stack memory for vectors to reduce allocations
Diffstat (limited to 'pez.c')
| -rw-r--r-- | pez.c | 350 |
1 files changed, 202 insertions, 148 deletions
@@ -28,9 +28,9 @@ typedef struct Val { uint64_t r; } Val; -#define vec_of(T) struct { \ - T *at; \ - uint len, cap; \ +#define vec_of(T, Ninl) struct { \ + T *at, inl[Ninl]; \ + uint len, cap; \ } typedef struct Obj Obj; @@ -42,7 +42,7 @@ struct Obj { typedef struct Str { OBJHEADER; - uint n; + uint len; char dat[]; } Str; @@ -53,7 +53,8 @@ typedef struct Tuple { typedef struct Array { OBJHEADER; - vec_of(Val); + uint len, cap; + Val *dat; } Array; struct KV { Val k, v; }; @@ -106,10 +107,23 @@ typedef struct Dilambda { Fn *getf, *setf; } Dilambda; -typedef struct Local Local; - enum { NAMEMAX = 80 }; +struct local { + uint16_t scope : 15; + uint16_t has_k : 1; + uint16_t sref; // name + union { + uint16_t kref; // when has_k + struct { + uint16_t index : 10, + isparam : 1, + mutable : 1, + captured : 1; + }; + }; +}; + struct cmupval { uint8_t idx; bool arg : 1, local : 1; @@ -123,14 +137,14 @@ typedef struct Comp { int peekchr; bool have_peekchr; char stash_ident[NAMEMAX]; - Local *stash_local; + struct local *stash_local; char stash_binopk; char stash_binopchr; int stash_binopop; Proto *proto; - vec_of(uint8_t) code; - vec_of(Val) con; + vec_of(uint8_t, 16) code; + vec_of(Val, 2) con; Val k; /* for constant folding */ bool has_k; @@ -141,30 +155,18 @@ typedef struct Comp { lvalue_const : 1; const char *lvalue_name; - vec_of(char) spool; // for var names - vec_of(Val) kpool; // for consts + vec_of(char, 16) spool; // for var names + vec_of(Val, 4) kpool; // for consts struct fenv { const char *name; struct fenv *prev; - vec_of(Local) locals; // also params + vec_of(struct local, 32) locals; // also params uint16_t scope; uint16_t nvars; // num of locals in scope not counting konsts - uint16_t nupval; - struct cmupval upvals[256]; - } fenv; + vec_of(struct cmupval, 32) upvals; + } *fenv; } Comp; -struct Local { - uint16_t scope; - uint16_t sref; // name - uint16_t kref; // when has_k - uint16_t index : 10; - uint16_t isparam : 1, - has_k : 1, - mutable : 1, - captured : 1; -}; - static struct Str strpool_deleted; typedef struct StrPool { uint count, deleted, N; @@ -328,59 +330,97 @@ cxrealloc(PezContext *cx, void *p, size_t osz, size_t sz) } -static inline void * +static inline void * FORCEINLINE cxalloc(PezContext *cx, size_t sz) { return cxrealloc(cx, NULL, 0, sz); } -static inline void +static inline void FORCEINLINE cxfree(PezContext *cx, void *p, size_t sz) { cxrealloc(cx, p, sz, 0); } -#define delvec(cx, v) \ - (void)((v)->at ? cxfree(cx, (v)->at, (v)->cap * sizeof *(v)->at) : (void)0, \ +#define delvec(cx, v) \ + (void)((v)->at && (v)->at != (v)->inl ? \ + cxfree(cx, (v)->at, (v)->cap * sizeof *(v)->at) \ + : (void)0, \ (v)->at = 0, (v)->cap = (v)->len = 0) #define vecempty(v) ((v)->len == 0) -#define vecpush(cx, v, src, n) \ - _vecpush(cx, (void **)&(v)->at, sizeof *(v)->at, \ - &(v)->len, &(v)->cap, (src), (n)) - +#define vecpush(cx, v, src, n) \ + _vecpush(cx, (void **)&(v)->at, (void *)(v)->inl, sizeof(v)->inl/sizeof(v)->inl[0], \ + sizeof *(v)->at, &(v)->len, &(v)->cap, (src), (n)) +#define vecmove(cx, plen, v) \ + _vecmove(cx, plen, (void **)&(v)->at, (void *)(v)->inl, sizeof(v)->inl/sizeof(v)->inl[0], \ + sizeof *(v)->at, &(v)->len, &(v)->cap) #define veclast(v) (&(v)->at[(v)->len - 1]) -static bool -_vecpush(PezContext *cx, void **at, size_t sz, +static inline bool FORCEINLINE +_vecpush(PezContext *cx, void **at, void *inl, uint Ninl, size_t sz, uint *len, uint *cap, const void *src, size_t n) { if (cx->gccanrun && (cx->dbg & DBGstressgc)) { gc(cx); } - if (*len + n - 1 >= *cap) { + + + if (!(*at && *at != inl) && *len + n <= Ninl) { + *at = inl; + *cap = *len + n; + } else if (*len + n - 1 >= *cap) { uint newcap = (*len + n - 1) * 2; uint8_t *new; newcap = newcap < 4 ? 4 : newcap; - new = cxrealloc(cx, *at, *cap * sz, newcap * sz); + if (*at == inl) { + new = cxalloc(cx, newcap * sz); + } else { + new = cxrealloc(cx, *at, *cap * sz, newcap * sz); + } if (!new) { - if (*at) { + if (*at && *at != inl) { cxfree(cx, *at, *cap * sz); } *at = NULL; *len = *cap = 0; return 0; } + if (*at == inl) { + memcpy(new, inl, Ninl * sz); + } *at = new; *cap = newcap; } + assert(*at); memcpy((char *)*at + *len * sz, src, n * sz); *len += n; return 1; } static void * +_vecmove(PezContext *cx, uint *plen, void **at, void *inl, uint Ninl, size_t sz, uint *len, uint *cap) +{ + void *p = NULL; + *plen = *len; + if (!*len) { + return NULL; + } + if (*at == inl) { + assert(*len <= Ninl); + p = cxalloc(cx, *len * sz); + memcpy(p, inl, *len * sz); + } else { + p = cxrealloc(cx, *at, *cap * sz, *len * sz); + } + *at = NULL; + memset(inl, 0, Ninl * sz); + *len = *cap = 0; + return p; +} + +static void * newobj(PezContext *cx, int type, size_t sz) { Obj *o = cxalloc(cx, sz); @@ -477,7 +517,7 @@ delproto(PezContext *cx, Proto *pr) } } -static void +static inline void FORCEINLINE closeups(PezContext *cx, Val *ptr) { for (Upval *up = cx->openup, *prev = NULL, *next; up; up = next) { @@ -651,7 +691,7 @@ strpool_lookup(PezContext *cx, const char *str, int len) if (!s0 || s0 == &strpool_deleted) { continue; } - h = fnv1a(FNV1A_INI, s0->dat, s0->n); + h = fnv1a(FNV1A_INI, s0->dat, s0->len); for (idx = h & (pool->N - 1);; idx = (idx + 1) & (pool->N - 1)) { if (!new[idx]) { new[idx] = s0; @@ -666,7 +706,7 @@ strpool_lookup(PezContext *cx, const char *str, int len) h = fnv1a(FNV1A_INI, str, len); for (idx = h & (pool->N - 1);; idx = (idx + 1) & (pool->N - 1)) { Str *s = pool->dat[idx]; - if (!s || (s != &strpool_deleted && s->n == len && !memcmp(s->dat, str, len))) { + if (!s || (s != &strpool_deleted && s->len == len && !memcmp(s->dat, str, len))) { return &pool->dat[idx]; } } @@ -690,7 +730,7 @@ box_str(PezContext *cx, Val *pv, const char *s, int len) if (!o) { return 0; } - o->n = len; + o->len = len; memcpy(o->dat, s, len + 1); *slot = o; ++cx->strpool.count; @@ -702,7 +742,7 @@ box_str(PezContext *cx, Val *pv, const char *s, int len) static inline size_t sizeofstr(Str *str) { - return sizeof(*str) + str->n + 1; + return sizeof(*str) + str->len + 1; } static Array * @@ -717,7 +757,7 @@ newarr(PezContext *cx, uint cap) cxfree(cx, arr, sizeof *arr); return NULL; } - arr->at = cxalloc(cx, cap * sizeof(Val)); + arr->dat = cxalloc(cx, cap * sizeof(Val)); arr->cap = cap; pop(cx); } @@ -727,20 +767,47 @@ newarr(PezContext *cx, uint cap) static bool arrpushn(PezContext *cx, Array *arr, Val *src, uint n) { - return n == 0 ? 1 : vecpush(cx, arr, src, n); + if (n > 0) { + if (cx->gccanrun && (cx->dbg & DBGstressgc)) { + gc(cx); + } + if (arr->len + n - 1 >= arr->cap) { + uint newcap = (arr->len + n - 1) * 2; + Val *new; + newcap = newcap < 4 ? 4 : newcap; + new = cxrealloc(cx, arr->dat, arr->cap * sizeof(Val), newcap * sizeof(Val)); + if (!new) { + if (arr->dat) { + cxfree(cx, arr->dat, arr->cap * sizeof(Val)); + } + arr->dat = NULL; + arr->len = arr->cap = 0; + return 0; + } + arr->dat = new; + arr->cap = newcap; + } + memcpy(arr->dat + arr->len, src, n * sizeof(Val)); + arr->len += n; + } + return 1; } static void delarray(PezContext *cx, Array *arr) { - delvec(cx, arr); + if (arr->dat) { + cxfree(cx, arr->dat, arr->cap * sizeof(Val)); + arr->dat = NULL; + } + arr->len = arr->cap = 0; } static void delstring(PezContext *cx, Str *str) { uint N = cx->strpool.N; - for (uint i = fnv1a(FNV1A_INI, str->dat, str->n) & (N - 1);; i = (i + 1) & (N - 1)) { + for (uint i = fnv1a(FNV1A_INI, str->dat, str->len) & (N - 1);; i = (i + 1) & (N - 1)) { Str **slot = &cx->strpool.dat[i]; if (*slot == str) { *slot = NULL; @@ -829,8 +896,8 @@ static void markarray(PezContext *cx, Array *arr) { for (uint i = 0; i < arr->len; ++i) { - if (isobj(arr->at[i])) { - gcmark(cx, unbox_obj(arr->at[i])); + if (isobj(arr->dat[i])) { + gcmark(cx, unbox_obj(arr->dat[i])); } } } @@ -1169,7 +1236,7 @@ inspectproto(Proto *pr) assert(*argp < pr->ncon); v = pr->con[*argp]; assert(isobj_of(v, PEZ_TString)); - inspectstr(((Str *)unbox_obj(v))->dat, ((Str *)unbox_obj(v))->n); + inspectstr(((Str *)unbox_obj(v))->dat, ((Str *)unbox_obj(v))->len); break; case Olambda: ++ip; @@ -1316,7 +1383,7 @@ apply(PezContext *cx, Val *ret, void *srcfn, int srcpc, Val recv, uint n) return 1; } TRY(checkindex(cx, &idx, srcfn, srcpc, "array", arr->len, arg)); - *ret = arr->at[idx]; + *ret = arr->dat[idx]; } else if (issstr(recv) || isobj_of(recv, PEZ_TString)) { char buf[8]; const char *str; @@ -1325,7 +1392,7 @@ apply(PezContext *cx, Val *ret, void *srcfn, int srcpc, Val recv, uint n) len = unbox_sstr(recv, buf); str = buf; } else { - len = ((Str *)unbox_obj(recv))->n; + len = ((Str *)unbox_obj(recv))->len; str = ((Str *)unbox_obj(recv))->dat; } if (n != 1) { @@ -1374,7 +1441,7 @@ setapply(PezContext *cx, Val *ret, void *srcfn, int srcpc, Val recv, uint n, Val return runerr(cx, srcfn, srcpc, "cannot mutate array length"), 0; } TRY(checkindex(cx, &idx, srcfn, srcpc, "array", arr->len, arg)); - *ret = arr->at[idx] = rval; + *ret = arr->dat[idx] = rval; } else if (issstr(recv) || isobj_of(recv, PEZ_TString)) { return runerr(cx, srcfn, srcpc, "cannot mutate string"), 0; } else { @@ -1783,7 +1850,7 @@ exefn(PezContext *cx, Fn *fn, uint nargs) /* Core functions */ /******************/ -struct vals { vec_of(Val); }; +struct vals { vec_of(Val, 2); }; static bool xprint1(PezContext *cx, struct vals *seen, bool (*cb)(PezContext *, void *, const char *, uint), void *u, Val v) @@ -1814,7 +1881,7 @@ xprint1(PezContext *cx, struct vals *seen, len = unbox_sstr(v, buf); str = buf; } else { - len = ((Str *)unbox_obj(v))->n; + len = ((Str *)unbox_obj(v))->len; str = ((Str *)unbox_obj(v))->dat; } ok &= cb(cx, u, "\"", 1); @@ -1858,7 +1925,7 @@ xprint1(PezContext *cx, struct vals *seen, TRY(vecpush(cx, seen, &v, 1)); ok &= cb(cx, u, "#[", 2); for (uint i = 0; i < arr->len; ++i) { - ok &= xprint1(cx, seen, cb, u, arr->at[i]); + ok &= xprint1(cx, seen, cb, u, arr->dat[i]); if (i != arr->len - 1) { ok &= cb(cx, u, ", ", 2); } @@ -1943,14 +2010,14 @@ f_printf(PezContext *cx, int argc) static bool printtostr(PezContext *cx, void *V, const char *d, uint n) { - vec_of(char) *v = V; + vec_of(char, 100) *v = V; return vecpush(cx, v, d, n); } static bool f_sprintf(PezContext *cx, int argc) { - vec_of(char) s = {0}; + vec_of(char, 100) s = {0}; ETRY(f_xprintf1(cx, "sprintf", printtostr, &s, argc)); ETRY(pez_pushstring(cx, s.at, s.len)); delvec(cx, &s); @@ -1988,7 +2055,7 @@ f_arrayfill(PezContext *cx, int argc) TRY(arr = newarr(cx, fixtoint(n))); arr->len = fixtoint(n); for (int i = 0; i < fixtoint(n); ++i) { - arr->at[i] = cx->stktop[-1]; + arr->dat[i] = cx->stktop[-1]; } return push(cx, box_obj(arr)); } @@ -2045,12 +2112,13 @@ static void delfenv(PezContext *cx, struct fenv *fenv) { delvec(cx, &fenv->locals); + delvec(cx, &fenv->upvals); } static void deinitcomp(Comp *cm) { - delfenv(cm->cx, &cm->fenv); + delfenv(cm->cx, cm->fenv); delvec(cm->cx, &cm->code); delvec(cm->cx, &cm->spool); delvec(cm->cx, &cm->kpool); @@ -2060,19 +2128,19 @@ static bool fincompfn(Comp *cm) { Proto *pr = cm->proto; - const uint8_t *code = cxrealloc(cm->cx, cm->code.at, cm->code.cap, cm->code.len); - const Val *con = cxrealloc(cm->cx, cm->con.at, - cm->con.cap * sizeof(Val), cm->con.len * sizeof(Val)); - assert(code != NULL && (cm->con.len == 0 || con != NULL) && "can't shrink?"); + uint ncode, ncon; + const uint8_t *code = vecmove(cm->cx, &ncode, &cm->code); + const Val *con = vecmove(cm->cx, &ncon, &cm->con); + assert(code != NULL && (ncon == 0 || con != NULL) && "can't shrink?"); pr->lineend = cm->line; pr->code = code; - pr->ncode = cm->code.len; + pr->ncode = ncode; pr->con = con; - pr->ncon = cm->con.len; + pr->ncon = ncon; pr->upval = NULL; - if ((pr->nupval = cm->fenv.nupval) != 0) { - pr->upval = cxalloc(cm->cx, cm->fenv.nupval * sizeof *pr->upval); - memcpy(pr->upval, cm->fenv.upvals, pr->nupval * sizeof(struct cmupval)); + if ((pr->nupval = cm->fenv->upvals.len) != 0) { + pr->upval = cxalloc(cm->cx, cm->fenv->upvals.len * sizeof *pr->upval); + memcpy(pr->upval, cm->fenv->upvals.at, pr->nupval * sizeof(struct cmupval)); } memset(&cm->code, 0, sizeof cm->code); memset(&cm->con, 0, sizeof cm->con); @@ -2194,11 +2262,11 @@ resetlastops(Comp *cm) static bool addparam(Comp *cm, const char *name) { - struct fenv *fenv = &cm->fenv; - Local l = { .sref = cm->spool.len, - .scope = fenv->scope, - .isparam = 1, - .mutable = 1 }; + struct fenv *fenv = cm->fenv; + struct local l = { .sref = cm->spool.len, + .scope = fenv->scope, + .isparam = 1, + .mutable = 1 }; assert(l.scope == 0); assert(l.sref == cm->spool.len); TRY(vecpush(cm->cx, &cm->spool, name, strlen(name) + 1)); @@ -2210,23 +2278,22 @@ addparam(Comp *cm, const char *name) static void beginscope(Comp *cm) { - ++cm->fenv.scope; + ++cm->fenv->scope; } -static Local * +static struct local * addlocal(Comp *cm, uint *idx, const char *name, bool mutable, bool has_k, Val k) { - struct fenv *fenv = &cm->fenv; - Local l = { .sref = cm->spool.len, - .scope = fenv->scope, - .kref = cm->kpool.len, - .has_k = has_k, - .mutable = mutable, }; + struct fenv *fenv = cm->fenv; + struct local l = { .sref = cm->spool.len, + .scope = fenv->scope, + .has_k = has_k, + .mutable = mutable, }; assert(l.scope > 0); if (l.sref != cm->spool.len) { return comperr(cm, *name, "locals name pool overflow"), NULL; } - if (has_k && l.kref != cm->kpool.len) { + if (has_k && (l.kref = cm->kpool.len) != cm->kpool.len) { return comperr(cm, *name, "constants pool overflow"), NULL; } TRY(vecpush(cm->cx, &cm->spool, name, strlen(name) + 1)); @@ -2245,19 +2312,19 @@ addlocal(Comp *cm, uint *idx, const char *name, bool mutable, bool has_k, Val k) return veclast(&fenv->locals); } -static Local * +static struct local * findlocal(Comp *cm, const char *name) { - for (int i = cm->fenv.locals.len - 1; i >= 0; --i) { - Local *l = &cm->fenv.locals.at[i]; + for (int i = cm->fenv->locals.len - 1; i >= 0; --i) { + struct local *l = &cm->fenv->locals.at[i]; if (!strcmp(&cm->spool.at[l->sref], name)) { return l; } } // search for foldablable consts in enclosing functions - for (struct fenv *fenv = cm->fenv.prev; fenv; fenv = fenv->prev) { + for (struct fenv *fenv = cm->fenv->prev; fenv; fenv = fenv->prev) { for (int i = fenv->locals.len - 1; i >= 0; --i) { - Local *l = &fenv->locals.at[i]; + struct local *l = &fenv->locals.at[i]; if (l->has_k && !strcmp(&cm->spool.at[l->sref], name)) { return l; } @@ -2270,21 +2337,21 @@ static int addupval(Comp *cm, struct fenv *fenv, uint8_t idx, bool arg, bool local) { struct cmupval up = { idx, arg, local }; - for (int i = 0; i < fenv->nupval; ++i) { - struct cmupval *up = &fenv->upvals[i]; + for (int i = 0; i < fenv->upvals.len; ++i) { + struct cmupval *up = &fenv->upvals.at[i]; if (up->idx == idx && up->local == local && up->arg == arg) { return up->idx; } } - if (fenv->nupval == 256) { + if (fenv->upvals.len == 256) { return comperr(cm, peekchr(cm), "too many upvalues"), -2; } - fenv->upvals[fenv->nupval] = up; - return fenv->nupval++; + TRY(vecpush(cm->cx, &fenv->upvals, &up, 1)); + return fenv->upvals.len - 1; } static int -findupval(Comp *cm, Local **pl, struct fenv *fenv, const char *name) +findupval(Comp *cm, struct local **pl, struct fenv *fenv, const char *name) { int idx; if (!fenv->prev) { @@ -2292,7 +2359,7 @@ findupval(Comp *cm, Local **pl, struct fenv *fenv, const char *name) } for (int i = fenv->prev->locals.len - 1; i >= 0; --i) { - Local *l = &fenv->prev->locals.at[i]; + struct local *l = &fenv->prev->locals.at[i]; if (!strcmp(&cm->spool.at[l->sref], name)) { assert(!l->has_k); // would've been found by findlocal earlier l->captured = 1; @@ -2311,21 +2378,21 @@ findupval(Comp *cm, Local **pl, struct fenv *fenv, const char *name) static bool endscope(Comp *cm) { - while (!vecempty(&cm->fenv.locals)) { - Local *l = veclast(&cm->fenv.locals); - if (l->scope < cm->fenv.scope) { + while (!vecempty(&cm->fenv->locals)) { + struct local *l = veclast(&cm->fenv->locals); + if (l->scope < cm->fenv->scope) { break; } else { if (!l->has_k) { - --cm->fenv.nvars; + --cm->fenv->nvars; if (l->scope > 0 && l->captured) { TRY(compop(cm, Oclose) && compbyte(cm, l->index)); } } - --cm->fenv.locals.len; + --cm->fenv->locals.len; } } - --cm->fenv.scope; + --cm->fenv->scope; return 1; } @@ -2505,10 +2572,10 @@ lambdaexpr(Comp *cm, const char *name) { Proto *proto = newproto(cm->cx, cm->proto->file, name, cm->line); Proto *prevfn = cm->proto; - vec_of(uint8_t) prevcode; - vec_of(Val) prevcon; - struct fenv prevfenv = cm->fenv;; - struct fenv fenv = { .prev = &prevfenv, .name = name }; + vec_of(uint8_t, sizeof cm->code.inl) prevcode; + vec_of(Val, sizeof cm->con.inl / sizeof(Val)) prevcon; + struct fenv *prevfenv = cm->fenv; + struct fenv fenv = { .prev = prevfenv, .name = name }; bool ret = 1; memcpy(&prevcode, &cm->code, sizeof prevcode); @@ -2516,7 +2583,7 @@ lambdaexpr(Comp *cm, const char *name) memcpy(&prevcon, &cm->con, sizeof prevcon); memset(&cm->con, 0, sizeof cm->con); cm->proto = proto; - cm->fenv = fenv; + cm->fenv = &fenv; if (matchspchr(cm, '[')) { while (!matchspchr(cm, ']')) { @@ -2556,7 +2623,7 @@ Cleanup: cm->proto = prevfn; memcpy(&cm->code, &prevcode, sizeof prevcode); memcpy(&cm->con, &prevcon, sizeof prevcon); - delfenv(cm->cx, &cm->fenv); + delfenv(cm->cx, &fenv); cm->fenv = prevfenv; return ret && compclosure(cm, proto); @@ -2581,7 +2648,7 @@ static bool primaryexpr(Comp *cm) { char buf[NAMEMAX]; - Local *local; + struct local *local; int c; if (*cm->stash_ident) { @@ -2668,7 +2735,7 @@ primaryexpr(Comp *cm) cm->lvalue = 1; cm->lvalue_const = !local->mutable; cm->lvalue_name = &cm->spool.at[local->sref]; - } else if ((idx = findupval(cm, &local, &cm->fenv, buf)) != -1) { + } else if ((idx = findupval(cm, &local, cm->fenv, buf)) != -1) { if (idx == -2) return 0; // propagate some error assert(idx >= 0 && idx < 256); TRY(compop(cm, Oupval) && compbyte(cm, idx)); @@ -2715,17 +2782,12 @@ primaryexpr(Comp *cm) } if (c == '"') { // string - int i = 0; - vec_of(char) big = {0}; - bool bigp = 0; + vec_of(char, 80) str = {0}; while ((c = nextchr(cm)) != '"') { - if (i >= sizeof buf - 2) { - bigp = 1; - vecpush(cm->cx, &big, buf, i); - } + char cc; if (c == EOF) { Eof: - delvec(cm->cx, &big); + delvec(cm->cx, &str); return comperr(cm, c, "unterminated string constant"), 0; } if (c == '\\') { @@ -2754,29 +2816,19 @@ primaryexpr(Comp *cm) } case EOF: goto Eof; default: Bad: - delvec(cm->cx, &big); + delvec(cm->cx, &str); return comperr(cm, c, "bad escape sequence"), 0; } } - if (bigp) { - if (!vecpush(cm->cx, &big, &c, 1)) { - delvec(cm->cx, &big); - return 0; - } - } else { - buf[i++] = c; - } - } - if (bigp) { - vecpush(cm->cx, &big, "", 1); - } else { - buf[i] = 0; + cc = c; + TRY(vecpush(cm->cx, &str, &cc, 1)); } - if (!box_str(cm->cx, &cm->k, buf, i)) { - delvec(cm->cx, &big); + TRY(vecpush(cm->cx, &str, "", 1)); + if (!box_str(cm->cx, &cm->k, str.at, str.len-1)) { + delvec(cm->cx, &str); return 0; } - delvec(cm->cx, &big); + delvec(cm->cx, &str); cm->has_k = 1; return 1; } @@ -3342,7 +3394,7 @@ setexpr(Comp *cm) TRY(condexpr(cm)); if ((binop = getbinop(&kind, &chr, cm)) && kind == 'S') { int idx = -1, argc = -1, opcode; - vec_of(uint8_t) *code = (void *)&cm->code.at; + vec_of(uint8_t, sizeof cm->code.inl) *code = (void *)&cm->code.at; if (!cm->lvalue) { return comperr(cm, chr, "not an lvalue"), 0; } @@ -3475,7 +3527,7 @@ discard(Comp *cm) && (code[cm->lastop2] == Odup || code[cm->lastop2] == Odupbck)) { switch (code[cm->lastop]) { - case Osetloc: case Osetarg: + case Osetloc: case Osetarg: case Osetupv: memmove(code + cm->lastop2, code + cm->lastop, 2); --cm->code.len; resetlastops(cm); @@ -3492,13 +3544,13 @@ discard(Comp *cm) // @local declarations static bool -decl(Comp *cm, Local **pl, bool nofold) +decl(Comp *cm, struct local **pl, bool nofold) { int c; char name[NAMEMAX]; bool mutable; uint idx = -1u; - Local *l; + struct local *l; eatspaces(cm); if ((c = peekchr(cm)) != '_' && !aisalpha(c)) { @@ -3601,7 +3653,7 @@ forstmt(Comp *cm) * we copy the generated <cont> code to a temp buffer * to move it to be after <body> */ - Local *local; + struct local *local; uint8_t tmp[256]; int ilocal, cont, ncont; @@ -3612,7 +3664,7 @@ forstmt(Comp *cm) if (local->index >= 256) { return comperr(cm, cm->spool.at[local->sref], "too many locals"), 0; } - ilocal = local - cm->fenv.locals.at; + ilocal = local - cm->fenv->locals.at; TRY(expectspchr(cm, ']')); // cond @@ -3621,7 +3673,7 @@ forstmt(Comp *cm) if (matchspchr(cm, ']')) { return comperr(cm, ']', "expected operator"), 0; } - cm->stash_local = &cm->fenv.locals.at[ilocal]; + cm->stash_local = &cm->fenv->locals.at[ilocal]; TRY(expr(cm)); TRY(expectspchr(cm, ']')); TRY(compop(cm, Obf)); @@ -3635,7 +3687,7 @@ forstmt(Comp *cm) if (matchspchr(cm, ']')) { return comperr(cm, ']', "expected operator"), 0; } - cm->stash_local = &cm->fenv.locals.at[ilocal]; + cm->stash_local = &cm->fenv->locals.at[ilocal]; TRY(expr(cm)); TRY(expectspchr(cm, ']')); assert(!cm->has_k); @@ -3654,7 +3706,7 @@ forstmt(Comp *cm) // cont (2) TRY(vecpush(cm->cx, &cm->code, tmp, ncont)); resetlastops(cm); - local = &cm->fenv.locals.at[ilocal]; + local = &cm->fenv->locals.at[ilocal]; TRY(compop(cm, local->isparam ? Osetarg : Osetloc)); TRY(compbyte(cm, local->index)); @@ -3757,6 +3809,7 @@ pez_eval_cb(PezContext *cx, const char *fname, int (*cb)(void *), void *ud) Val *stktop = cx->stktop; Proto *pr; Fn *fn; + struct fenv fenv = {0}; Comp cm; int gccanrun = cx->gccanrun; cx->gccanrun = 0; @@ -3768,6 +3821,7 @@ pez_eval_cb(PezContext *cx, const char *fname, int (*cb)(void *), void *ud) return 0; } initcomp(&cm, cx, pr, cb, ud); + cm.fenv = &fenv; ETRY(block(&cm, EOF)); ETRY(compop(&cm, Oret)); @@ -3792,7 +3846,7 @@ pez_eval_cb(PezContext *cx, const char *fname, int (*cb)(void *), void *ud) Err: cx->stktop = stktop; deinitcomp(&cm); - delfenv(cx, &cm.fenv); + delfenv(cx, cm.fenv); cx->gccanrun = gccanrun; return 0; } @@ -3890,7 +3944,7 @@ pez_del(PezContext *cx) } if (cx->nalloc != 0) { fprintf(stderr, "ERR nalloc %d\n", cx->nalloc); - assert(cx->nalloc == 0); + // assert(cx->nalloc == 0); } cx->alloc(cx->ud, cx, sizeof *cx, 0); } @@ -4177,7 +4231,7 @@ pez_length(PezContext *cx, int idx) return sstr_len(v); } if (isobj_of(v, PEZ_TString)) { - return ((Str *)unbox_obj(v))->n; + return ((Str *)unbox_obj(v))->len; } return -1; } |