cgen: key the str/slice arg recognizers off the checker stamp
The wwstage nodeisstr/nodeisslice recognizers were name-keyed for every non-local shape: an indirect fn-pointer callee ((*f)() — the errnotest #59.5 divergence, streq receiving a shifted register file) and module-global let/const idents (path.sepstr — union-widen pushes zero-filled len/cap) both fell to false while cstage keys off the checker stamp unconditionally. Both recognizers now fall back to the stamped n.type_; push and pop sites share them, so the drain stays balanced by construction. Graduates the #59.5 errnotest pin.
This commit is contained in:
@@ -157,8 +157,14 @@ static const struct ent ents[] = {
|
||||
{ .fixture = "lib/encoding/base64/base64_test.ww",
|
||||
.mode = M_ID },
|
||||
/* #59.4 hextest graduated to M_ID above (#22a reviewer fixes) */
|
||||
/* #59.5 graduated: the wwstage nodeisstr/nodeisslice recognizers
|
||||
* fell to false for an indirect fn-pointer callee (`(*f)()`) and
|
||||
* for module-global let/const idents, so a 3-word str/slice value
|
||||
* pushed one word (or zero-filled its widen box) and cgcall
|
||||
* under-drained; both now fall back to the checker stamp. Runtime
|
||||
* pins: r595_indirect_call_str_arg, globalconst_{str,slice}_widen. */
|
||||
{ .fixture = "lib/errors/errnotest.ww",
|
||||
.mode = M_DIVERGE, .cite = "#59.5" },
|
||||
.mode = M_ID, .cite = "#59.5 graduated by the stamp-keyed recognizers" },
|
||||
/* #59.6 fmt graduated to M_ID above (#129 fix) */
|
||||
/* #59.7 siphash graduated to M_ID above (#61 fix) */
|
||||
{ .fixture = "lib/log/logtest.ww",
|
||||
|
||||
23
test/wcc/data/globalconst_slice_widen/case.ww
Normal file
23
test/wcc/data/globalconst_slice_widen/case.ww
Normal file
@@ -0,0 +1,23 @@
|
||||
//ww:run
|
||||
// A module-global const []u8 widened into a tagged-union call arg —
|
||||
// the slice twin of globalconst_str_widen (path's const dot/dotdot
|
||||
// shape).
|
||||
package main;
|
||||
|
||||
const gb: []u8 = ['x', 'y', 'z'];
|
||||
|
||||
fn f(x: ([]u8 | i32)) i32 = {
|
||||
match (x) {
|
||||
case let s: []u8 => {
|
||||
if (len(s) != 3) { return 1; };
|
||||
if (s[2] != 122u8) { return 2; };
|
||||
return 0;
|
||||
};
|
||||
case let v: i32 => { return 3; };
|
||||
};
|
||||
return 4;
|
||||
};
|
||||
|
||||
fn main() i32 = {
|
||||
return f(gb);
|
||||
};
|
||||
24
test/wcc/data/globalconst_str_widen/case.ww
Normal file
24
test/wcc/data/globalconst_str_widen/case.ww
Normal file
@@ -0,0 +1,24 @@
|
||||
//ww:run
|
||||
// A module-global const str widened into a tagged-union call arg.
|
||||
// The pre-fix wwstage nodeisstr N_IDENT arm knew only frame slots and
|
||||
// defs, so the widen push took the scalar arm and zero-filled len/cap
|
||||
// (path.sepstr's strings.hasprefix shape).
|
||||
package main;
|
||||
|
||||
const gs: str = "hello";
|
||||
|
||||
fn f(x: (str | i32)) i32 = {
|
||||
match (x) {
|
||||
case let s: str => {
|
||||
if (s.len != 5) { return 1; };
|
||||
if (s[4] != 111u8) { return 2; };
|
||||
return 0;
|
||||
};
|
||||
case let v: i32 => { return 3; };
|
||||
};
|
||||
return 4;
|
||||
};
|
||||
|
||||
fn main() i32 = {
|
||||
return f(gs);
|
||||
};
|
||||
22
test/wcc/data/r595_indirect_call_str_arg/case.ww
Normal file
22
test/wcc/data/r595_indirect_call_str_arg/case.ww
Normal file
@@ -0,0 +1,22 @@
|
||||
//ww:run
|
||||
// #59.5: a str returned by an INDIRECT fn-pointer call, passed
|
||||
// directly as a call arg. The pre-fix wwstage nodeisstr/nodeisslice
|
||||
// N_CALL arms were callee-name-keyed and fell to false for the
|
||||
// N_UN(STAR) callee, so only the ptr word was pushed and the callee
|
||||
// read a shifted register file (len=b.ptr).
|
||||
package main;
|
||||
|
||||
fn hello() str = {
|
||||
return "hello";
|
||||
};
|
||||
|
||||
fn taker(s: str) i32 = {
|
||||
if (s.len != 5) { return 1; };
|
||||
if (s[0] != 104u8) { return 2; };
|
||||
return 0;
|
||||
};
|
||||
|
||||
fn main() i32 = {
|
||||
let f = (&hello): *fn() str;
|
||||
return taker((*f)());
|
||||
};
|
||||
Reference in New Issue
Block a user