@@ -21,6 +21,16 @@ use super::{
2121use super :: layout:: { align_to, resolve_struct_layout, type_layout_for_abi} ;
2222use super :: sig_to_clif;
2323
24+ #[ derive( Copy , Clone , Debug ) ]
25+ struct ResultStringSlots {
26+ slot_ptr : ir:: StackSlot ,
27+ slot_len : ir:: StackSlot ,
28+ slot_err : ir:: StackSlot ,
29+ ptr_align : u32 ,
30+ len_align : u32 ,
31+ err_align : u32 ,
32+ }
33+
2434
2535/// Emit a single HIR statement.
2636pub ( super ) fn emit_hir_stmt (
@@ -607,39 +617,15 @@ fn emit_hir_expr_inner(
607617 }
608618
609619 // Handle result out-parameters (same logic as AST version)
610- let mut out_slots = None ;
620+ let mut out_slots: Option < ResultStringSlots > = None ;
611621 let mut result_out = None ;
612622 let abi_sig = info. abi_sig . as_ref ( ) . unwrap_or ( & info. sig ) ;
613623
614624 if abi_sig. ret == AbiType :: ResultString {
615625 let ptr_ty = module. isa ( ) . pointer_type ( ) ;
616- let ptr_align = ptr_ty. bytes ( ) as u32 ;
617- let len_bytes = result_string_len_bytes ( ) ;
618- let len_align = len_bytes;
619- let err_align = 4u32 ;
620-
621- let slot_ptr = builder. create_sized_stack_slot ( ir:: StackSlotData :: new (
622- ir:: StackSlotKind :: ExplicitSlot ,
623- aligned_slot_size ( ptr_ty. bytes ( ) as u32 , ptr_align) ,
624- ) ) ;
625- let slot_len = builder. create_sized_stack_slot ( ir:: StackSlotData :: new (
626- ir:: StackSlotKind :: ExplicitSlot ,
627- aligned_slot_size ( len_bytes, len_align) ,
628- ) ) ;
629- let slot_err = builder. create_sized_stack_slot ( ir:: StackSlotData :: new (
630- ir:: StackSlotKind :: ExplicitSlot ,
631- aligned_slot_size ( 4 , err_align) ,
632- ) ) ;
633-
634- let ptr_ptr = aligned_stack_addr ( builder, slot_ptr, ptr_align, ptr_ty) ;
635- let len_ptr = aligned_stack_addr ( builder, slot_len, len_align, ptr_ty) ;
636- let err_ptr = aligned_stack_addr ( builder, slot_err, err_align, ptr_ty) ;
637-
638- args. push ( ptr_ptr) ;
639- args. push ( len_ptr) ;
640- args. push ( err_ptr) ;
641-
642- out_slots = Some ( ( slot_ptr, slot_len, slot_err) ) ;
626+ let slots = result_string_slots ( builder, ptr_ty) ;
627+ push_result_string_out_params ( builder, ptr_ty, & slots, & mut args) ;
628+ out_slots = Some ( slots) ;
643629 }
644630
645631 if let AbiType :: ResultOut ( ok_ty, err_ty) = & abi_sig. ret {
@@ -698,25 +684,10 @@ fn emit_hir_expr_inner(
698684 let tag = results
699685 . get ( 0 )
700686 . ok_or_else ( || CodegenError :: Codegen ( "missing result tag" . to_string ( ) ) ) ?;
701- let ( slot_ptr , slot_len , slot_err ) =
687+ let slots =
702688 out_slots. ok_or_else ( || CodegenError :: Codegen ( "missing slots" . to_string ( ) ) ) ?;
703689 let ptr_ty = module. isa ( ) . pointer_type ( ) ;
704- let ptr_align = ptr_ty. bytes ( ) as u32 ;
705- let len_align = result_string_len_bytes ( ) ;
706- let err_align = 4u32 ;
707- let ptr_addr = aligned_stack_addr ( builder, slot_ptr, ptr_align, ptr_ty) ;
708- let len_addr = aligned_stack_addr ( builder, slot_len, len_align, ptr_ty) ;
709- let err_addr = aligned_stack_addr ( builder, slot_err, err_align, ptr_ty) ;
710- let ptr =
711- builder
712- . ins ( )
713- . load ( module. isa ( ) . pointer_type ( ) , MemFlags :: new ( ) , ptr_addr, 0 ) ;
714- let len = builder
715- . ins ( )
716- . load ( ir:: types:: I64 , MemFlags :: new ( ) , len_addr, 0 ) ;
717- let err = builder
718- . ins ( )
719- . load ( ir:: types:: I32 , MemFlags :: new ( ) , err_addr, 0 ) ;
690+ let ( ptr, len, err) = read_result_string_slots ( builder, ptr_ty, & slots) ;
720691 match & info. sig . ret {
721692 AbiType :: Result ( ok_ty, err_ty) => {
722693 if * * ok_ty != AbiType :: String || * * err_ty != AbiType :: I32 {
@@ -1495,6 +1466,65 @@ fn result_string_len_bytes() -> u32 {
14951466 8
14961467}
14971468
1469+ fn result_string_slots ( builder : & mut FunctionBuilder , ptr_ty : Type ) -> ResultStringSlots {
1470+ let ptr_align = ptr_ty. bytes ( ) as u32 ;
1471+ let len_bytes = result_string_len_bytes ( ) ;
1472+ let len_align = len_bytes;
1473+ let err_align = 4u32 ;
1474+ let slot_ptr = builder. create_sized_stack_slot ( ir:: StackSlotData :: new (
1475+ ir:: StackSlotKind :: ExplicitSlot ,
1476+ aligned_slot_size ( ptr_ty. bytes ( ) as u32 , ptr_align) ,
1477+ ) ) ;
1478+ let slot_len = builder. create_sized_stack_slot ( ir:: StackSlotData :: new (
1479+ ir:: StackSlotKind :: ExplicitSlot ,
1480+ aligned_slot_size ( len_bytes, len_align) ,
1481+ ) ) ;
1482+ let slot_err = builder. create_sized_stack_slot ( ir:: StackSlotData :: new (
1483+ ir:: StackSlotKind :: ExplicitSlot ,
1484+ aligned_slot_size ( 4 , err_align) ,
1485+ ) ) ;
1486+ ResultStringSlots {
1487+ slot_ptr,
1488+ slot_len,
1489+ slot_err,
1490+ ptr_align,
1491+ len_align,
1492+ err_align,
1493+ }
1494+ }
1495+
1496+ fn push_result_string_out_params (
1497+ builder : & mut FunctionBuilder ,
1498+ ptr_ty : Type ,
1499+ slots : & ResultStringSlots ,
1500+ args : & mut Vec < Value > ,
1501+ ) {
1502+ let ptr_ptr = aligned_stack_addr ( builder, slots. slot_ptr , slots. ptr_align , ptr_ty) ;
1503+ let len_ptr = aligned_stack_addr ( builder, slots. slot_len , slots. len_align , ptr_ty) ;
1504+ let err_ptr = aligned_stack_addr ( builder, slots. slot_err , slots. err_align , ptr_ty) ;
1505+ args. push ( ptr_ptr) ;
1506+ args. push ( len_ptr) ;
1507+ args. push ( err_ptr) ;
1508+ }
1509+
1510+ fn read_result_string_slots (
1511+ builder : & mut FunctionBuilder ,
1512+ ptr_ty : Type ,
1513+ slots : & ResultStringSlots ,
1514+ ) -> ( Value , Value , Value ) {
1515+ let ptr_addr = aligned_stack_addr ( builder, slots. slot_ptr , slots. ptr_align , ptr_ty) ;
1516+ let len_addr = aligned_stack_addr ( builder, slots. slot_len , slots. len_align , ptr_ty) ;
1517+ let err_addr = aligned_stack_addr ( builder, slots. slot_err , slots. err_align , ptr_ty) ;
1518+ let ptr = builder. ins ( ) . load ( ptr_ty, MemFlags :: new ( ) , ptr_addr, 0 ) ;
1519+ let len = builder
1520+ . ins ( )
1521+ . load ( ir:: types:: I64 , MemFlags :: new ( ) , len_addr, 0 ) ;
1522+ let err = builder
1523+ . ins ( )
1524+ . load ( ir:: types:: I32 , MemFlags :: new ( ) , err_addr, 0 ) ;
1525+ ( ptr, len, err)
1526+ }
1527+
14981528/// Compute pointer/len offsets for the string layout.
14991529fn string_offsets ( ptr_ty : Type ) -> ( u32 , u32 ) {
15001530 let ptr_size = ptr_ty. bytes ( ) as u32 ;
@@ -2293,37 +2323,14 @@ pub(super) fn emit_runtime_wrapper_call(
22932323) -> Result < ValueRepr , CodegenError > {
22942324 ensure_abi_sig_handled ( info) ?;
22952325 let abi_sig = info. abi_sig . as_ref ( ) . unwrap_or ( & info. sig ) ;
2296- let mut out_slots = None ;
2326+ let mut out_slots: Option < ResultStringSlots > = None ;
22972327 let mut result_out = None ;
22982328
22992329 if abi_sig. ret == AbiType :: ResultString {
23002330 let ptr_ty = module. isa ( ) . pointer_type ( ) ;
2301- let ptr_align = ptr_ty. bytes ( ) as u32 ;
2302- let len_bytes = result_string_len_bytes ( ) ;
2303- let len_align = len_bytes;
2304- let err_align = 4u32 ;
2305- let slot_ptr = builder. create_sized_stack_slot ( ir:: StackSlotData :: new (
2306- ir:: StackSlotKind :: ExplicitSlot ,
2307- aligned_slot_size ( ptr_ty. bytes ( ) , ptr_align) ,
2308- ) ) ;
2309- let slot_len = builder. create_sized_stack_slot ( ir:: StackSlotData :: new (
2310- ir:: StackSlotKind :: ExplicitSlot ,
2311- aligned_slot_size ( len_bytes, len_align) ,
2312- ) ) ;
2313- let slot_err = builder. create_sized_stack_slot ( ir:: StackSlotData :: new (
2314- ir:: StackSlotKind :: ExplicitSlot ,
2315- aligned_slot_size ( 4 , err_align) ,
2316- ) ) ;
2317-
2318- let ptr_ptr = aligned_stack_addr ( builder, slot_ptr, ptr_align, ptr_ty) ;
2319- let len_ptr = aligned_stack_addr ( builder, slot_len, len_align, ptr_ty) ;
2320- let err_ptr = aligned_stack_addr ( builder, slot_err, err_align, ptr_ty) ;
2321-
2322- args. push ( ptr_ptr) ;
2323- args. push ( len_ptr) ;
2324- args. push ( err_ptr) ;
2325-
2326- out_slots = Some ( ( slot_ptr, slot_len, slot_err) ) ;
2331+ let slots = result_string_slots ( builder, ptr_ty) ;
2332+ push_result_string_out_params ( builder, ptr_ty, & slots, & mut args) ;
2333+ out_slots = Some ( slots) ;
23272334 }
23282335
23292336 if let AbiType :: ResultOut ( ok_ty, err_ty) = & abi_sig. ret {
@@ -2375,24 +2382,9 @@ pub(super) fn emit_runtime_wrapper_call(
23752382 let tag = results
23762383 . get ( 0 )
23772384 . ok_or_else ( || CodegenError :: Codegen ( "missing result tag" . to_string ( ) ) ) ?;
2378- let ( slot_ptr, slot_len, slot_err) =
2379- out_slots. ok_or_else ( || CodegenError :: Codegen ( "missing slots" . to_string ( ) ) ) ?;
2385+ let slots = out_slots. ok_or_else ( || CodegenError :: Codegen ( "missing slots" . to_string ( ) ) ) ?;
23802386 let ptr_ty = module. isa ( ) . pointer_type ( ) ;
2381- let ptr_align = ptr_ty. bytes ( ) as u32 ;
2382- let len_align = result_string_len_bytes ( ) ;
2383- let err_align = 4u32 ;
2384- let ptr_addr = aligned_stack_addr ( builder, slot_ptr, ptr_align, ptr_ty) ;
2385- let len_addr = aligned_stack_addr ( builder, slot_len, len_align, ptr_ty) ;
2386- let err_addr = aligned_stack_addr ( builder, slot_err, err_align, ptr_ty) ;
2387- let ptr = builder
2388- . ins ( )
2389- . load ( module. isa ( ) . pointer_type ( ) , MemFlags :: new ( ) , ptr_addr, 0 ) ;
2390- let len = builder
2391- . ins ( )
2392- . load ( ir:: types:: I64 , MemFlags :: new ( ) , len_addr, 0 ) ;
2393- let err = builder
2394- . ins ( )
2395- . load ( ir:: types:: I32 , MemFlags :: new ( ) , err_addr, 0 ) ;
2387+ let ( ptr, len, err) = read_result_string_slots ( builder, ptr_ty, & slots) ;
23962388 match & info. sig . ret {
23972389 AbiType :: Result ( ok_ty, err_ty) => {
23982390 if * * ok_ty != AbiType :: String || * * err_ty != AbiType :: I32 {
0 commit comments