Creates a new owned instance handle from `req`. The runtime memory/table data structures must have been previously allocated and are present within `memories` and `tables`. These values are `mem::take`n upon allocation success of an instance, and if the instance allocation fails then these are otherwise left in place. This enable the pooling allocator to run custom deallocation code for them, for
(
req: InstanceAllocationRequest,
memories: &mut TryPrimaryMap<DefinedMemoryIndex, (MemoryAllocationIndex, Memory)>,
tables: &mut TryPrimaryMap<DefinedTableIndex, (TableAllocat
| 166 | /// being allocated according to `req.runtime_info`. Additionally `memories` |
| 167 | /// and `tables` must have been allocated for `req.store`. |
| 168 | unsafe fn new( |
| 169 | req: InstanceAllocationRequest, |
| 170 | memories: &mut TryPrimaryMap<DefinedMemoryIndex, (MemoryAllocationIndex, Memory)>, |
| 171 | tables: &mut TryPrimaryMap<DefinedTableIndex, (TableAllocationIndex, Table)>, |
| 172 | ) -> Result<InstanceHandle, OutOfMemory> { |
| 173 | let module = req.runtime_info.env_module(); |
| 174 | let memory_tys = &module.memories; |
| 175 | let mut passive_elements = TryVec::with_capacity(module.passive_elements.len())?; |
| 176 | |
| 177 | #[cfg(feature = "wmemcheck")] |
| 178 | let wmemcheck_state = if req.store.engine().config().wmemcheck { |
| 179 | let size = memory_tys |
| 180 | .iter() |
| 181 | .next() |
| 182 | .map(|memory| memory.1.limits.min) |
| 183 | .unwrap_or(0) |
| 184 | * 64 |
| 185 | * 1024; |
| 186 | Some(Wmemcheck::new(size.try_into().unwrap())) |
| 187 | } else { |
| 188 | None |
| 189 | }; |
| 190 | #[cfg(not(feature = "wmemcheck"))] |
| 191 | let _ = memory_tys; |
| 192 | |
| 193 | for (_, (ty, len)) in req.runtime_info.env_module().passive_elements.iter() { |
| 194 | let len = usize::try_from(*len).unwrap(); |
| 195 | passive_elements.push(PassiveElementSegment::new(*ty, len)?)?; |
| 196 | } |
| 197 | |
| 198 | // Allocate the instance and its `VMContext` with empty memory and table |
| 199 | // maps. This is the final fallible allocation in this function; only |
| 200 | // after it succeeds do we transfer ownership of the pool-allocated |
| 201 | // `memories`/`tables` into the instance (below), so that a failure here |
| 202 | // leaves them in the caller's deallocation guard to be freed. |
| 203 | let mut ret = OwnedInstance::new(Instance { |
| 204 | id: req.id, |
| 205 | runtime_info: req.runtime_info.clone(), |
| 206 | memories: TryPrimaryMap::default(), |
| 207 | tables: TryPrimaryMap::default(), |
| 208 | passive_elements, |
| 209 | #[cfg(feature = "wmemcheck")] |
| 210 | wmemcheck_state, |
| 211 | store: None, |
| 212 | vmctx: OwnedVMContext::new(), |
| 213 | })?; |
| 214 | |
| 215 | // Can't fail any more, so transfer ownership of `memories` and `tables` |
| 216 | // to this instance. |
| 217 | *ret.get_mut().memories_mut() = mem::take(memories); |
| 218 | *ret.get_mut().tables_mut() = mem::take(tables); |
| 219 | |
| 220 | // SAFETY: this vmctx was allocated with the same layout above, so it |
| 221 | // should be safe to initialize with the same values here. |
| 222 | unsafe { |
| 223 | ret.get_mut().initialize_vmctx(req.store, req.imports); |
| 224 | } |
| 225 |
nothing calls this directly
no test coverage detected