summaryrefslogtreecommitdiff
path: root/pez.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-10-10 20:41:55 +0200
committerlemon <lsof@mailbox.org>2022-10-10 20:43:18 +0200
commit61ac668a962d265a0394fcab6ac534ed13784ef5 (patch)
tree3dc3d47af9ac4abd7dcaf8169a925db3b238badf /pez.c
parent6c8f7191e4366676ca7ba2cac7259d57aade0dea (diff)
better error reporting
Diffstat (limited to 'pez.c')
-rw-r--r--pez.c99
1 files changed, 76 insertions, 23 deletions
diff --git a/pez.c b/pez.c
index e000efa..3632544 100644
--- a/pez.c
+++ b/pez.c
@@ -1995,7 +1995,6 @@ f_arraypush(PezContext *cx, int argc)
{
Array *arr;
TRY(pez_checksig(cx, argc, "array#push", "array, any"));
- assert(isobj_of(cx->stktop[-2], PEZ_TArray));
arr = unbox_obj(cx->stktop[-2]);
TRY(arrpushn(cx, arr, peek(cx), 1));
return push(cx, box_obj(arr));
@@ -2222,8 +2221,12 @@ addlocal(Comp *cm, uint *idx, const char *name, bool mutable, bool has_k, Val k)
.has_k = has_k,
.mutable = mutable, };
assert(l.scope > 0);
- assert(l.sref == cm->spool.len);
- assert(l.kref == cm->kpool.len);
+ if (l.sref != cm->spool.len) {
+ return comperr(cm, *name, "locals name pool overflow"), NULL;
+ }
+ if (has_k && l.kref != cm->kpool.len) {
+ return comperr(cm, *name, "constants pool overflow"), NULL;
+ }
TRY(vecpush(cm->cx, &cm->spool, name, strlen(name) + 1));
if (mutable) {
assert(!has_k);
@@ -2271,7 +2274,9 @@ addupval(Comp *cm, struct fenv *fenv, uint8_t idx, bool arg, bool local)
return up->idx;
}
}
- assert(fenv->nupval < 256 && "upval limit");
+ if (fenv->nupval == 256) {
+ return comperr(cm, peekchr(cm), "too many upvalues"), -2;
+ }
fenv->upvals[fenv->nupval] = up;
return fenv->nupval++;
}
@@ -2644,19 +2649,24 @@ primaryexpr(Comp *cm)
if (local) {
Local:
if (local->isparam) {
- assert(local->index < 256);
+ if (local->index >= 256) {
+ return comperr(cm, *buf, "too many locals"), 0;
+ }
TRY(compop(cm, Oarg) && compbyte(cm, local->index));
} else if (local->has_k) {
cm->has_k = 1;
cm->k = cm->kpool.at[local->kref];
} else {
- assert(local->index < 256);
+ if (local->index >= 256) {
+ return comperr(cm, *buf, "too many locals"), 0;
+ }
TRY(compop(cm, Olocal) && compbyte(cm, local->index));
}
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) {
+ if (idx == -2) return 0; // propagate some error
assert(idx >= 0 && idx < 256);
TRY(compop(cm, Oupval) && compbyte(cm, idx));
cm->lvalue = 1;
@@ -2677,7 +2687,9 @@ primaryexpr(Comp *cm)
// enum-like string
int i = 0;
while (!aissep2((c = peekchr(cm)))) {
- assert(i < sizeof buf - 2);
+ if (i >= sizeof buf - 2) {
+ return comperr(cm, c, "enum-like string too long"), 0;
+ }
buf[i++] = c;
nextchr(cm);
}
@@ -2701,10 +2713,16 @@ primaryexpr(Comp *cm)
if (c == '"') {
// string
int i = 0;
+ vec_of(char) big = {0};
+ bool bigp = 0;
while ((c = nextchr(cm)) != '"') {
- assert(i < sizeof buf - 2);
+ if (i >= sizeof buf - 2) {
+ bigp = 1;
+ vecpush(cm->cx, &big, buf, i);
+ }
if (c == EOF) {
Eof:
+ delvec(cm->cx, &big);
return comperr(cm, c, "unterminated string constant"), 0;
}
if (c == '\\') {
@@ -2732,13 +2750,30 @@ primaryexpr(Comp *cm)
break;
}
case EOF: goto Eof;
- default: Bad: comperr(cm, c, "bad escape sequence"); return 0;
+ default: Bad:
+ delvec(cm->cx, &big);
+ return comperr(cm, c, "bad escape sequence"), 0;
}
}
- buf[i++] = c;
+ if (bigp) {
+ if (!vecpush(cm->cx, &big, &c, 1)) {
+ delvec(cm->cx, &big);
+ return 0;
+ }
+ } else {
+ buf[i++] = c;
+ }
}
- buf[i] = 0;
- TRY(box_str(cm->cx, &cm->k, buf, i));
+ if (bigp) {
+ vecpush(cm->cx, &big, "", 1);
+ } else {
+ buf[i] = 0;
+ }
+ if (!box_str(cm->cx, &cm->k, buf, i)) {
+ delvec(cm->cx, &big);
+ return 0;
+ }
+ delvec(cm->cx, &big);
cm->has_k = 1;
return 1;
}
@@ -3210,7 +3245,9 @@ logicexpr(Comp *cm)
TRY(flushconst(cm));
off = diff = *ip - br_jumpfrom;
- assert(off == diff);
+ if (off != diff) {
+ return comperr(cm, peekchr(cm), "branch target too far"), 0;
+ }
memcpy(cm->code.at + br_arg, &off, 2);
resetlastops(cm);
@@ -3275,13 +3312,17 @@ condexpr(Comp *cm)
TRY(expectspchr(cm, ':'));
off = diff = *ip - bf_jumpfrom;
- assert(off == diff);
+ if (off != diff) {
+ return comperr(cm, peekchr(cm), "branch target too far"), 0;
+ }
memcpy(&cm->code.at[bf_arg], &off, 2);
TRY(condexpr(cm) && flushconst(cm));
off = diff = *ip - b_jumpfrom;
- assert(off == diff);
+ if (off != diff) {
+ return comperr(cm, peekchr(cm), "branch target too far"), 0;
+ }
memcpy(&cm->code.at[b_arg], &off, 2);
resetlastops(cm);
@@ -3532,11 +3573,15 @@ forstmt(Comp *cm)
TRY(compop(cm, Ob));
off = diff = b_jumpto - (*ip + 2);
- assert(off == diff);
+ if (off != diff) {
+ return comperr(cm, peekchr(cm), "branch target too far"), 0;
+ }
TRY(compbytes(cm, &off, 2));
off = diff = *ip - bf_jumpfrom;
- assert(off == diff);
+ if (off != diff) {
+ return comperr(cm, peekchr(cm), "branch target too far"), 0;
+ }
memcpy(cm->code.at + bf_arg, &off, 2);
} else {
// FOR [@x: ini][cond][cont] body
@@ -3562,6 +3607,9 @@ forstmt(Comp *cm)
beginscope(cm);
TRY(decl(cm, &local, /* nofold */ 1) && discard(cm));
assert(local);
+ if (local->index >= 256) {
+ return comperr(cm, cm->spool.at[local->sref], "too many locals"), 0;
+ }
ilocal = local - cm->fenv.locals.at;
TRY(expectspchr(cm, ']'));
@@ -3591,7 +3639,9 @@ forstmt(Comp *cm)
assert(!cm->has_k);
ncont = *ip - cont;
assert(ncont > 0 && "?");
- assert(ncont < 256 && "cont too big");
+ if (ncont > 256) {
+ return comperr(cm, peekchr(cm), "internal error: FOR cont expression too big"), 0;
+ }
memcpy(tmp, cm->code.at + cont, ncont);
*ip -= ncont;
resetlastops(cm);
@@ -3604,19 +3654,22 @@ forstmt(Comp *cm)
resetlastops(cm);
local = &cm->fenv.locals.at[ilocal];
TRY(compop(cm, local->isparam ? Osetarg : Osetloc));
- assert(local->index < 256);
TRY(compbyte(cm, local->index));
TRY(compop(cm, Ob));
off = diff = b_jumpto - (*ip + 2);
- assert(off == diff);
+ if (off != diff) {
+ return comperr(cm, peekchr(cm), "branch target too far"), 0;
+ }
TRY(compbytes(cm, &off, 2));
off = diff = *ip - bf_jumpfrom;
- assert(off == diff);
+ if (off != diff) {
+ return comperr(cm, peekchr(cm), "branch target too far"), 0;
+ }
memcpy(cm->code.at + bf_arg, &off, 2);
- endscope(cm);
+ TRY(endscope(cm));
}
resetlastops(cm);
@@ -3688,7 +3741,7 @@ block(Comp *cm, int endchr)
return comperr(cm, EOF, "unexpected end of input"), 0;
}
nextchr(cm);
- endscope(cm);
+ TRY(endscope(cm));
return 1;
}