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

Method emit_memory_init

winch/codegen/src/codegen/mod.rs:1703–1804  ·  view source on GitHub ↗

Emit the `memory.init` operation.

(&mut self, segment: DataIndex, mem: MemoryIndex)

Source from the content-addressed store, hash-verified

1701
1702 /// Emit the `memory.init` operation.
1703 pub fn emit_memory_init(&mut self, segment: DataIndex, mem: MemoryIndex) -> Result<()> {
1704 let dst_heap = self.env.resolve_heap(mem);
1705
1706 let len = self.context.pop_to_reg(self.masm, None)?;
1707 let src = self.context.pop_to_reg(self.masm, None)?;
1708 let dst = self.context.pop_to_reg(self.masm, None)?;
1709
1710 // Make sure `len` is zero extended within its register ensuring that
1711 // the full 64-bits of the register are defined. This assists in
1712 // situations like cross-memory copies where one memory is 32-bit and
1713 // one is 64-bit and the same register can be used for the length in
1714 // both bounds checks below.
1715 self.masm.extend(
1716 writable!(len.reg),
1717 len.reg,
1718 Extend::<Zero>::I64Extend32.into(),
1719 )?;
1720
1721 let dst_raw_addr = self.context.any_gpr(self.masm)?;
1722 self.emit_bounds_check_and_compute_addr(&dst_heap, dst_raw_addr, dst.reg, len.reg)?;
1723 self.context.free_reg(dst);
1724
1725 let runtime_data_index = match self.env.translation.runtime_data_map[segment] {
1726 Some(i) => i,
1727
1728 // Active data segments always have length zero, so this is only
1729 // valid of src and len are both zero.
1730 None => {
1731 self.masm.cmp(src.reg, RegImm::i32(0), OperandSize::S32)?;
1732 self.masm
1733 .trapif(IntCmpKind::Ne, TrapCode::HEAP_OUT_OF_BOUNDS)?;
1734 self.masm.cmp(len.reg, RegImm::i32(0), OperandSize::S32)?;
1735 self.masm
1736 .trapif(IntCmpKind::Ne, TrapCode::HEAP_OUT_OF_BOUNDS)?;
1737 self.context.free_reg(dst_raw_addr);
1738 self.context.free_reg(src);
1739 self.context.free_reg(len);
1740 return Ok(());
1741 }
1742 };
1743
1744 // Bounds check this passive data segment. Load its
1745 // dynamically-specified length and see if that's in the range
1746 // of `src+len`.
1747 let data_segment_length_offset = self
1748 .env
1749 .vmoffsets
1750 .vmctx_runtime_data_length(runtime_data_index);
1751 let tmp1 = self.context.any_gpr(self.masm)?;
1752 let tmp2 = self.context.any_gpr(self.masm)?;
1753 self.masm.load(
1754 self.masm.address_at_vmctx(data_segment_length_offset)?,
1755 writable!(tmp1),
1756 OperandSize::S32,
1757 )?;
1758 self.masm
1759 .mov(writable!(tmp2), src.reg.into(), OperandSize::S32)?;
1760 self.masm.checked_uadd(

Callers 1

visit_memory_initMethod · 0.80

Calls 15

OkFunction · 0.85
i64Function · 0.85
resolve_heapMethod · 0.80
pop_to_regMethod · 0.80
any_gprMethod · 0.80
free_regMethod · 0.80
extendMethod · 0.45
cmpMethod · 0.45
trapifMethod · 0.45

Tested by

no test coverage detected