aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/expr.zc
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-15 02:35:04 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-15 02:40:51 +0330
commit31ae48845492c12f2745c7f4c0cd2ea448e0942a (patch)
treebcd26f483f4774fbcbae9c621050b10b3b53f295 /src/compiler/expr.zc
parentgenmap: 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.zc11
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