Bug 1452620 - Add an FfiVec structure. r?Gankro
This structure makes it more ergonomic to access vectors from C++. A
Vec<T> can be converted to FfiVec<T> which can safely cross the FFI
boundary. That provides an easy to use read-only access mechanism to the
vector contents. The FfiVec must be returned to rust code to be freed
properly.
MozReview-Commit-ID: AdIyEsjrPSZ
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -154,16 +154,49 @@ impl WrVecU8 {
fn push_bytes(&mut self, bytes: &[u8]) {
let mut vec = self.flush_into_vec();
vec.extend_from_slice(bytes);
*self = Self::from_vec(vec);
}
}
+#[repr(C)]
+pub struct FfiVec<T> {
+ // We use a *const instead of a *mut because we don't want the C++ side
+ // to be mutating this. It is strictly read-only from C++
+ data: *const T,
+ length: usize,
+ capacity: usize,
+}
+
+impl<T> FfiVec<T> {
+ fn from_vec(v: Vec<T>) -> FfiVec<T> {
+ let ret = FfiVec {
+ data: v.as_ptr(),
+ length: v.len(),
+ capacity: v.capacity(),
+ };
+ mem::forget(v);
+ ret
+ }
+}
+
+impl<T> Drop for FfiVec<T> {
+ fn drop(&mut self) {
+ // turn the stuff back into a Vec and let it be freed normally
+ let _ = unsafe {
+ Vec::from_raw_parts(
+ self.data as *mut T,
+ self.length,
+ self.capacity
+ )
+ };
+ }
+}
#[no_mangle]
pub extern "C" fn wr_vec_u8_push_bytes(v: &mut WrVecU8, bytes: ByteSlice) {
v.push_bytes(bytes.as_slice());
}
#[no_mangle]
pub extern "C" fn wr_vec_u8_free(v: WrVecU8) {