@@ -594,6 +594,24 @@ impl CraneliftBackend {
594594 }
595595 }
596596
597+ // Pre-compute sizes for aggregate undef values (to avoid borrow checker issues later)
598+ let mut undef_aggregate_sizes: HashMap < HirId , u32 > = HashMap :: new ( ) ;
599+ for value in function. values . values ( ) {
600+ if let HirValueKind :: Undef = value. kind {
601+ match & value. ty {
602+ HirType :: Struct ( _) | HirType :: Array ( _, _) | HirType :: Union ( _) => {
603+ let alloc_size = self . type_size ( & value. ty ) . unwrap_or ( 8 ) as u32 ;
604+ let alloc_size = std:: cmp:: max ( alloc_size, 8 ) ; // At least 8 bytes
605+ undef_aggregate_sizes. insert ( value. id , alloc_size) ;
606+ }
607+ _ => { }
608+ }
609+ }
610+ }
611+
612+ // Pre-compute pointer type for use inside builder scope
613+ let pointer_type = self . module . target_config ( ) . pointer_type ( ) ;
614+
597615 // Phase 2: Create builder and all Cranelift blocks
598616 let mut builder = FunctionBuilder :: new (
599617 & mut self . codegen_context . func ,
@@ -702,31 +720,18 @@ impl CraneliftBackend {
702720 }
703721
704722 // Map undef values to zero constants (for IDF-based SSA)
705- // For struct types, allocate stack space instead of using a zero constant
723+ // For aggregate types (structs, arrays) , allocate stack space instead of using a zero constant
706724 for value in function. values . values ( ) {
707725 if let HirValueKind :: Undef = value. kind {
708- // Check if this is a struct type that needs stack allocation
709- if let HirType :: Struct ( struct_ty) = & value. ty {
710- // Allocate stack space for the struct
711- let struct_size = struct_ty. fields . iter ( )
712- . map ( |f| match f {
713- HirType :: I8 | HirType :: U8 | HirType :: Bool => 1 ,
714- HirType :: I16 | HirType :: U16 => 2 ,
715- HirType :: I32 | HirType :: U32 | HirType :: F32 => 4 ,
716- HirType :: I64 | HirType :: U64 | HirType :: F64 | HirType :: Ptr ( _) => 8 ,
717- HirType :: I128 | HirType :: U128 => 16 ,
718- _ => 8 , // Default
719- } )
720- . sum :: < usize > ( ) ;
721- let struct_size = std:: cmp:: max ( struct_size, 8 ) as u32 ; // At least 8 bytes
722-
726+ // Check if this is an aggregate type with pre-computed size
727+ if let Some ( & alloc_size) = undef_aggregate_sizes. get ( & value. id ) {
723728 let slot = builder. create_sized_stack_slot ( cranelift_codegen:: ir:: StackSlotData :: new (
724729 cranelift_codegen:: ir:: StackSlotKind :: ExplicitSlot ,
725- struct_size ,
730+ alloc_size ,
726731 ) ) ;
727- let ptr = builder. ins ( ) . stack_addr ( self . module . target_config ( ) . pointer_type ( ) , slot, 0 ) ;
732+ let ptr = builder. ins ( ) . stack_addr ( pointer_type, slot, 0 ) ;
728733 self . value_map . insert ( value. id , ptr) ;
729- eprintln ! ( "[CRANELIFT UNDEF] Allocated {} bytes stack for struct undef {:?}" , struct_size , value. id) ;
734+ eprintln ! ( "[CRANELIFT UNDEF] Allocated {} bytes stack for aggregate undef {:?}" , alloc_size , value. id) ;
730735 } else {
731736 // For scalar types, use zero constant
732737 let ty = type_cache. get ( & value. ty ) . copied ( ) . unwrap_or ( types:: I64 ) ;
0 commit comments