(&mut self, data_index: u32, mem_index: u32)
| 1320 | } |
| 1321 | |
| 1322 | fn exec_memory_init(&mut self, data_index: u32, mem_index: u32) -> Result<(), Trap> { |
| 1323 | let size = i32::stack_pop(&mut self.store.value_stack); |
| 1324 | let offset = i32::stack_pop(&mut self.store.value_stack); |
| 1325 | let dst = i32::stack_pop(&mut self.store.value_stack); |
| 1326 | |
| 1327 | let data_addr = self.module.resolve_data_addr(data_index) as usize; |
| 1328 | let Some(data) = self.store.state.data.get(data_addr) else { |
| 1329 | unreachable!("data segment not found, should have been validated by the parser") |
| 1330 | }; |
| 1331 | |
| 1332 | let mem_addr = self.module.resolve_mem_addr(mem_index) as usize; |
| 1333 | let Some(mem) = self.store.state.memories.get_mut(mem_addr) else { |
| 1334 | unreachable!("memory not found, should have been validated by the parser") |
| 1335 | }; |
| 1336 | |
| 1337 | let data_len = data.data.as_ref().map_or(0, |d| d.len()); |
| 1338 | if ((size + offset) as usize > data_len) || ((dst + size) as usize > mem.inner.len()) { |
| 1339 | cold_path(); |
| 1340 | return Err(Trap::MemoryOutOfBounds { offset: offset as usize, len: size as usize, max: data_len }); |
| 1341 | } |
| 1342 | |
| 1343 | if size == 0 { |
| 1344 | return Ok(()); |
| 1345 | } |
| 1346 | |
| 1347 | let Some(data) = &data.data else { |
| 1348 | cold_path(); |
| 1349 | return Err(Trap::MemoryOutOfBounds { offset: 0, len: 0, max: 0 }); |
| 1350 | }; |
| 1351 | |
| 1352 | if mem.inner.write_all(dst as usize, &data[offset as usize..((offset + size) as usize)]).is_none() { |
| 1353 | cold_path(); |
| 1354 | return Err(Trap::MemoryOutOfBounds { offset: dst as usize, len: size as usize, max: mem.inner.len() }); |
| 1355 | } |
| 1356 | Ok(()) |
| 1357 | } |
| 1358 | |
| 1359 | fn exec_table_copy(&mut self, dst_table: u32, src_table: u32) -> Result<(), Trap> { |
| 1360 | let size = i32::stack_pop(&mut self.store.value_stack); |
no test coverage detected