(mut vec: Vec<O::Payload>, mut ops: O)
| 25 | |
| 26 | impl<O: StreamOps> AbiBuffer<O> { |
| 27 | pub(crate) fn new(mut vec: Vec<O::Payload>, mut ops: O) -> AbiBuffer<O> { |
| 28 | // SAFETY: We're converting `Vec<T>` to `Vec<MaybeUninit<T>>`, which |
| 29 | // should be safe. |
| 30 | let rust_storage = unsafe { |
| 31 | let ptr = vec.as_mut_ptr(); |
| 32 | let len = vec.len(); |
| 33 | let cap = vec.capacity(); |
| 34 | mem::forget(vec); |
| 35 | Vec::<MaybeUninit<O::Payload>>::from_raw_parts(ptr.cast(), len, cap) |
| 36 | }; |
| 37 | |
| 38 | // If `lower` is provided then the canonical ABI format is different |
| 39 | // from the native format, so all items are converted at this time. |
| 40 | // |
| 41 | // Note that this is probably pretty inefficient for "big" use cases |
| 42 | // but it's hoped that "big" use cases are using `u8` and therefore |
| 43 | // skip this entirely. |
| 44 | let alloc = if ops.native_abi_matches_canonical_abi() { |
| 45 | None |
| 46 | } else { |
| 47 | let elem_layout = ops.elem_layout(); |
| 48 | let layout = Layout::from_size_align( |
| 49 | elem_layout.size() * rust_storage.len(), |
| 50 | elem_layout.align(), |
| 51 | ) |
| 52 | .unwrap(); |
| 53 | let (mut ptr, cleanup) = Cleanup::new(layout); |
| 54 | // SAFETY: All items in `rust_storage` are already initialized so |
| 55 | // it should be safe to read them and move ownership into the |
| 56 | // canonical ABI format. |
| 57 | unsafe { |
| 58 | for item in rust_storage.iter() { |
| 59 | let item = item.assume_init_read(); |
| 60 | ops.lower(item, ptr); |
| 61 | ptr = ptr.add(elem_layout.size()); |
| 62 | } |
| 63 | } |
| 64 | cleanup |
| 65 | }; |
| 66 | AbiBuffer { |
| 67 | rust_storage, |
| 68 | alloc, |
| 69 | ops, |
| 70 | cursor: 0, |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | /// Returns the canonical ABI pointer/length to pass off to a write |
| 75 | /// operation. |
nothing calls this directly
no test coverage detected