wcc/ww: nodeisslice/nodeisstr local idents read the checker stamp
Collapse the localfindnode tnode read to the stamped n.type_ — a zero-delta mechanic validation for the F7 predicate type-keying arc: self-compile byte-id holds on all four bootstrap combineds, proving n.type_ matches the local-table truth on every corpus local before any behavior-changing conversion lands. The localfindnode gate stays so a global-not-def ident still routes false.
This commit is contained in:
@@ -18521,7 +18521,15 @@ fn nodeisslice(c: *cgen, n: *node) bool = {
|
||||
if (k == nkind.N_IDENT) {
|
||||
let nm: str = n.str;
|
||||
let lc: *local = localfindnode(c, nm);
|
||||
if (lc != nil) { return isslicetype(c, lc.tnode); };
|
||||
// F7-c1: the local read collapses onto the checker-stamped
|
||||
// n.type_, the same shape cstage's node_isslice uses
|
||||
// (cmd/w6c/cgen.c:182 type_isslice(n->type)). lc.tnode.type_
|
||||
// (what isslicetype read) and n.type_ are the same tinfo for a
|
||||
// local ident (exprtype N_IDENT stamps n.type_ off the same
|
||||
// decl localfindnode keys on); the localfindnode gate stays to
|
||||
// keep the global-var-not-def case routing to false (out of F7
|
||||
// scope), so this is a zero-delta mechanic validation.
|
||||
if (lc != nil) { return typeisslice(n.type_: *tinfo); };
|
||||
// #21: a module-level `def g: []T` ident is not a frame
|
||||
// slot (localfindnode→nil), so the local arm above misses
|
||||
// it and it would fall to the scalar single-PUSHQ default,
|
||||
@@ -18605,13 +18613,17 @@ fn nodeisstr(c: *cgen, n: *node) bool = {
|
||||
if (k == nkind.N_IDENT) {
|
||||
let nm: str = n.str;
|
||||
let lc: *local = localfindnode(c, nm);
|
||||
if (lc != nil) {
|
||||
// Use isstrtype so `!str` aliases (parserr = !str) and
|
||||
// `type foo = str;` chains resolve through. The bare
|
||||
// `streq("str", ...)` test missed them and dropped the
|
||||
// MOVQ BX,CX shuffle on returns of str-aliased locals.
|
||||
if (isstrtype(c, lc.tnode)) { return true; };
|
||||
};
|
||||
// F7-c1: the local read collapses onto the checker-stamped
|
||||
// n.type_, the same shape cstage's node_isstr uses (cmd/w6c/
|
||||
// cgen.c:213 type_isstr(n->type)). typeisstr chases TY_NAMED so
|
||||
// `!str` aliases (parserr = !str) and `type foo = str;` chains
|
||||
// resolve through exactly as isstrtype(lc.tnode) did — n.type_
|
||||
// and lc.tnode.type_ are the same tinfo for a local ident
|
||||
// (exprtype N_IDENT stamps n.type_ off the same decl
|
||||
// localfindnode keys on). The localfindnode gate stays to keep
|
||||
// the global-var-not-def case routing to false (out of F7
|
||||
// scope), so this is a zero-delta mechanic validation.
|
||||
if (lc != nil) { return typeisstr(n.type_: *tinfo); };
|
||||
// #21: a module-level `def s: str` ident is not a frame slot
|
||||
// (localfindnode→nil), so the local arm above misses it and
|
||||
// it would fall to the scalar single-PUSHQ default, dropping
|
||||
|
||||
@@ -1148,7 +1148,15 @@ fn nodeisslice(c: *cgen, n: *node) bool = {
|
||||
if (k == nkind.N_IDENT) {
|
||||
let nm: str = n.str;
|
||||
let lc: *local = localfindnode(c, nm);
|
||||
if (lc != nil) { return isslicetype(c, lc.tnode); };
|
||||
// F7-c1: the local read collapses onto the checker-stamped
|
||||
// n.type_, the same shape cstage's node_isslice uses
|
||||
// (cmd/w6c/cgen.c:182 type_isslice(n->type)). lc.tnode.type_
|
||||
// (what isslicetype read) and n.type_ are the same tinfo for a
|
||||
// local ident (exprtype N_IDENT stamps n.type_ off the same
|
||||
// decl localfindnode keys on); the localfindnode gate stays to
|
||||
// keep the global-var-not-def case routing to false (out of F7
|
||||
// scope), so this is a zero-delta mechanic validation.
|
||||
if (lc != nil) { return typeisslice(n.type_: *tinfo); };
|
||||
// #21: a module-level `def g: []T` ident is not a frame
|
||||
// slot (localfindnode→nil), so the local arm above misses
|
||||
// it and it would fall to the scalar single-PUSHQ default,
|
||||
@@ -1232,13 +1240,17 @@ fn nodeisstr(c: *cgen, n: *node) bool = {
|
||||
if (k == nkind.N_IDENT) {
|
||||
let nm: str = n.str;
|
||||
let lc: *local = localfindnode(c, nm);
|
||||
if (lc != nil) {
|
||||
// Use isstrtype so `!str` aliases (parserr = !str) and
|
||||
// `type foo = str;` chains resolve through. The bare
|
||||
// `streq("str", ...)` test missed them and dropped the
|
||||
// MOVQ BX,CX shuffle on returns of str-aliased locals.
|
||||
if (isstrtype(c, lc.tnode)) { return true; };
|
||||
};
|
||||
// F7-c1: the local read collapses onto the checker-stamped
|
||||
// n.type_, the same shape cstage's node_isstr uses (cmd/w6c/
|
||||
// cgen.c:213 type_isstr(n->type)). typeisstr chases TY_NAMED so
|
||||
// `!str` aliases (parserr = !str) and `type foo = str;` chains
|
||||
// resolve through exactly as isstrtype(lc.tnode) did — n.type_
|
||||
// and lc.tnode.type_ are the same tinfo for a local ident
|
||||
// (exprtype N_IDENT stamps n.type_ off the same decl
|
||||
// localfindnode keys on). The localfindnode gate stays to keep
|
||||
// the global-var-not-def case routing to false (out of F7
|
||||
// scope), so this is a zero-delta mechanic validation.
|
||||
if (lc != nil) { return typeisstr(n.type_: *tinfo); };
|
||||
// #21: a module-level `def s: str` ident is not a frame slot
|
||||
// (localfindnode→nil), so the local arm above misses it and
|
||||
// it would fall to the scalar single-PUSHQ default, dropping
|
||||
|
||||
@@ -18521,7 +18521,15 @@ fn nodeisslice(c: *cgen, n: *node) bool = {
|
||||
if (k == nkind.N_IDENT) {
|
||||
let nm: str = n.str;
|
||||
let lc: *local = localfindnode(c, nm);
|
||||
if (lc != nil) { return isslicetype(c, lc.tnode); };
|
||||
// F7-c1: the local read collapses onto the checker-stamped
|
||||
// n.type_, the same shape cstage's node_isslice uses
|
||||
// (cmd/w6c/cgen.c:182 type_isslice(n->type)). lc.tnode.type_
|
||||
// (what isslicetype read) and n.type_ are the same tinfo for a
|
||||
// local ident (exprtype N_IDENT stamps n.type_ off the same
|
||||
// decl localfindnode keys on); the localfindnode gate stays to
|
||||
// keep the global-var-not-def case routing to false (out of F7
|
||||
// scope), so this is a zero-delta mechanic validation.
|
||||
if (lc != nil) { return typeisslice(n.type_: *tinfo); };
|
||||
// #21: a module-level `def g: []T` ident is not a frame
|
||||
// slot (localfindnode→nil), so the local arm above misses
|
||||
// it and it would fall to the scalar single-PUSHQ default,
|
||||
@@ -18605,13 +18613,17 @@ fn nodeisstr(c: *cgen, n: *node) bool = {
|
||||
if (k == nkind.N_IDENT) {
|
||||
let nm: str = n.str;
|
||||
let lc: *local = localfindnode(c, nm);
|
||||
if (lc != nil) {
|
||||
// Use isstrtype so `!str` aliases (parserr = !str) and
|
||||
// `type foo = str;` chains resolve through. The bare
|
||||
// `streq("str", ...)` test missed them and dropped the
|
||||
// MOVQ BX,CX shuffle on returns of str-aliased locals.
|
||||
if (isstrtype(c, lc.tnode)) { return true; };
|
||||
};
|
||||
// F7-c1: the local read collapses onto the checker-stamped
|
||||
// n.type_, the same shape cstage's node_isstr uses (cmd/w6c/
|
||||
// cgen.c:213 type_isstr(n->type)). typeisstr chases TY_NAMED so
|
||||
// `!str` aliases (parserr = !str) and `type foo = str;` chains
|
||||
// resolve through exactly as isstrtype(lc.tnode) did — n.type_
|
||||
// and lc.tnode.type_ are the same tinfo for a local ident
|
||||
// (exprtype N_IDENT stamps n.type_ off the same decl
|
||||
// localfindnode keys on). The localfindnode gate stays to keep
|
||||
// the global-var-not-def case routing to false (out of F7
|
||||
// scope), so this is a zero-delta mechanic validation.
|
||||
if (lc != nil) { return typeisstr(n.type_: *tinfo); };
|
||||
// #21: a module-level `def s: str` ident is not a frame slot
|
||||
// (localfindnode→nil), so the local arm above misses it and
|
||||
// it would fall to the scalar single-PUSHQ default, dropping
|
||||
|
||||
Reference in New Issue
Block a user