diff options
| author | 2026-10-14 15:58:58 +0330 | |
|---|---|---|
| committer | 2026-10-14 15:58:58 +0330 | |
| commit | d55b5fdf92a674a6495878f97a09e95bafdcba3f (patch) | |
| tree | e811149b65640a3e253e6ebdce41affddb53ac37 /src/compiler/types.zc | |
| parent | merge line tables (diff) | |
bounds checking: port agent/bounds-checking onto main 0879d0a; unbounded main in o3call, o3 tests expect no check, boundsrules, bounds_fixed, bounds_heap and zc0unbounded tests
Diffstat (limited to 'src/compiler/types.zc')
| -rw-r--r-- | src/compiler/types.zc | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/src/compiler/types.zc b/src/compiler/types.zc index 6dda110..ca31248 100644 --- a/src/compiler/types.zc +++ b/src/compiler/types.zc @@ -567,7 +567,7 @@ int kw_struct() { if (tk == T_EOF) { die("missing }"); break; } stat = 0; if (struct_const_start()) { struct_const(n); continue; } - if (is_id(s_unchecked)) { next(); stat = 2; } + while (is_id(s_unchecked) || is_id(s_unbounded)) { if (is_id(s_unchecked)) stat = stat | 2; else stat = stat | 4; next(); } if (is_id(s_static)) { // static fn name(params) { body }, or static T name(params) { body }: a function of the struct, called as Struct.name(args), with no this next(); stat = stat | 1; @@ -746,7 +746,7 @@ int tkput(word r, int k, int kind, int val, int pl) { } // compile a struct method once the struct is complete. int methdef(char* sn, char* mn, word q, int stat, int typed, int rty, int rtag) { - int n = q[0]; word r; int i, k = 0, lnp, unchecked_method = stat & 2; + int n = q[0]; word r; int i, k = 0, lnp, unchecked_method = stat & 2, unbounded_method = stat & 4, pc = (stat & 2) / 2 + (stat & 4) / 4; stat = stat & 1; if (!n) { rt.free(q); return 0; } if (!stat) { @@ -759,6 +759,7 @@ int methdef(char* sn, char* mn, word q, int stat, int typed, int rty, int rtag) r = rt.new((n + 8 + mdg * 4) * 3 + 1); lnp = q[3]; if (unchecked_method) k = tkput(r, k, T_ID, s_unchecked, lnp); + if (unbounded_method) k = tkput(r, k, T_ID, s_unbounded, lnp); k = tkput(r, k, T_ID, s_fn, lnp); r[1 + k * 3] = T_ID; r[2 + k * 3] = methname(sn, mn); r[3 + k * 3] = lnp; k++; if (mdg) { // a method of a generic struct is a generic function over the struct's parameters: fn S.m<K, V>(S<K, V>* this, ...) @@ -806,7 +807,7 @@ int methdef(char* sn, char* mn, word q, int stat, int typed, int rty, int rtag) rt.free(q); if (typed && mdg) { // retain a typed generic method as ordinary typed function tokens. - int mode = rt.outmode, length = rt.outn, capacity = rt.outcap, prefix = unchecked_method != 0; + int mode = rt.outmode, length = rt.outn, capacity = rt.outcap, prefix = pc; word output = rt.outbuf, grow = rt.outgrow, buffer = rt.new(4096), return_tokens, joined; rt.outmode = 2; rt.outbuf = m*buffer; rt.outn = 0; rt.outcap = 4095; rt.outgrow = 0; tprint(rty); if (rtag) rt.put_s(".u"); buffer[rt.outn] = 0; @@ -824,7 +825,7 @@ int methdef(char* sn, char* mn, word q, int stat, int typed, int rty, int rtag) } joined = rt.new((r[0] + return_tokens[0]) * 3 + 1); joined[0] = r[0] - 1 + return_tokens[0]; - if (prefix) rt.copy_w(joined + 1, r + 1, 3); + if (prefix) rt.copy_w(joined + 1, r + 1, prefix * 3); rt.copy_w(joined + 1 + prefix * 3, return_tokens + 1, return_tokens[0] * 3); rt.copy_w(joined + 1 + (prefix + return_tokens[0]) * 3, r + 1 + (prefix + 1) * 3, (r[0] - prefix - 1) * 3); rt.free(r); r = joined; rt.free(return_tokens); rt.free(buffer); |
