Emit the `memory.fill` operation.
(&mut self, mem: MemoryIndex)
| 1656 | |
| 1657 | /// Emit the `memory.fill` operation. |
| 1658 | pub fn emit_memory_fill(&mut self, mem: MemoryIndex) -> Result<()> { |
| 1659 | let heap = self.env.resolve_heap(mem); |
| 1660 | let ptr_size: OperandSize = self.env.ptr_type().try_into()?; |
| 1661 | let idx_size: OperandSize = heap.index_type().try_into()?; |
| 1662 | |
| 1663 | // The wasm stack at this point is `[dst, val, len]`. |
| 1664 | let len = self.context.pop_to_reg(self.masm, None)?; |
| 1665 | let val = self.context.pop_to_reg(self.masm, None)?; |
| 1666 | let dst = self.context.pop_to_reg(self.masm, None)?; |
| 1667 | |
| 1668 | let raw_addr = self.context.any_gpr(self.masm)?; |
| 1669 | self.emit_bounds_check_and_compute_addr(&heap, raw_addr, dst.reg, len.reg)?; |
| 1670 | self.context.free_reg(dst); |
| 1671 | |
| 1672 | // The libcall takes the length as a host-pointer-sized integer, so |
| 1673 | // zero-extend if the wasm index type is smaller. |
| 1674 | let len_reg = len.reg; |
| 1675 | if idx_size == OperandSize::S32 && ptr_size == OperandSize::S64 { |
| 1676 | self.masm.extend( |
| 1677 | writable!(len_reg), |
| 1678 | len_reg, |
| 1679 | Extend::<Zero>::I64Extend32.into(), |
| 1680 | )?; |
| 1681 | } |
| 1682 | |
| 1683 | // Set up the call arguments: `[dst_ptr, val, len]`. |
| 1684 | self.context |
| 1685 | .stack |
| 1686 | .push(TypedReg::new(self.env.ptr_type(), raw_addr).into()); |
| 1687 | self.context.stack.push(val.into()); |
| 1688 | self.context |
| 1689 | .stack |
| 1690 | .push(TypedReg::new(self.env.ptr_type(), len_reg).into()); |
| 1691 | |
| 1692 | let builtin = self.env.builtins.memory_fill::<M::ABI>()?; |
| 1693 | FnCall::emit::<M>( |
| 1694 | &mut self.env, |
| 1695 | self.masm, |
| 1696 | &mut self.context, |
| 1697 | Callee::Builtin(builtin), |
| 1698 | )?; |
| 1699 | Ok(()) |
| 1700 | } |
| 1701 | |
| 1702 | /// Emit the `memory.init` operation. |
| 1703 | pub fn emit_memory_init(&mut self, segment: DataIndex, mem: MemoryIndex) -> Result<()> { |
no test coverage detected