selfhost: nodeisstr chained-str through value-struct in call args (closes #30)

This commit is contained in:
2026-05-14 23:26:49 +09:00
parent a5919ed8da
commit 9706513e59
5 changed files with 247 additions and 0 deletions

View File

@@ -6063,6 +6063,26 @@ fn nodeisstr(c: *cgen, n: *node) bool = {
};
};
};
// Chained dot through value-struct hops (`p.inner.s`):
// dotinnerstructptr above only walks *struct fields, so
// a value-struct chain falls through and the call-arg
// path then pushes only 1 word for the str instead of
// 2 (ptr+len), silently dropping the len half.
// dotchainresolve handles arbitrary depth through value
// struct AND `*T` root, returning the leaf fieldinfo.
let rootnm: str = "";
let rootoff: i32 = 0;
let totaloff: i32 = 0;
let lfi: *fieldinfo = nil;
let sdelta: i32 = -1;
let isglobal: bool = false;
let ptrroot: bool = false;
let ok: bool = dotchainresolve(c, n,
&rootnm, &rootoff, &totaloff,
&lfi, &sdelta, &isglobal, &ptrroot);
if (ok && sdelta < 0 && lfi != nil) {
return isstrtype(c, lfi.tnode);
};
};
return false;
};

View File

@@ -493,6 +493,26 @@ fn nodeisstr(c: *cgen, n: *node) bool = {
};
};
};
// Chained dot through value-struct hops (`p.inner.s`):
// dotinnerstructptr above only walks *struct fields, so
// a value-struct chain falls through and the call-arg
// path then pushes only 1 word for the str instead of
// 2 (ptr+len), silently dropping the len half.
// dotchainresolve handles arbitrary depth through value
// struct AND `*T` root, returning the leaf fieldinfo.
let rootnm: str = "";
let rootoff: i32 = 0;
let totaloff: i32 = 0;
let lfi: *fieldinfo = nil;
let sdelta: i32 = -1;
let isglobal: bool = false;
let ptrroot: bool = false;
let ok: bool = dotchainresolve(c, n,
&rootnm, &rootoff, &totaloff,
&lfi, &sdelta, &isglobal, &ptrroot);
if (ok && sdelta < 0 && lfi != nil) {
return isstrtype(c, lfi.tnode);
};
};
return false;
};

View File

@@ -6063,6 +6063,26 @@ fn nodeisstr(c: *cgen, n: *node) bool = {
};
};
};
// Chained dot through value-struct hops (`p.inner.s`):
// dotinnerstructptr above only walks *struct fields, so
// a value-struct chain falls through and the call-arg
// path then pushes only 1 word for the str instead of
// 2 (ptr+len), silently dropping the len half.
// dotchainresolve handles arbitrary depth through value
// struct AND `*T` root, returning the leaf fieldinfo.
let rootnm: str = "";
let rootoff: i32 = 0;
let totaloff: i32 = 0;
let lfi: *fieldinfo = nil;
let sdelta: i32 = -1;
let isglobal: bool = false;
let ptrroot: bool = false;
let ok: bool = dotchainresolve(c, n,
&rootnm, &rootoff, &totaloff,
&lfi, &sdelta, &isglobal, &ptrroot);
if (ok && sdelta < 0 && lfi != nil) {
return isstrtype(c, lfi.tnode);
};
};
return false;
};