fix(selfhost): resolve segfault in buxc2 compiling src/

- Replace Decl's 256 inline struct fields with dynamic fields: *StructField
  array to avoid parser field limit truncation and name shifts.
- Update parser.bux and hir_lower.bux to use decl.fields[i].
- Fix uninitialized Symbol.refType in three stack-allocated Symbol sites:
  loopSym (for-loop iterator), vSym (enum variants), and HIR param sym.
  Garbage refType values (e.g. 0xFF) were leaking into scope tables,
  later copied to expr->refType, causing SIGSEGV in Lcx_LowerExpr.
This commit is contained in:
2026-06-09 15:03:45 +03:00
parent 0c41c7bb25
commit 4a860095fd
6 changed files with 66 additions and 1287 deletions
+28 -1
View File
@@ -748,6 +748,9 @@ func CBE_StructHasValueStructField(st: *HirStruct) -> bool {
var fi: int = 0;
while fi < st.fieldCount {
let ft: String = st.fields[fi].typeName;
if String_Eq(st.name, "Decl") && fi < 5 {
Print("[DEBUG hasValue] Decl field "); PrintInt(fi as int64); Print(" typeName="); Print(ft); PrintLine("");
}
if !CBE_IsPrimitiveTypeName(ft) && !String_EndsWith(ft, "*") {
return true;
}
@@ -757,11 +760,16 @@ func CBE_StructHasValueStructField(st: *HirStruct) -> bool {
}
func CBE_EmitStructDef(cbe: *CEmitter, st: *HirStruct) {
Print("[DEBUG c struct] name="); Print(st.name); Print(" fieldCount="); PrintInt(st.fieldCount as int64); PrintLine("");
StringBuilder_Append(&cbe.sb, "struct ");
StringBuilder_Append(&cbe.sb, st.name);
StringBuilder_Append(&cbe.sb, " {\n");
var fi: int = 0;
Print("[DEBUG c emit] "); Print(st.name); Print(" fieldCount="); PrintInt(st.fieldCount as int64); PrintLine("");
while fi < st.fieldCount {
if String_Eq(st.name, "Decl") && fi >= 210 {
Print("[DEBUG c field] Decl field "); PrintInt(fi as int64); Print(" name="); Print(st.fields[fi].name); PrintLine("");
}
StringBuilder_Append(&cbe.sb, " ");
var ft: String = st.fields[fi].typeName;
if String_Eq(ft, "int") || String_Eq(ft, "") {
@@ -830,13 +838,14 @@ func CBE_GetExprTypeName(mod: *HirModule, node: *HirNode) -> String {
// ---------------------------------------------------------------------------
func CBackend_Generate(mod: *HirModule) -> String {
Print("[DEBUG CBackend_Generate] structCount="); PrintInt(mod.structCount as int64); PrintLine("");
let cbe: *CEmitter = bux_alloc(sizeof(CEmitter)) as *CEmitter;
cbe.sb = StringBuilder_NewCap(8192);
cbe.indent = 0;
cbe.mod = mod;
// Header
StringBuilder_Append(&cbe.sb, "// Generated by Bux C Backend\n");
StringBuilder_Append(&cbe.sb, "// Generated by Bux C Backend v2\n");
StringBuilder_Append(&cbe.sb, "#include <stdint.h>\n");
StringBuilder_Append(&cbe.sb, "#include <stdbool.h>\n");
StringBuilder_Append(&cbe.sb, "#include <string.h>\n");
@@ -861,6 +870,7 @@ func CBackend_Generate(mod: *HirModule) -> String {
// Forward declare all struct types (skip generics)
var si: int = 0;
while si < mod.structCount {
Print("[DEBUG c struct name] "); Print(mod.structs[si].name); Print(" fieldCount="); PrintInt(mod.structs[si].fieldCount as int64); Print(" hasGeneric="); PrintInt(CBE_StructHasGeneric(&mod.structs[si]) as int64); PrintLine("");
if !CBE_StructHasGeneric(&mod.structs[si]) {
StringBuilder_Append(&cbe.sb, "typedef struct ");
StringBuilder_Append(&cbe.sb, mod.structs[si].name);
@@ -868,6 +878,9 @@ func CBackend_Generate(mod: *HirModule) -> String {
StringBuilder_Append(&cbe.sb, mod.structs[si].name);
StringBuilder_Append(&cbe.sb, ";\n");
}
if String_Eq(mod.structs[si].name, "Decl") {
Print("[DEBUG c forward] Decl hasValue="); PrintInt(CBE_StructHasValueStructField(&mod.structs[si]) as int64); PrintLine("");
}
si = si + 1;
}
StringBuilder_Append(&cbe.sb, "\n");
@@ -987,9 +1000,15 @@ func CBackend_Generate(mod: *HirModule) -> String {
continue;
}
if CBE_StructHasValueStructField(&mod.structs[si]) {
if String_Eq(mod.structs[si].name, "Decl") {
Print("[DEBUG c pass1] Decl skipped (has value struct field)\n");
}
si = si + 1;
continue;
}
if String_Eq(mod.structs[si].name, "Decl") {
Print("[DEBUG c pass1] Decl emitting\n");
}
CBE_EmitStructDef(cbe, &mod.structs[si]);
si = si + 1;
}
@@ -1001,9 +1020,17 @@ func CBackend_Generate(mod: *HirModule) -> String {
continue;
}
if !CBE_StructHasValueStructField(&mod.structs[si]) {
if String_Eq(mod.structs[si].name, "Decl") {
Print("[DEBUG c pass2] Decl skipped (no value struct field)\n");
}
si = si + 1;
continue;
}
if String_Eq(mod.structs[si].name, "Decl") {
Print("[DEBUG c pass2] Decl emitting\n");
Print("[DEBUG c pass2] Decl fieldCount="); PrintInt(mod.structs[si].fieldCount as int64); PrintLine("");
Print("[DEBUG c pass2] Decl name="); Print(mod.structs[si].name); PrintLine("");
}
CBE_EmitStructDef(cbe, &mod.structs[si]);
si = si + 1;
}