Code generation prologue.
(mut self)
| 148 | |
| 149 | /// Code generation prologue. |
| 150 | pub fn emit_prologue(mut self) -> Result<CodeGen<'a, 'translation, 'data, M, Emission>> { |
| 151 | let vmctx = self |
| 152 | .sig |
| 153 | .params() |
| 154 | .first() |
| 155 | .ok_or_else(|| format_err!(CodeGenError::vmcontext_arg_expected()))? |
| 156 | .unwrap_reg(); |
| 157 | |
| 158 | self.masm.start_source_loc(Default::default())?; |
| 159 | // We need to use the vmctx parameter before pinning it for stack checking. |
| 160 | self.masm.prologue(vmctx)?; |
| 161 | |
| 162 | // Pin the `VMContext` pointer. |
| 163 | self.masm.mov( |
| 164 | writable!(vmctx!(M)), |
| 165 | vmctx.into(), |
| 166 | self.env.ptr_type().try_into()?, |
| 167 | )?; |
| 168 | |
| 169 | self.masm.reserve_stack(self.context.frame.locals_size)?; |
| 170 | self.spill_register_arguments()?; |
| 171 | |
| 172 | let defined_locals_range = &self.context.frame.defined_locals_range; |
| 173 | self.masm.zero_mem_range(defined_locals_range.as_range())?; |
| 174 | |
| 175 | // Save the results base parameter register into its slot. |
| 176 | |
| 177 | if self.sig.params.has_retptr() { |
| 178 | match self.sig.params.unwrap_results_area_operand() { |
| 179 | ABIOperand::Reg { ty, reg, .. } => { |
| 180 | let results_base_slot = self.context.frame.results_base_slot.as_ref().unwrap(); |
| 181 | ensure!( |
| 182 | results_base_slot.addressed_from_sp(), |
| 183 | CodeGenError::sp_addressing_expected(), |
| 184 | ); |
| 185 | let addr = self.masm.local_address(results_base_slot)?; |
| 186 | self.masm.store((*reg).into(), addr, (*ty).try_into()?)?; |
| 187 | } |
| 188 | // The result base parameter is a stack parameter, addressed |
| 189 | // from FP. |
| 190 | _ => {} |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | self.masm.end_source_loc()?; |
| 195 | |
| 196 | Ok(CodeGen { |
| 197 | sig: self.sig, |
| 198 | context: self.context.for_emission(), |
| 199 | masm: self.masm, |
| 200 | env: self.env, |
| 201 | tunables: self.tunables, |
| 202 | source_location: self.source_location, |
| 203 | control_frames: self.control_frames, |
| 204 | fuel_consumed: self.fuel_consumed, |
| 205 | phase: PhantomData, |
| 206 | }) |
| 207 | } |
no test coverage detected