Emit the usual function end instruction sequence.
(&mut self)
| 505 | |
| 506 | /// Emit the usual function end instruction sequence. |
| 507 | fn emit_end(&mut self) -> Result<()> { |
| 508 | // The implicit body block is treated a normal block (it pushes results |
| 509 | // to the stack); so when reaching the end, we pop them taking as |
| 510 | // reference the current function's signature. |
| 511 | let base = SPOffset::from_u32(self.context.frame.locals_size); |
| 512 | self.masm.start_source_loc(Default::default())?; |
| 513 | if self.context.reachable { |
| 514 | ControlStackFrame::pop_abi_results_impl( |
| 515 | &mut self.sig.results, |
| 516 | &mut self.context, |
| 517 | self.masm, |
| 518 | |results, _, _| Ok(results.ret_area().copied()), |
| 519 | )?; |
| 520 | } else { |
| 521 | // If we reach the end of the function in an unreachable code state, |
| 522 | // simply truncate to the expected values. |
| 523 | // The compiler could enter this state through an infinite loop. |
| 524 | self.context.truncate_stack_to(0)?; |
| 525 | self.masm.reset_stack_pointer(base)?; |
| 526 | } |
| 527 | ensure!( |
| 528 | self.context.stack.len() == 0, |
| 529 | CodeGenError::unexpected_value_in_value_stack() |
| 530 | ); |
| 531 | self.masm.free_stack(self.context.frame.locals_size)?; |
| 532 | self.masm.epilogue()?; |
| 533 | self.masm.end_source_loc()?; |
| 534 | Ok(()) |
| 535 | } |
| 536 | |
| 537 | /// Pops the value at the stack top and assigns it to the local at |
| 538 | /// the given index, returning the typed register holding the |
no test coverage detected