wcc/ww: try-unwrap str success reads the stamped operand type
The ?/! success-is-str decision was name-keyed off the FIRST variant and only handled call operands — an ident operand with junk registers unwrapped garbage, and error-first unions picked the wrong variant. Key on the stamped success variant (successvariant + typeisstr, mirror cgen.c:10459-10466/10595-10602). Review item #16.
This commit is contained in:
@@ -23738,42 +23738,13 @@ fn cgtryprop(c: *cgen, n: *node) void = {
|
||||
// the codegen expects the success value in AX (and BX for str).
|
||||
// AX=tag, DX=val0, CX=val1 from the call ABI. For str success,
|
||||
// shuffle (DX,CX) → (AX,BX); else move DX → AX.
|
||||
// #16: read the STAMPED operand's success-variant type (any source
|
||||
// shape, any variant order), not a name-keyed call-only lookup of
|
||||
// the first variant. Mirrors cstage cgen.c:10459-10466
|
||||
// (success_is_str = type_isstr(succ_t at cg_tagged_success_tag)).
|
||||
let succisstr: bool = false;
|
||||
if (n.lhs != nil) {
|
||||
if (n.lhs.kind == nkind.N_CALL) {
|
||||
let callee: *node = n.lhs.lhs;
|
||||
if (callee != nil) {
|
||||
let cname: str;
|
||||
cname.ptr = nil; cname.len = 0;
|
||||
let cmod: str;
|
||||
cmod.ptr = nil; cmod.len = 0;
|
||||
if (callee.kind == nkind.N_IDENT) {
|
||||
cname = callee.str;
|
||||
cmod = c.curmod;
|
||||
};
|
||||
if (callee.kind == nkind.N_DOT) {
|
||||
cname = callee.str;
|
||||
if (callee.lhs != nil) {
|
||||
if (callee.lhs.kind == nkind.N_IDENT) {
|
||||
cmod = callee.lhs.str;
|
||||
};
|
||||
};
|
||||
};
|
||||
if (cname.len > 0) {
|
||||
let rtyp: *node = fnretlookupmod(c, cname, cmod);
|
||||
if (rtyp != nil) {
|
||||
if (rtyp.kind == nkind.N_TTAGGED) {
|
||||
let first: *node = rtyp.list;
|
||||
if (first != nil) {
|
||||
if (isstrtype(c, first)) {
|
||||
succisstr = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
succisstr = typeisstr(successvariant(n.lhs.type_: *tinfo));
|
||||
};
|
||||
if (succisstr) {
|
||||
// str IS []u8: success arrives DX=ptr, CX=len, R8=cap
|
||||
@@ -23836,42 +23807,11 @@ fn cgtryunw(c: *cgen, n: *node) void = {
|
||||
if (cgtrytupleshift(c, n)) { return; };
|
||||
if (cgtrytaggedshift(c, n)) { return; };
|
||||
// Unwrap success value. (Same shuffle pattern as cgtryprop.)
|
||||
// #16: stamped success-variant type, any source/order (twin of
|
||||
// cgtryprop; cstage cgen.c:10595-10602).
|
||||
let succisstr: bool = false;
|
||||
if (n.lhs != nil) {
|
||||
if (n.lhs.kind == nkind.N_CALL) {
|
||||
let callee: *node = n.lhs.lhs;
|
||||
if (callee != nil) {
|
||||
let cname: str;
|
||||
cname.ptr = nil; cname.len = 0;
|
||||
let cmod: str;
|
||||
cmod.ptr = nil; cmod.len = 0;
|
||||
if (callee.kind == nkind.N_IDENT) {
|
||||
cname = callee.str;
|
||||
cmod = c.curmod;
|
||||
};
|
||||
if (callee.kind == nkind.N_DOT) {
|
||||
cname = callee.str;
|
||||
if (callee.lhs != nil) {
|
||||
if (callee.lhs.kind == nkind.N_IDENT) {
|
||||
cmod = callee.lhs.str;
|
||||
};
|
||||
};
|
||||
};
|
||||
if (cname.len > 0) {
|
||||
let rtyp: *node = fnretlookupmod(c, cname, cmod);
|
||||
if (rtyp != nil) {
|
||||
if (rtyp.kind == nkind.N_TTAGGED) {
|
||||
let first: *node = rtyp.list;
|
||||
if (first != nil) {
|
||||
if (isstrtype(c, first)) {
|
||||
succisstr = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
succisstr = typeisstr(successvariant(n.lhs.type_: *tinfo));
|
||||
};
|
||||
if (succisstr) {
|
||||
// str IS []u8: success arrives DX=ptr, CX=len, R8=cap
|
||||
|
||||
@@ -518,42 +518,13 @@ fn cgtryprop(c: *cgen, n: *node) void = {
|
||||
// the codegen expects the success value in AX (and BX for str).
|
||||
// AX=tag, DX=val0, CX=val1 from the call ABI. For str success,
|
||||
// shuffle (DX,CX) → (AX,BX); else move DX → AX.
|
||||
// #16: read the STAMPED operand's success-variant type (any source
|
||||
// shape, any variant order), not a name-keyed call-only lookup of
|
||||
// the first variant. Mirrors cstage cgen.c:10459-10466
|
||||
// (success_is_str = type_isstr(succ_t at cg_tagged_success_tag)).
|
||||
let succisstr: bool = false;
|
||||
if (n.lhs != nil) {
|
||||
if (n.lhs.kind == nkind.N_CALL) {
|
||||
let callee: *node = n.lhs.lhs;
|
||||
if (callee != nil) {
|
||||
let cname: str;
|
||||
cname.ptr = nil; cname.len = 0;
|
||||
let cmod: str;
|
||||
cmod.ptr = nil; cmod.len = 0;
|
||||
if (callee.kind == nkind.N_IDENT) {
|
||||
cname = callee.str;
|
||||
cmod = c.curmod;
|
||||
};
|
||||
if (callee.kind == nkind.N_DOT) {
|
||||
cname = callee.str;
|
||||
if (callee.lhs != nil) {
|
||||
if (callee.lhs.kind == nkind.N_IDENT) {
|
||||
cmod = callee.lhs.str;
|
||||
};
|
||||
};
|
||||
};
|
||||
if (cname.len > 0) {
|
||||
let rtyp: *node = fnretlookupmod(c, cname, cmod);
|
||||
if (rtyp != nil) {
|
||||
if (rtyp.kind == nkind.N_TTAGGED) {
|
||||
let first: *node = rtyp.list;
|
||||
if (first != nil) {
|
||||
if (isstrtype(c, first)) {
|
||||
succisstr = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
succisstr = typeisstr(successvariant(n.lhs.type_: *tinfo));
|
||||
};
|
||||
if (succisstr) {
|
||||
// str IS []u8: success arrives DX=ptr, CX=len, R8=cap
|
||||
@@ -616,42 +587,11 @@ fn cgtryunw(c: *cgen, n: *node) void = {
|
||||
if (cgtrytupleshift(c, n)) { return; };
|
||||
if (cgtrytaggedshift(c, n)) { return; };
|
||||
// Unwrap success value. (Same shuffle pattern as cgtryprop.)
|
||||
// #16: stamped success-variant type, any source/order (twin of
|
||||
// cgtryprop; cstage cgen.c:10595-10602).
|
||||
let succisstr: bool = false;
|
||||
if (n.lhs != nil) {
|
||||
if (n.lhs.kind == nkind.N_CALL) {
|
||||
let callee: *node = n.lhs.lhs;
|
||||
if (callee != nil) {
|
||||
let cname: str;
|
||||
cname.ptr = nil; cname.len = 0;
|
||||
let cmod: str;
|
||||
cmod.ptr = nil; cmod.len = 0;
|
||||
if (callee.kind == nkind.N_IDENT) {
|
||||
cname = callee.str;
|
||||
cmod = c.curmod;
|
||||
};
|
||||
if (callee.kind == nkind.N_DOT) {
|
||||
cname = callee.str;
|
||||
if (callee.lhs != nil) {
|
||||
if (callee.lhs.kind == nkind.N_IDENT) {
|
||||
cmod = callee.lhs.str;
|
||||
};
|
||||
};
|
||||
};
|
||||
if (cname.len > 0) {
|
||||
let rtyp: *node = fnretlookupmod(c, cname, cmod);
|
||||
if (rtyp != nil) {
|
||||
if (rtyp.kind == nkind.N_TTAGGED) {
|
||||
let first: *node = rtyp.list;
|
||||
if (first != nil) {
|
||||
if (isstrtype(c, first)) {
|
||||
succisstr = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
succisstr = typeisstr(successvariant(n.lhs.type_: *tinfo));
|
||||
};
|
||||
if (succisstr) {
|
||||
// str IS []u8: success arrives DX=ptr, CX=len, R8=cap
|
||||
|
||||
@@ -23738,42 +23738,13 @@ fn cgtryprop(c: *cgen, n: *node) void = {
|
||||
// the codegen expects the success value in AX (and BX for str).
|
||||
// AX=tag, DX=val0, CX=val1 from the call ABI. For str success,
|
||||
// shuffle (DX,CX) → (AX,BX); else move DX → AX.
|
||||
// #16: read the STAMPED operand's success-variant type (any source
|
||||
// shape, any variant order), not a name-keyed call-only lookup of
|
||||
// the first variant. Mirrors cstage cgen.c:10459-10466
|
||||
// (success_is_str = type_isstr(succ_t at cg_tagged_success_tag)).
|
||||
let succisstr: bool = false;
|
||||
if (n.lhs != nil) {
|
||||
if (n.lhs.kind == nkind.N_CALL) {
|
||||
let callee: *node = n.lhs.lhs;
|
||||
if (callee != nil) {
|
||||
let cname: str;
|
||||
cname.ptr = nil; cname.len = 0;
|
||||
let cmod: str;
|
||||
cmod.ptr = nil; cmod.len = 0;
|
||||
if (callee.kind == nkind.N_IDENT) {
|
||||
cname = callee.str;
|
||||
cmod = c.curmod;
|
||||
};
|
||||
if (callee.kind == nkind.N_DOT) {
|
||||
cname = callee.str;
|
||||
if (callee.lhs != nil) {
|
||||
if (callee.lhs.kind == nkind.N_IDENT) {
|
||||
cmod = callee.lhs.str;
|
||||
};
|
||||
};
|
||||
};
|
||||
if (cname.len > 0) {
|
||||
let rtyp: *node = fnretlookupmod(c, cname, cmod);
|
||||
if (rtyp != nil) {
|
||||
if (rtyp.kind == nkind.N_TTAGGED) {
|
||||
let first: *node = rtyp.list;
|
||||
if (first != nil) {
|
||||
if (isstrtype(c, first)) {
|
||||
succisstr = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
succisstr = typeisstr(successvariant(n.lhs.type_: *tinfo));
|
||||
};
|
||||
if (succisstr) {
|
||||
// str IS []u8: success arrives DX=ptr, CX=len, R8=cap
|
||||
@@ -23836,42 +23807,11 @@ fn cgtryunw(c: *cgen, n: *node) void = {
|
||||
if (cgtrytupleshift(c, n)) { return; };
|
||||
if (cgtrytaggedshift(c, n)) { return; };
|
||||
// Unwrap success value. (Same shuffle pattern as cgtryprop.)
|
||||
// #16: stamped success-variant type, any source/order (twin of
|
||||
// cgtryprop; cstage cgen.c:10595-10602).
|
||||
let succisstr: bool = false;
|
||||
if (n.lhs != nil) {
|
||||
if (n.lhs.kind == nkind.N_CALL) {
|
||||
let callee: *node = n.lhs.lhs;
|
||||
if (callee != nil) {
|
||||
let cname: str;
|
||||
cname.ptr = nil; cname.len = 0;
|
||||
let cmod: str;
|
||||
cmod.ptr = nil; cmod.len = 0;
|
||||
if (callee.kind == nkind.N_IDENT) {
|
||||
cname = callee.str;
|
||||
cmod = c.curmod;
|
||||
};
|
||||
if (callee.kind == nkind.N_DOT) {
|
||||
cname = callee.str;
|
||||
if (callee.lhs != nil) {
|
||||
if (callee.lhs.kind == nkind.N_IDENT) {
|
||||
cmod = callee.lhs.str;
|
||||
};
|
||||
};
|
||||
};
|
||||
if (cname.len > 0) {
|
||||
let rtyp: *node = fnretlookupmod(c, cname, cmod);
|
||||
if (rtyp != nil) {
|
||||
if (rtyp.kind == nkind.N_TTAGGED) {
|
||||
let first: *node = rtyp.list;
|
||||
if (first != nil) {
|
||||
if (isstrtype(c, first)) {
|
||||
succisstr = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
succisstr = typeisstr(successvariant(n.lhs.type_: *tinfo));
|
||||
};
|
||||
if (succisstr) {
|
||||
// str IS []u8: success arrives DX=ptr, CX=len, R8=cap
|
||||
|
||||
Reference in New Issue
Block a user