diff options
| -rw-r--r-- | pez.c | 59 | ||||
| -rw-r--r-- | repl.c | 2 |
2 files changed, 36 insertions, 25 deletions
@@ -203,6 +203,7 @@ struct PezContext { Obj *heap; Upval *openup; uint nalloc, gcthresh, gccanrun : 1; + int exedepth; StrPool strpool; Globals globals; }; @@ -1599,7 +1600,8 @@ exefn(PezContext *cx, Fn *fn, uint nargs) } /* Val *start = stktop; */ assert(pr->nstack > 0); - if (stktop + pr->nstack >= cx->stkend) { + if (stktop + pr->nstack >= cx->stkend || cx->exedepth++ > 6000) { + --cx->exedepth; return cx->err = PEZ_EStack, 0; } @@ -1631,6 +1633,7 @@ exefn(PezContext *cx, Fn *fn, uint nargs) push(ret); closeups(cx, args); cx->stktop = stktop; + --cx->exedepth; return 1; } CASE(Opop) { @@ -1715,7 +1718,7 @@ exefn(PezContext *cx, Fn *fn, uint nargs) k = pr->con[idx]; assert(isobj_of(k, PEZ_TFnProto)); cx->stktop = stktop; - TRY(ofn = newfn(cx, unbox_obj(k), args, locals, fn)); + ETRY(ofn = newfn(cx, unbox_obj(k), args, locals, fn)); stktop = cx->stktop; push(box_obj(ofn)); } @@ -1726,19 +1729,20 @@ exefn(PezContext *cx, Fn *fn, uint nargs) CASE(Oneg) { Val *p = peek(); if (!isnum(*p)) { - return runerr(cx, fn, ip, "attempt to negate %s value", typestr(*p)), 0; + runerr(cx, fn, ip, "attempt to negate %s value", typestr(*p)); + goto Err; } *p = box_num(-(uint32_t)unbox_num(*p)); } #define ARITH(o, oname) \ CASE(O##o) { \ - Val b = pop(), a = pop(); \ + Val b = pop(), a = pop(); \ if (!isnum(a) || !isnum(b)) { \ runerr(cx, fn, ip, "cannot %s %s and %s values", \ oname, typestr(a), typestr(b)); \ - return 0; \ + goto Err; \ } \ - push(UDO_O##o(a, b)); \ + push(UDO_O##o(a, b)); \ } ARITH(add, "add") ARITH(sub, "subtract") @@ -1765,7 +1769,7 @@ exefn(PezContext *cx, Fn *fn, uint nargs) if (!isnum(a)) { \ runerr(cx, fn, ip, "cannot %s %s and number values", \ oname, typestr(a)); \ - return 0; \ + goto Err; \ } \ *p = expr; \ } @@ -1836,16 +1840,17 @@ exefn(PezContext *cx, Fn *fn, uint nargs) fixnum num = unbox_num(a); int idx = fixtoint(num) + pr->nparams; if (!isnum(a) || num < 0 || fixtrunc(num) != num) { - return runerr(cx, fn, ip, "SEL expected positive integer index"), 0; + runerr(cx, fn, ip, "SEL expected positive integer index"); + goto Err; } push(idx >= nargs ? VOID : args[idx]); } CASE(Ogather) { int n = nargs - pr->nparams; Array *arr = newarr(cx, n); - TRY(arr); + ETRY(arr); push(box_obj(arr)); - TRY(arrpushn(cx, arr, args + pr->nparams, n)); + ETRY(arrpushn(cx, arr, args + pr->nparams, n)); } CASE(Oglobal) { Val *k = peek(), *v; @@ -1861,7 +1866,8 @@ exefn(PezContext *cx, Fn *fn, uint nargs) Str *s = unbox_obj(*k); name = s->dat; } else { assert(0); } - return runerr(cx, fn, ip, "no such global \"%s\"", name), 0; + runerr(cx, fn, ip, "no such global \"%s\"", name); + goto Err; } } CASE(Osetglo) { @@ -1880,14 +1886,15 @@ exefn(PezContext *cx, Fn *fn, uint nargs) Str *s = unbox_obj(k); name = s->dat; } else { assert(0); } - return runerr(cx, fn, ip, "no such global \"%s\"", name), 0; + runerr(cx, fn, ip, "no such global \"%s\"", name); + goto Err; } } CASE(Oputglo) { Val k, v; v = pop(); k = pop(); - TRY(putglobal(cx, k, v)); + ETRY(putglobal(cx, k, v)); } CASE(Oapply) { uint8_t n = code[ip++]; @@ -1901,17 +1908,17 @@ exefn(PezContext *cx, Fn *fn, uint nargs) if (pr->variadic ? n < pr->nparams : n != pr->nparams) { runerr(cx, fn, ip, "function takes %d arg(s), %d %s given", pr->nparams, n, n == 1 ? "was" : "were"); - return 0; + goto Err; } cx->stktop = stktop; - TRY(exefn(cx, f, n)); + ETRY(exefn(cx, f, n)); stktop = cx->stktop; ret = pop(); stktop -= n-1; *peek() = ret; } else { cx->stktop = stktop; - TRY(apply(cx, &ret, fn, ip, lhs, n)); + ETRY(apply(cx, &ret, fn, ip, lhs, n)); stktop = cx->stktop; stktop -= n-1; *peek() = ret; @@ -1923,7 +1930,7 @@ exefn(PezContext *cx, Fn *fn, uint nargs) a = stktop[-1 - n], ret; cx->stktop = stktop; - TRY(setapply(cx, &ret, fn, ip, a, n, rval)); + ETRY(setapply(cx, &ret, fn, ip, a, n, rval)); stktop = cx->stktop; stktop -= n; stktop[-1] = ret; @@ -1938,7 +1945,7 @@ exefn(PezContext *cx, Fn *fn, uint nargs) assert(ok); push(arg); cx->stktop = stktop; - TRY(apply(cx, &ret, fn, ip, a, 1)); + ETRY(apply(cx, &ret, fn, ip, a, 1)); stktop = cx->stktop; --stktop; *peek() = ret; @@ -1948,10 +1955,10 @@ exefn(PezContext *cx, Fn *fn, uint nargs) uint8_t n = code[ip++]; Array *arr; cx->stktop = stktop; - TRY((arr = newarr(cx, n)) != NULL); - TRY((push)(cx, box_obj(arr))); // gc keep + ETRY((arr = newarr(cx, n)) != NULL); + ETRY((push)(cx, box_obj(arr))); // gc keep stktop = cx->stktop; - TRY(arrpushn(cx, arr, cx->stktop - n - 1, n)); + ETRY(arrpushn(cx, arr, cx->stktop - n - 1, n)); stktop -= n + 1; push(box_obj(arr)); } @@ -1960,13 +1967,13 @@ exefn(PezContext *cx, Fn *fn, uint nargs) Val r = stktop[-n - 1]; Array *arr = unbox_obj(r); assert(isobj(r) && arr->t == PEZ_TArray); - TRY(arrpushn(cx, arr, stktop - n, n)); + ETRY(arrpushn(cx, arr, stktop - n, n)); stktop -= n; } CASE(Onewrec) { uint8_t n = code[ip++]; Record *rc; - TRY((rc = newrecord(cx, n, stktop - 2*n)) != NULL); + ETRY((rc = newrecord(cx, n, stktop - 2*n)) != NULL); stktop -= 2*n; push(box_obj(rc)); } @@ -2001,7 +2008,8 @@ exefn(PezContext *cx, Fn *fn, uint nargs) } } BADOP { - return runerr(cx, fn, ip, "bad opcode %#x", code[ip-1]), 0; + runerr(cx, fn, ip, "bad opcode %#x", code[ip-1]); + goto Err; } VMEND #undef peek @@ -2011,6 +2019,9 @@ exefn(PezContext *cx, Fn *fn, uint nargs) #undef CASE #undef VMEND #undef VMBEGIN +Err: + --cx->exedepth; + return 0; } /******************/ @@ -39,7 +39,7 @@ help(void) int main(int argc, char **argv) { - PezContext *cx = pez_new(NULL, NULL, 32*1024 /* 32KiB stack */); + PezContext *cx = pez_new(NULL, NULL, 8*1024 /* 8KiB stack */); FILE *fp = NULL; int i, ret = 0; |