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

Method adjust_stack_results

winch/codegen/src/codegen/control.rs:836–964  ·  view source on GitHub ↗

If the results on the stack are handled via the stack pointer, ensure that the stack results are correctly located. In general, since values in the value stack are spilled when exiting the block, the top `n` entries in the value stack, representing the `n` stack results of the block are almost correctly located. However, since constants are not spilled, their presence complicate block exits. For t

(
        ret_area: RetArea,
        results: &ABIResults,
        context: &mut CodeGenContext<Emission>,
        masm: &mut M,
    )

Source from the content-addressed store, hash-verified

834 // SpiderMonkey's WebAssembly Baseline Compiler:
835 // https://wingolog.org/archives/2020/04/03/multi-value-webassembly-in-firefox-from-1-to-n
836 fn adjust_stack_results<M>(
837 ret_area: RetArea,
838 results: &ABIResults,
839 context: &mut CodeGenContext<Emission>,
840 masm: &mut M,
841 ) -> Result<()>
842 where
843 M: MacroAssembler,
844 {
845 ensure!(ret_area.is_sp(), CodeGenError::sp_addressing_expected());
846 let results_offset = ret_area.unwrap_sp();
847
848 // Start iterating from memory values that are closer to the
849 // frame pointer (oldest entries first).
850 for (i, operand) in results.operands().iter().enumerate() {
851 if operand.is_reg() {
852 break;
853 }
854
855 let value_index = (context.stack.len() - results.stack_operands_len()) + i;
856 let val = context.stack.inner()[value_index];
857
858 match (val, operand) {
859 (Val::Memory(mem), ABIOperand::Stack { offset, size, .. }) => {
860 let dst = results_offset.as_u32() - *offset;
861 let src = mem.slot.offset;
862
863 // Values are moved from lower (SP) to higher (FP)
864 // addresses.
865 if src.as_u32() <= dst {
866 break;
867 }
868
869 masm.memmove(
870 src,
871 SPOffset::from_u32(dst),
872 *size,
873 MemMoveDirection::LowToHigh,
874 )?;
875 }
876 _ => {}
877 }
878 }
879
880 // Start iterating from memory values that are closer to the
881 // stack pointer (newest entries first).
882 for (i, operand) in results
883 .operands()
884 .iter()
885 .rev()
886 // Skip any register results.
887 .skip(results.regs().len())
888 .enumerate()
889 {
890 let value_index = context.stack.len() - i - 1;
891 let val = context.stack.inner()[value_index];
892 match (val, operand) {
893 (Val::Memory(mem), ABIOperand::Stack { offset, size, .. }) => {

Callers

nothing calls this directly

Calls 15

i64Function · 0.85
v128Function · 0.85
OkFunction · 0.85
unwrap_spMethod · 0.80
stack_operands_lenMethod · 0.80
memmoveMethod · 0.80
iterMethod · 0.45
operandsMethod · 0.45
is_regMethod · 0.45
lenMethod · 0.45
innerMethod · 0.45
as_u32Method · 0.45

Tested by

no test coverage detected