@@ -471,7 +471,7 @@ impl IrBuilder {
471471 if branch_incoming. is_empty ( ) {
472472 self . dead_code = true ;
473473 } else {
474- self . insert_phis_at_join ( end_block, & branch_incoming) ;
474+ self . insert_phis_at_join ( end_block, & branch_incoming) ? ;
475475 }
476476 }
477477
@@ -495,7 +495,7 @@ impl IrBuilder {
495495 preds. push ( ( then_block, then_locals) ) ;
496496 }
497497 self . push_predecessor_if_live ( & mut preds) ;
498- preds. extend ( branch_incoming. iter ( ) . cloned ( ) ) ;
498+ preds. extend ( branch_incoming. clone ( ) ) ;
499499
500500 // Assign result if needed (else-branch fall-through)
501501 if let Some ( result_var) = rv {
@@ -516,7 +516,7 @@ impl IrBuilder {
516516 if preds. is_empty ( ) {
517517 self . dead_code = true ;
518518 } else {
519- self . insert_phis_at_join ( end_block, & preds) ;
519+ self . insert_phis_at_join ( end_block, & preds) ? ;
520520 }
521521 }
522522
@@ -553,7 +553,7 @@ impl IrBuilder {
553553 if branch_incoming. is_empty ( ) {
554554 self . dead_code = true ;
555555 } else {
556- self . insert_phis_at_join ( end_block, & branch_incoming) ;
556+ self . insert_phis_at_join ( end_block, & branch_incoming) ? ;
557557 }
558558 }
559559
@@ -588,7 +588,7 @@ impl IrBuilder {
588588 if branch_incoming. is_empty ( ) {
589589 self . dead_code = true ;
590590 } else {
591- self . insert_phis_at_join ( end_block, & branch_incoming) ;
591+ self . insert_phis_at_join ( end_block, & branch_incoming) ? ;
592592 }
593593 }
594594 }
@@ -980,22 +980,7 @@ impl IrBuilder {
980980 // Before terminating the block we snapshot `local_vars` and record it
981981 // as a phi predecessor for the target frame. This snapshot is used by
982982 // `insert_phis_at_join` (or `emit_loop_phis`) to build the phi sources.
983- let depth = * relative_depth as usize ;
984- let frame_idx =
985- self . control_stack
986- . len ( )
987- . checked_sub ( depth + 1 )
988- . ok_or_else ( || {
989- anyhow:: anyhow!( "br: depth {} exceeds control stack" , relative_depth)
990- } ) ?;
991-
992- let ( target, is_loop) = {
993- let frame = & self . control_stack [ frame_idx] ;
994- match frame {
995- super :: core:: ControlFrame :: Loop { start_block, .. } => ( * start_block, true ) ,
996- _ => ( frame. end_block ( ) , false ) ,
997- }
998- } ;
983+ let ( target, is_loop, frame_idx) = self . resolve_branch_info ( * relative_depth) ?;
999984
1000985 // Record snapshot *before* terminating so local_vars is still valid.
1001986 if is_loop {
@@ -1035,22 +1020,7 @@ impl IrBuilder {
10351020 . ok_or_else ( || anyhow:: anyhow!( "Stack underflow for br_if" ) ) ?
10361021 . var_id ( ) ;
10371022
1038- let depth = * relative_depth as usize ;
1039- let frame_idx =
1040- self . control_stack
1041- . len ( )
1042- . checked_sub ( depth + 1 )
1043- . ok_or_else ( || {
1044- anyhow:: anyhow!( "br_if: depth {} exceeds control stack" , relative_depth)
1045- } ) ?;
1046-
1047- let ( target, is_loop) = {
1048- let frame = & self . control_stack [ frame_idx] ;
1049- match frame {
1050- super :: core:: ControlFrame :: Loop { start_block, .. } => ( * start_block, true ) ,
1051- _ => ( frame. end_block ( ) , false ) ,
1052- }
1053- } ;
1023+ let ( target, is_loop, frame_idx) = self . resolve_branch_info ( * relative_depth) ?;
10541024
10551025 // Record the taken branch as a phi predecessor (snapshot before termination).
10561026 if is_loop {
@@ -1091,18 +1061,17 @@ impl IrBuilder {
10911061 let target_depths: Vec < u32 > = targets. targets ( ) . collect :: < Result < Vec < _ > , _ > > ( ) ?;
10921062 let default_depth = targets. default ( ) ;
10931063
1094- let stack_len = self . control_stack . len ( ) ;
1064+ // Collect all branch targets and record phi predecessors, deduplicating by frame_idx
1065+ // (multiple table entries may point to the same target frame).
10951066 let mut recorded: std:: collections:: HashSet < usize > =
10961067 std:: collections:: HashSet :: new ( ) ;
10971068 for depth in target_depths
10981069 . iter ( )
10991070 . copied ( )
11001071 . chain ( std:: iter:: once ( default_depth) )
11011072 {
1102- let depth = depth as usize ;
1103- let frame_idx = stack_len. saturating_sub ( depth + 1 ) ;
1073+ let ( _, is_loop, frame_idx) = self . resolve_branch_info ( depth) ?;
11041074 if recorded. insert ( frame_idx) {
1105- let is_loop = self . control_stack [ frame_idx] . is_loop ( ) ;
11061075 if is_loop {
11071076 self . record_loop_back_branch ( frame_idx) ;
11081077 } else {
0 commit comments