cgen: *p=sliceval deref store -> 3-word (both stages, #79)
A slice VALUE stored through a whole-deref lhs `*p = v` dropped len+cap:
the `*p = v` arm kind-gated its 3-word {ptr,len,cap} stash+store on str
ONLY, so a slice fell to the 1-word fldstoreop default (ptr only). The
deref READ is 3-word, so the reader got garbage len/cap -- correctness,
not perf. str IS []u8 since #1, so the str machinery applies verbatim;
widen the gate str -> str||slice (kind-OR, not a sz==24 test). This is
the project #75 str-only-gate one level down (deref-store).
cstage cmd/w6c/cgen.c:3792/3800 (two gates); wwstage cgenexpr.ww `*p=v`
twin detects N_TSLICE syntactically (mirror str). Both stages dropped
identically, so cs==ww + 990-997 + byte-id are all gate-blind here --
only a store->read roundtrip catches it. New 944_deref_slice_store_run
asserts the {ptr,len,cap} survives a poisoned dst, via the direct local
and the field-deref read; str-deref + (*p).field controls guard the
untouched arms. Verified fail-before (1-word ptr store) / pass-after
(8/8), byte-identical asm both stages.
Out-of-gate, deferred to #80: the wwstage syntactic detection is
alias-BLIND -- a slice-alias `*Foo` (Foo=[]T) or non-ident deref-store
stays 1-word, the SAME retained divergence str already carries (cstage's
resolved-type vt fires in both). #80 unifies detection by aligning the
wwstage UP, not gating cstage down. Separately surfaced (filed apart,
not touched here): the whole-deref READ-into-let `let v = *p` drops
len+cap for a slice while the str form is 3-word -- the read-side twin
of this store hole.
This commit is contained in:
@@ -17559,6 +17559,16 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
else { if (ps == 4) { storeop = "MOVL"; }; };
|
||||
}; }; };
|
||||
};
|
||||
// A slice IS the same 3-word {ptr,len,cap}
|
||||
// header as str (ref/hare/rt/ensure.ha:4-8),
|
||||
// so `*p = sliceval` takes str's stash+store
|
||||
// path (#79; precedent cgenstmt.ww:1631,
|
||||
// cgenexpr.ww:1684). LIKE str this is
|
||||
// alias-BLIND: a slice-alias `*Foo` / non-ident
|
||||
// deref-store stays 1-word, the SAME divergence
|
||||
// str carries; resolved-vs-syntactic detection
|
||||
// is unified UP in #80, not patched here.
|
||||
if (pe.kind == nkind.N_TSLICE) { elemstr = true; };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -3700,6 +3700,16 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
else { if (ps == 4) { storeop = "MOVL"; }; };
|
||||
}; }; };
|
||||
};
|
||||
// A slice IS the same 3-word {ptr,len,cap}
|
||||
// header as str (ref/hare/rt/ensure.ha:4-8),
|
||||
// so `*p = sliceval` takes str's stash+store
|
||||
// path (#79; precedent cgenstmt.ww:1631,
|
||||
// cgenexpr.ww:1684). LIKE str this is
|
||||
// alias-BLIND: a slice-alias `*Foo` / non-ident
|
||||
// deref-store stays 1-word, the SAME divergence
|
||||
// str carries; resolved-vs-syntactic detection
|
||||
// is unified UP in #80, not patched here.
|
||||
if (pe.kind == nkind.N_TSLICE) { elemstr = true; };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -17559,6 +17559,16 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
else { if (ps == 4) { storeop = "MOVL"; }; };
|
||||
}; }; };
|
||||
};
|
||||
// A slice IS the same 3-word {ptr,len,cap}
|
||||
// header as str (ref/hare/rt/ensure.ha:4-8),
|
||||
// so `*p = sliceval` takes str's stash+store
|
||||
// path (#79; precedent cgenstmt.ww:1631,
|
||||
// cgenexpr.ww:1684). LIKE str this is
|
||||
// alias-BLIND: a slice-alias `*Foo` / non-ident
|
||||
// deref-store stays 1-word, the SAME divergence
|
||||
// str carries; resolved-vs-syntactic detection
|
||||
// is unified UP in #80, not patched here.
|
||||
if (pe.kind == nkind.N_TSLICE) { elemstr = true; };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user