MCPcopy Create free account
hub / github.com/bytecodealliance/wit-bindgen / take_vec

Method take_vec

crates/guest-rust/src/rt/async_support/abi_buffer.rs:147–191  ·  view source on GitHub ↗
(&mut self)

Source from the content-addressed store, hash-verified

145 }
146
147 fn take_vec(&mut self) -> Vec<O::Payload> {
148 // First, if necessary, convert remaining values within `self.alloc`
149 // back into `self.rust_storage`. This is necessary when a lift
150 // operation is available meaning that the representation of `T` is
151 // different in the canonical ABI.
152 //
153 // Note that when `lift` is provided then when this original
154 // `AbiBuffer` was created it moved ownership of all values from the
155 // original vector into the `alloc` value. This is the reverse
156 // operation, moving all the values back into the vector.
157 if !self.ops.native_abi_matches_canonical_abi() {
158 let (mut ptr, mut len) = self.abi_ptr_and_len();
159 // SAFETY: this should be safe as `lift` is operating on values that
160 // were initialized with a previous `lower`, and the pointer
161 // arithmetic here should all be in-bounds.
162 unsafe {
163 for dst in self.rust_storage[self.cursor..].iter_mut() {
164 dst.write(self.ops.lift(ptr.cast_mut()));
165 ptr = ptr.add(self.ops.elem_layout().size());
166 len -= 1;
167 }
168 assert_eq!(len, 0);
169 }
170 }
171
172 // Next extract the rust storage and zero out this struct's fields.
173 // This is also the location where a "shift" happens to remove items
174 // from the beginning of the returned vector as those have already been
175 // transferred somewhere else.
176 let mut storage = mem::take(&mut self.rust_storage);
177 storage.drain(..self.cursor);
178 self.cursor = 0;
179 self.alloc = None;
180
181 // SAFETY: we're casting `Vec<MaybeUninit<T>>` here to `Vec<T>`. The
182 // elements were either always initialized (`lift` is `None`) or we just
183 // re-initialized them above from `self.alloc`.
184 unsafe {
185 let ptr = storage.as_mut_ptr();
186 let len = storage.len();
187 let cap = storage.capacity();
188 mem::forget(storage);
189 Vec::<O::Payload>::from_raw_parts(ptr.cast(), len, cap)
190 }
191 }
192}
193
194impl<O> Drop for AbiBuffer<O>

Callers 2

into_vecMethod · 0.80
dropMethod · 0.80

Calls 7

abi_ptr_and_lenMethod · 0.80
writeMethod · 0.45
liftMethod · 0.45
addMethod · 0.45
sizeMethod · 0.45
elem_layoutMethod · 0.45

Tested by

no test coverage detected