diff options
| author | 2026-10-14 18:22:04 +0330 | |
|---|---|---|
| committer | 2026-10-14 20:03:38 +0330 | |
| commit | 459b7661aaa0d65d01be064bd4b9976c4f045a5c (patch) | |
| tree | eccb0738631fc52e5116fb238c2f7f961784ff36 /src/compiler/expr.zc | |
| parent | zy: nonzero exit on compile errors (diff) | |
bounds: body scan, loop-entry hoisting, pointer proofs from requested size, --explain-checks v1 (non-o3 code)
Diffstat (limited to 'src/compiler/expr.zc')
| -rw-r--r-- | src/compiler/expr.zc | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/src/compiler/expr.zc b/src/compiler/expr.zc index a548f8d..8768658 100644 --- a/src/compiler/expr.zc +++ b/src/compiler/expr.zc @@ -647,6 +647,7 @@ word closure_layout(int closure_index, int count) { // variable in. ctx_push / ctx_pop save and restore the enclosing function's // compiler state around the body. int closure() { + char* xcf; int np = 0; char*[24] pn; word[24] pty; int hop, entry, i, t, envl, ncap, c, result, declared = 0, tags = 0, tag, lt, lfl = tline; word[24] ptags; word expected = closure_expected; closure_expected = 0; reserve_closures(nclo + 1); @@ -679,6 +680,7 @@ int closure() { hop = hole(); op(O_JMP); entry = here; fn_begin(1, 0); fbnd = ctx_bnd(); + xcf = xc_fn; xc_fn = "<closure>"; lt = lt_begin(entry, "<closure>", lfl); if (declared) fty = declared; prologue(); borrow_prologue(); @@ -700,7 +702,7 @@ int closure() { if (result <= 0 || live) result = tword; if (declared) result = declared; epilogue(); - lt_end(lt, here); + lt_end(lt, here); xc_fn = xcf; nclo--; c = nclo; ncap = clo_n[c]; @@ -1363,7 +1365,7 @@ int ptr_chk(int sz) { // through rt.bchk, which only knows the size of a heap block's first word. int postfix() { return postfix_tail(primary()); } int postfix_tail(int c) { - int b, n, t, et; word ft; word[8] bs; int k, ci, was, al, ix, enh, cz, cj, place, offset, temporary, call_owner, readonly, ub, bl, ic, inr; word storage, storage_mask, call_origins; + int b, n, t, et; word ft; word[8] bs; int k, ci, was, al, ix, enh, cz, cj, place, offset, temporary, call_owner, readonly, ub, bl, ic, inr, hg, pn; word storage, storage_mask, call_origins; while (1) { if (tk == T_ID && tv == s_as) { // e as T: same bits, another type next(); t = ptype(); rval(); if (!xaf || xaf[2] != 5) xaf = 0; vf_coerce(t, 0); @@ -1415,7 +1417,7 @@ int postfix_tail(int c) { op(O_SWAP); lit(2); op(O_ADD); op(O_LD); lit(8); op(15); op(O_SWAP); if (tbytes(et) != 1) { lit(tbytes(et)); op(15); } op(O_ADD); - } else callname(intern("datb")); + } else { callname(intern("datb")); xc_note(0, XC_PACKED, place); } et = tpk(et); } else if (xty[0] == TY_DYN) { // a growable array: bounds-checked, through the runtime et = xty[4]; @@ -1468,7 +1470,7 @@ int postfix_tail(int c) { setlit(k, here); op(O_SWAP); lit(2); op(O_ADD); op(O_LD); op(O_SWAP); mulsz(et); op(O_ADD); - } else callname(s_dat); + } else { callname(s_dat); xc_note(0, xc_reason(ix, al), place); } } else { tcneed(isptr(xty) || xty == tword, "only pointers and arrays can be indexed", xty); et = telem(xty); @@ -1490,9 +1492,26 @@ int postfix_tail(int c) { tcneed(isnum(xty) || xty == tword, "an index has to be a number", xty); expect(s_rk); if (!ub && !inr) { - if (n >= 0) { if (!ic && !(ix >= 0 && proven_n(ix, n))) fixed_chk(n); } - else if (tbytes(et)) ptr_chk(0 - tbytes(et)); - else ptr_chk(tsz(et)); + if (n >= 0) { + if (!ic && !(ix >= 0 && proven_n(ix, n))) { + hg = hoist_guard(ix, n, 0 - 1); + fixed_chk(n); + if (hg >= 0) { setlit(hg, here); xc_note(0, XC_HOISTED, place); } + else xc_note(0, xc_reason(ix, 0 - 1), place); + } + } else { + pn = ptr_elems(storage, et, bl); + if (pn < 0) pn = ptr_elems(entry_fact(ix, bl), et, bl); // the loop top forgot the fact; the body leaves the pointer alone (hoist_guard and proven_p check) + if (pn >= 0 && ix >= 0 && proven_p(ix, pn, bl)) pn = pn; // the loop test proved it + else { + hg = 0 - 1; if (pn >= 0) hg = hoist_guard(ix, pn, bl); + if (tbytes(et)) ptr_chk(0 - tbytes(et)); + else ptr_chk(tsz(et)); + if (hg >= 0) { setlit(hg, here); xc_note(1, XC_HOISTED, place); } + else if (pn < 0) xc_note(1, XC_SIZE, place); + else xc_note(1, xc_reason(ix, bl), place); + } + } } if (tbytes(et)) { // packed: byte address = base * 8 + index * bytes if (tbytes(et) != 1) { lit(tbytes(et)); op(15); } |
