wcc/cgen: #121 indexed tuple-element read + literal-store round-trip (both-stage)
Reading or storing a tuple element of an indexed array element was
broken across the board (the fold-6 read-path). One fused commit,
both stages, four faces of indexed tuple-element access:
- FIELD read `tbl[i].N`: was loud ("unsupported field-read shape" --
the field-read dispatch keyed on an N_IDENT base; an INDEX base fell
to a fatal). Now resolves &tbl[i] via the place-spine and reads the
field at addr+foff through the existing per-kind arms (str-triple /
scalar / fn-ptr).
- WHOLE read `let e = tbl[i]`: was a silent word0-only truncation
(plain-tuple kin of #37/#58, which covered only tagged). Now a full
cursor fill from &tbl[i].
- STORE `a[i] = (3,4)` (N_TUPLE-literal rhs): was a silent word0-only
store -- the write face of the read. The aggregate-store-into-index
site handled ident/dot/deref tuple rhs but not the literal; now it
materializes the literal and word-copies. Narrow: N_IDENT base only
(N_DOT/chained stay deferred, #270).
- for-range over a const-slice-of-tuple: was a divergent SEGV; now a
symmetric loud-stop on both stages (filed #122).
The store and read were a round-trip that passed test 809 only by luck
(broken store XOR broken read canceled). Fixing the read alone exposed
the silent store; rule-7 obliges fixing both, so 809 is now genuinely
correct, not luck-correct. Both faces are byte-id-blind (#263) -- the
net is a runtime round-trip pin with distinct-per-word values and a
real call clobbering the cursor registers between store and read, so a
word0-only store or read is caught. Both stages byte-identical
(990-997 green). Pin 947_tuple_index_read_run.
This commit is contained in:
@@ -3727,6 +3727,32 @@ fn cgforrange(c: *cgen, n: *node) void = {
|
||||
baseoff = localalloc(c, bname, 8, nil);
|
||||
};
|
||||
};
|
||||
// #121 leg (c): for-range over a module-GLOBAL slice/str/array base
|
||||
// SEGV's today — the init + per-iteration base resolution below
|
||||
// assume a frame-local slot (localfindnode), so a global let/def base
|
||||
// reads saved-BP as the .ptr/.len. LOUD-STOP symmetric with cstage
|
||||
// cgen.c (byte-id-neutral; segfault→compile-error is pure
|
||||
// improvement). The fix (the N_INDEX isglobal base resolution ported
|
||||
// into the for-range spine) is a DISTINCT mechanism — filed as a #121
|
||||
// sibling, off fold-6's path.
|
||||
if (slc != nil) {
|
||||
if (slc.kind == nkind.N_IDENT) {
|
||||
if (localfindnode(c, slc.str) == nil) {
|
||||
let isglob: bool = isletvar(c, slc.str);
|
||||
if (!isglob) {
|
||||
let gdtn: *node = defvartnode(c, slc.str);
|
||||
if (gdtn != nil) {
|
||||
if (gdtn.kind == nkind.N_TARRAY) { isglob = true; };
|
||||
};
|
||||
};
|
||||
if (isglob) {
|
||||
let mc: str = "#121: for-range over a module-global slice/array base unwired (global-base resolution gap)\n";
|
||||
os.write(2, mc.ptr, mc.len: u64);
|
||||
os.exit(1);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
// Per-binding (up to 8 — matches the C array). Parallel arrays so
|
||||
// we don't depend on local-struct cgen.
|
||||
|
||||
Reference in New Issue
Block a user