Binds the else branch label and converts `self` to [`ControlStackFrame::Else`].
(
&mut self,
masm: &mut M,
context: &mut CodeGenContext<Emission>,
)
| 506 | /// Binds the else branch label and converts `self` to |
| 507 | /// [`ControlStackFrame::Else`]. |
| 508 | pub fn bind_else<M: MacroAssembler>( |
| 509 | &mut self, |
| 510 | masm: &mut M, |
| 511 | context: &mut CodeGenContext<Emission>, |
| 512 | ) -> Result<()> { |
| 513 | use ControlStackFrame::*; |
| 514 | match self { |
| 515 | If { |
| 516 | cont, |
| 517 | sig, |
| 518 | stack_state, |
| 519 | exit, |
| 520 | .. |
| 521 | } => { |
| 522 | // Bind the else branch. |
| 523 | masm.bind(*cont)?; |
| 524 | |
| 525 | // Push the abi results to the value stack, so that they are |
| 526 | // used as params for the else branch. At the beginning of the |
| 527 | // if block, any params are preemptively resolved as results; |
| 528 | // when reaching the else all params are already materialized as |
| 529 | // stack results. As part of ensuring the right state when |
| 530 | // entering the else branch, the following snippet also soft |
| 531 | // resets the stack pointer so that it matches the expectations |
| 532 | // of the else branch: the stack pointer is expected to be at |
| 533 | // the base stack pointer, plus the params stack size in bytes. |
| 534 | let params_size = sig.params::<M>()?.size(); |
| 535 | context.push_abi_results::<M, _>(sig.params::<M>()?, masm, |params, _, _| { |
| 536 | params.ret_area().copied() |
| 537 | })?; |
| 538 | masm.reset_stack_pointer(SPOffset::from_u32( |
| 539 | stack_state.base_offset.as_u32() + params_size, |
| 540 | ))?; |
| 541 | |
| 542 | // Update the stack control frame with an else control frame. |
| 543 | *self = ControlStackFrame::Else { |
| 544 | exit: *exit, |
| 545 | stack_state: *stack_state, |
| 546 | reachable: context.reachable, |
| 547 | sig: sig.clone(), |
| 548 | }; |
| 549 | } |
| 550 | _ => bail!(CodeGenError::if_control_frame_expected()), |
| 551 | } |
| 552 | Ok(()) |
| 553 | } |
| 554 | |
| 555 | /// Handles the end of a control stack frame. |
| 556 | pub fn emit_end<M: MacroAssembler>( |