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:
+28
-1
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user