diff options
| author | 2026-10-15 02:35:04 +0330 | |
|---|---|---|
| committer | 2026-10-15 02:40:51 +0330 | |
| commit | 31ae48845492c12f2745c7f4c0cd2ea448e0942a (patch) | |
| tree | bcd26f483f4774fbcbae9c621050b10b3b53f295 /src/compiler/expr.zc | |
| parent | genmap: default genome reservation 0x70000 words (the genome had 197 words le... (diff) | |
destructors: reassigning an m owner that still holds a value frees the old value first, running its drop (right side first, then the free, then the store), with hint: x: reassigning frees the old value; a new value that is part of the old one is an error; u, d and captured owners keep the leak error; the new value's size, leaf type and drop are recorded like a declaration's; spec 6.8.5, 6.15.2
Diffstat (limited to 'src/compiler/expr.zc')
| -rw-r--r-- | src/compiler/expr.zc | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/src/compiler/expr.zc b/src/compiler/expr.zc index e6acfc8..7687394 100644 --- a/src/compiler/expr.zc +++ b/src/compiler/expr.zc @@ -1868,8 +1868,8 @@ int expr() { next(); a = o3on && k == LV_LOCAL && (ltag[i] & 16) && !larr[i]; if (a) op(O_DROP); // an o3 variable: its address comes after the value, so it never waits on the stack across a branch - xlend = -1; - rc = expr(); rval(); + xlend = -1; newsz = -1; newleaf = 0; + rc = expr(); rval(); fk = drop_tail == here; if (k != LV_LOCAL) af_escape(xaf); fcoerce(lt); if (k == LV_LOCAL) { @@ -1881,6 +1881,13 @@ int expr() { if (cmode && !dry && k == LV_GLOBAL) { vf_symbols(); svkind[i] = xvk; svvalue[i] = xvv; } else if (k != LV_LOCAL) vf_effect(); if (!compat(lt, xty)) tcerr("assignment", lt, xty); + if (k == LV_LOCAL) { + reassign_free(i, rc, xbor); + if (rc == C_FRESH && fchk) { // the new value's size and drop, as a declaration records them + lnsz[i] = newsz; lleaf[i] = newleaf; if (local_dropset) local_dropset[i] = fk; + if (ltag[i] & LREAD) ltag[i] = (ltag[i] - LREAD) | LWASREAD; + } + } if (a) { lit(0); op(O_PICK); vaddr(i); op(O_ST); o3refresh(i); } else { if (o3on && k != LV_ELEM && hasptr(lt)) { lit(lt); callname(s_fatten); } // o3 data going somewhere normal code can see |
