Performs the initial part of [`Vm::call`] in setting up the `args` provided in registers according to Pulley's ABI. # Return Returns the old `lr` register value. The current `lr` value is replaced with a sentinel that triggers a return to the host when returned-to. # Unsafety All the same unsafety as `call` and additionally, you must invoke `call_run` and then `call_end` after calling `call_st
(&'a mut self, args: &[Val])
| 103 | /// If you don't want to wrangle these invocations, use `call` instead |
| 104 | /// of `call_{start,run,end}`. |
| 105 | pub unsafe fn call_start<'a>(&'a mut self, args: &[Val]) -> *mut u8 { |
| 106 | // NB: make sure this method stays in sync with |
| 107 | // `PulleyMachineDeps::compute_arg_locs`! |
| 108 | |
| 109 | let mut x_args = (0..15).map(|x| unsafe { XReg::new_unchecked(x) }); |
| 110 | let mut f_args = (0..16).map(|f| unsafe { FReg::new_unchecked(f) }); |
| 111 | #[cfg(not(pulley_disable_interp_simd))] |
| 112 | let mut v_args = (0..16).map(|v| unsafe { VReg::new_unchecked(v) }); |
| 113 | |
| 114 | for arg in args { |
| 115 | match arg { |
| 116 | Val::XReg(val) => match x_args.next() { |
| 117 | Some(reg) => self.state[reg] = *val, |
| 118 | None => todo!("stack slots"), |
| 119 | }, |
| 120 | Val::FReg(val) => match f_args.next() { |
| 121 | Some(reg) => self.state[reg] = *val, |
| 122 | None => todo!("stack slots"), |
| 123 | }, |
| 124 | #[cfg(not(pulley_disable_interp_simd))] |
| 125 | Val::VReg(val) => match v_args.next() { |
| 126 | Some(reg) => self.state[reg] = *val, |
| 127 | None => todo!("stack slots"), |
| 128 | }, |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | mem::replace(&mut self.state.lr, HOST_RETURN_ADDR) |
| 133 | } |
| 134 | |
| 135 | /// Performs the internal part of [`Vm::call`] where bytecode is actually |
| 136 | /// executed. |