MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / br

Method br

winch/codegen/src/codegen/context.rs:666–759  ·  view source on GitHub ↗

Prepares the compiler to branch to the given destination frame. This process involves: Balancing the machine stack pointer and value stack by popping it to match the destination branch. Updating the reachability state. Marking the destination frame as a destination target.

(
        &mut self,
        dest: &mut ControlStackFrame,
        masm: &mut M,
        mut maybe_pop_results: F,
    )

Source from the content-addressed store, hash-verified

664 /// * Updating the reachability state.
665 /// * Marking the destination frame as a destination target.
666 pub fn br<M, F, B>(
667 &mut self,
668 dest: &mut ControlStackFrame,
669 masm: &mut M,
670 mut maybe_pop_results: F,
671 ) -> Result<()>
672 where
673 M: MacroAssembler,
674 F: FnMut(&mut M, &mut Self, &mut ControlStackFrame) -> Result<()>,
675 B: BranchState,
676 {
677 let state = dest.stack_state();
678 let target_offset = state.target_offset;
679 let base_offset = state.base_offset;
680 let results_size = dest.results::<M>()?.size();
681
682 maybe_pop_results(masm, self, dest)?;
683 // After calling `maybe_pop_results`, the stack pointer plus
684 // any result space needed, must be greater or equal to the
685 // destination frame base stack pointer offset.
686 //
687 // We check
688 // current_sp + results >= base_offset
689 // as opposed to
690 // current_sp >= base_offset
691 //
692 // To:
693 // - Verify that `maybe_pop_results` popped exactly the right
694 // amount relative to the base offset.
695 // - Accommodate for multi-branch cases (i.e., `br_table`) in which
696 // result handling happens only once and _could_ happen outside of
697 // `maybe_pop_results` callback.
698 //
699 //
700 // Ensuring that the current stack pointer offset plus any
701 // result space is equal to or greater than the target branch
702 // base offset is the the most deterministic check at branch
703 // emission time since we can be certain that the base offset
704 // is the value recorded when a new control frame was pushed,
705 // upon which the expected target offset is calculated.
706 ensure!(
707 (masm.sp_offset()?.as_u32() + results_size) >= base_offset.as_u32(),
708 CodeGenError::invalid_sp_offset()
709 );
710
711 // At jump sites, the machine stack might be left unbalanced,
712 // due to register spills.
713 // The following snippet, pops the stack pointer to ensure
714 // that it is correctly placed according to the expectations
715 // of the destination branch.
716 //
717 // Note that in most branch cases (`return`, ` br`) the stack
718 // pointer will be already balanced, by virtue of calling
719 // [`ControlStackFrame::pop_abi_results`] through the
720 // callback.
721 //
722 // More generally speaking the current stack pointer will be
723 // less than the destination frame stack pointer offset in

Callers

nothing calls this directly

Calls 9

OkFunction · 0.85
stack_stateMethod · 0.80
memmoveMethod · 0.80
ensure_sp_for_jumpMethod · 0.80
set_as_targetMethod · 0.80
labelMethod · 0.80
sizeMethod · 0.45
sp_offsetMethod · 0.45
jmpMethod · 0.45

Tested by

no test coverage detected