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

Method emit_memory_copy

winch/codegen/src/codegen/mod.rs:1606–1655  ·  view source on GitHub ↗

Emit the `memory.copy` operation.

(&mut self, dst_mem: MemoryIndex, src_mem: MemoryIndex)

Source from the content-addressed store, hash-verified

1604
1605 /// Emit the `memory.copy` operation.
1606 pub fn emit_memory_copy(&mut self, dst_mem: MemoryIndex, src_mem: MemoryIndex) -> Result<()> {
1607 let dst_heap = self.env.resolve_heap(dst_mem);
1608 let src_heap = self.env.resolve_heap(src_mem);
1609 let dst_idx_size: OperandSize = dst_heap.index_type().try_into()?;
1610 let src_idx_size: OperandSize = src_heap.index_type().try_into()?;
1611
1612 let len = self.context.pop_to_reg(self.masm, None)?;
1613 let src = self.context.pop_to_reg(self.masm, None)?;
1614 let dst = self.context.pop_to_reg(self.masm, None)?;
1615
1616 // For 32-bit linear memories go ahead and make sure `len` is zero
1617 // extended within its register ensuring that the full 64-bits of the
1618 // register are defined. This assists in situations like cross-memory
1619 // copies where one memory is 32-bit and one is 64-bit and the same
1620 // register can be used for the length in both bounds checks below.
1621 if dst_idx_size == OperandSize::S32 || src_idx_size == OperandSize::S32 {
1622 self.masm.extend(
1623 writable!(len.reg),
1624 len.reg,
1625 Extend::<Zero>::I64Extend32.into(),
1626 )?;
1627 }
1628
1629 let dst_raw_addr = self.context.any_gpr(self.masm)?;
1630 self.emit_bounds_check_and_compute_addr(&dst_heap, dst_raw_addr, dst.reg, len.reg)?;
1631 self.context.free_reg(dst);
1632
1633 let src_raw_addr = self.context.any_gpr(self.masm)?;
1634 self.emit_bounds_check_and_compute_addr(&src_heap, src_raw_addr, src.reg, len.reg)?;
1635 self.context.free_reg(src);
1636
1637 self.context
1638 .stack
1639 .push(TypedReg::new(self.env.ptr_type(), dst_raw_addr).into());
1640 self.context
1641 .stack
1642 .push(TypedReg::new(self.env.ptr_type(), src_raw_addr).into());
1643 self.context
1644 .stack
1645 .push(TypedReg::new(self.env.ptr_type(), len.reg).into());
1646
1647 let builtin = self.env.builtins.memory_copy::<M::ABI>()?;
1648 FnCall::emit::<M>(
1649 &mut self.env,
1650 self.masm,
1651 &mut self.context,
1652 Callee::Builtin(builtin),
1653 )?;
1654 Ok(())
1655 }
1656
1657 /// Emit the `memory.fill` operation.
1658 pub fn emit_memory_fill(&mut self, mem: MemoryIndex) -> Result<()> {

Callers 1

visit_memory_copyMethod · 0.80

Calls 12

OkFunction · 0.85
resolve_heapMethod · 0.80
pop_to_regMethod · 0.80
any_gprMethod · 0.80
free_regMethod · 0.80
newFunction · 0.50
try_intoMethod · 0.45
index_typeMethod · 0.45
extendMethod · 0.45
pushMethod · 0.45
ptr_typeMethod · 0.45

Tested by

no test coverage detected