(
&mut self,
dst: usize,
src_memory: &MemoryInstance,
src: usize,
len: usize,
)
| 189 | } |
| 190 | |
| 191 | pub(crate) fn copy_from_memory( |
| 192 | &mut self, |
| 193 | dst: usize, |
| 194 | src_memory: &MemoryInstance, |
| 195 | src: usize, |
| 196 | len: usize, |
| 197 | ) -> Result<(), Trap> { |
| 198 | fn check_range(mem: &MemoryStorage, addr: usize, len: usize) -> Result<(), crate::Trap> { |
| 199 | let Some(end) = addr.checked_add(len) else { |
| 200 | cold_path(); |
| 201 | return Err(memory_oob(addr, len, mem.len())); |
| 202 | }; |
| 203 | |
| 204 | if end > mem.len() || end < addr { |
| 205 | cold_path(); |
| 206 | return Err(memory_oob(addr, len, mem.len())); |
| 207 | } |
| 208 | Ok(()) |
| 209 | } |
| 210 | |
| 211 | check_range(&src_memory.inner, src, len)?; |
| 212 | check_range(&self.inner, dst, len)?; |
| 213 | |
| 214 | if len == 0 { |
| 215 | return Ok(()); |
| 216 | } |
| 217 | |
| 218 | let mut buf = [0u8; Self::COPY_CHUNK_SIZE]; |
| 219 | let mut copied = 0; |
| 220 | while copied < len { |
| 221 | let chunk_len = buf.len().min(len - copied); |
| 222 | src_memory.inner.read_exact(src + copied, &mut buf[..chunk_len]).ok_or_else(|| { |
| 223 | cold_path(); |
| 224 | memory_oob(src + copied, chunk_len, src_memory.inner.len()) |
| 225 | })?; |
| 226 | self.inner.write_all(dst + copied, &buf[..chunk_len]).ok_or_else(|| { |
| 227 | cold_path(); |
| 228 | memory_oob(dst + copied, chunk_len, self.inner.len()) |
| 229 | })?; |
| 230 | copied += chunk_len; |
| 231 | } |
| 232 | |
| 233 | Ok(()) |
| 234 | } |
| 235 | |
| 236 | pub(crate) fn copy_within(&mut self, dst: usize, src: usize, len: usize) -> Result<(), Trap> { |
| 237 | self.inner.copy_within(dst, src, len).ok_or_else(|| { |
no test coverage detected