From ab90379eac8899bea345a1b4a0c12400cdf1bf61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Ver=C5=A1i=C4=87?= Date: Thu, 11 Jan 2024 22:15:13 +0300 Subject: [PATCH] [feature] #4126: add implementation for Box FFI conversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marin Veršić --- ffi/derive/src/lib.rs | 2 +- ffi/derive/src/wrapper.rs | 6 +- ffi/src/ir.rs | 52 +++--- ffi/src/lib.rs | 2 +- ffi/src/primitives.rs | 4 +- ffi/src/repr_c.rs | 286 +++++++++++++++++++++------------ ffi/src/slice.rs | 33 ++-- ffi/src/std_impls.rs | 21 ++- ffi/tests/export_shared_fns.rs | 2 +- ffi/tests/ffi_export.rs | 8 +- ffi/tests/ffi_import.rs | 16 +- ffi/tests/ffi_import_opaque.rs | 6 +- ffi/tests/import_getset.rs | 6 +- ffi/tests/import_shared_fns.rs | 4 +- ffi/tests/transparent.rs | 6 +- 15 files changed, 265 insertions(+), 189 deletions(-) diff --git a/ffi/derive/src/lib.rs b/ffi/derive/src/lib.rs index aa2fd27550d..0d56d35a2dd 100644 --- a/ffi/derive/src/lib.rs +++ b/ffi/derive/src/lib.rs @@ -260,7 +260,7 @@ pub fn ffi_type_derive(input: TokenStream) -> TokenStream { /// /* function implementation */ /// FfiReturn::Ok /// } -/// extern "C" fn Foo__bar(handle: *const Foo, output: *mut SliceRef) -> FfiReturn { +/// extern "C" fn Foo__bar(handle: *const Foo, output: *mut RefSlice) -> FfiReturn { /// /* function implementation */ /// FfiReturn::Ok /// } diff --git a/ffi/derive/src/wrapper.rs b/ffi/derive/src/wrapper.rs index 01aec489542..eb8fab7d9b0 100644 --- a/ffi/derive/src/wrapper.rs +++ b/ffi/derive/src/wrapper.rs @@ -382,9 +382,9 @@ fn gen_impl_ffi(name: &Ident, generics: &syn2::Generics) -> TokenStream { type Ref<#lifetime> = &#lifetime iroha_ffi::Extern where #(#lifetime_bounded_where_clause),*; type RefMut<#lifetime> = &#lifetime mut iroha_ffi::Extern where #(#lifetime_bounded_where_clause),*; type Box = Box; - type SliceBox = Box<[iroha_ffi::Extern]>; - type SliceRef<#lifetime> = &#lifetime [iroha_ffi::ir::Transparent] where #(#lifetime_bounded_where_clause),*; - type SliceRefMut<#lifetime> = &#lifetime mut [iroha_ffi::ir::Transparent] where #(#lifetime_bounded_where_clause),*; + type BoxedSlice = Box<[iroha_ffi::Extern]>; + type RefSlice<#lifetime> = &#lifetime [iroha_ffi::ir::Transparent] where #(#lifetime_bounded_where_clause),*; + type RefMutSlice<#lifetime> = &#lifetime mut [iroha_ffi::ir::Transparent] where #(#lifetime_bounded_where_clause),*; type Vec = Vec; type Arr = iroha_ffi::ir::Transparent; } diff --git a/ffi/src/ir.rs b/ffi/src/ir.rs index 6c99c9dbf69..b8dfa64aa14 100644 --- a/ffi/src/ir.rs +++ b/ffi/src/ir.rs @@ -103,16 +103,16 @@ pub trait IrTypeFamily { type RefMut<'itm> where Self: 'itm; - /// [`Ir`] type that [`Box`] is mapped into + /// [`Ir`] type that [`Box`] is mapped into for any `T: Sized` type Box; /// [`Ir`] type that `Box<[T]>` is mapped into - type SliceBox; + type BoxedSlice; /// [`Ir`] type that `&[T]` is mapped into - type SliceRef<'itm> + type RefSlice<'itm> where Self: 'itm; /// [`Ir`] type that `&mut [T]` is mapped into - type SliceRefMut<'itm> + type RefMutSlice<'itm> where Self: 'itm; /// [`Ir`] type that [`Vec`] is mapped into @@ -126,10 +126,10 @@ impl IrTypeFamily for R { // NOTE: Unused type RefMut<'itm> = () where Self: 'itm; type Box = Box; - type SliceBox = Box<[Self]>; - type SliceRef<'itm> = &'itm [Self] where Self: 'itm; + type BoxedSlice = Box<[Self]>; + type RefSlice<'itm> = &'itm [Self] where Self: 'itm; // NOTE: Unused - type SliceRefMut<'itm> = () where Self: 'itm; + type RefMutSlice<'itm> = () where Self: 'itm; type Vec = Vec; type Arr = [Self; N]; } @@ -137,9 +137,9 @@ impl IrTypeFamily for Robust { type Ref<'itm> = Transparent; type RefMut<'itm> = Transparent; type Box = Box; - type SliceBox = Box<[Self]>; - type SliceRef<'itm> = &'itm [Self]; - type SliceRefMut<'itm> = &'itm mut [Self]; + type BoxedSlice = Box<[Self]>; + type RefSlice<'itm> = &'itm [Self]; + type RefMutSlice<'itm> = &'itm mut [Self]; type Vec = Vec; type Arr = Self; } @@ -147,9 +147,9 @@ impl IrTypeFamily for Opaque { type Ref<'itm> = Transparent; type RefMut<'itm> = Transparent; type Box = Box; - type SliceBox = Box<[Self]>; - type SliceRef<'itm> = &'itm [Self]; - type SliceRefMut<'itm> = &'itm mut [Self]; + type BoxedSlice = Box<[Self]>; + type RefSlice<'itm> = &'itm [Self]; + type RefMutSlice<'itm> = &'itm mut [Self]; type Vec = Vec; type Arr = [Self; N]; } @@ -157,9 +157,9 @@ impl IrTypeFamily for Transparent { type Ref<'itm> = Self; type RefMut<'itm> = Self; type Box = Box; - type SliceBox = Box<[Self]>; - type SliceRef<'itm> = &'itm [Self]; - type SliceRefMut<'itm> = &'itm mut [Self]; + type BoxedSlice = Box<[Self]>; + type RefSlice<'itm> = &'itm [Self]; + type RefMutSlice<'itm> = &'itm mut [Self]; type Vec = Vec; type Arr = Self; } @@ -167,9 +167,9 @@ impl IrTypeFamily for &Extern { type Ref<'itm> = &'itm Self where Self: 'itm; type RefMut<'itm> = &'itm mut Self where Self: 'itm; type Box = Box; - type SliceBox = Box<[Self]>; - type SliceRef<'itm> = &'itm [Self] where Self: 'itm; - type SliceRefMut<'itm> = &'itm mut [Self] where Self: 'itm; + type BoxedSlice = Box<[Self]>; + type RefSlice<'itm> = &'itm [Self] where Self: 'itm; + type RefMutSlice<'itm> = &'itm mut [Self] where Self: 'itm; type Vec = Vec; type Arr = [Self; N]; } @@ -177,9 +177,9 @@ impl IrTypeFamily for &mut Extern { type Ref<'itm> = &'itm Self where Self: 'itm; type RefMut<'itm> = &'itm mut Self where Self: 'itm; type Box = Box; - type SliceBox = Box<[Self]>; - type SliceRef<'itm> = &'itm [Self] where Self: 'itm; - type SliceRefMut<'itm> = &'itm mut [Self] where Self: 'itm; + type BoxedSlice = Box<[Self]>; + type RefSlice<'itm> = &'itm [Self] where Self: 'itm; + type RefMutSlice<'itm> = &'itm mut [Self] where Self: 'itm; type Vec = Vec; type Arr = [Self; N]; } @@ -221,27 +221,27 @@ impl Ir for Box<[R]> where R::Type: IrTypeFamily, { - type Type = ::SliceBox; + type Type = ::BoxedSlice; } impl<'itm, R: Ir> Ir for &'itm [R] where R::Type: IrTypeFamily, { - type Type = ::SliceRef<'itm>; + type Type = ::RefSlice<'itm>; } #[cfg(feature = "non_robust_ref_mut")] impl<'itm, R: Ir> Ir for &'itm mut [R] where R::Type: IrTypeFamily, { - type Type = ::SliceRefMut<'itm>; + type Type = ::RefMutSlice<'itm>; } #[cfg(not(feature = "non_robust_ref_mut"))] impl<'itm, R: Ir + InfallibleTransmute> Ir for &'itm mut [R] where R::Type: IrTypeFamily, { - type Type = ::SliceRefMut<'itm>; + type Type = ::RefMutSlice<'itm>; } impl Ir for Vec where diff --git a/ffi/src/lib.rs b/ffi/src/lib.rs index 4590f55b1c7..8467a87c981 100644 --- a/ffi/src/lib.rs +++ b/ffi/src/lib.rs @@ -223,7 +223,7 @@ pub struct LocalRef<'data, R>(R, core::marker::PhantomData<&'data ()>); /// ``` #[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord)] #[repr(transparent)] -pub struct LocalSlice<'data, R>(alloc::vec::Vec, core::marker::PhantomData<&'data ()>); +pub struct LocalSlice<'data, R>(alloc::boxed::Box<[R]>, core::marker::PhantomData<&'data ()>); /// Result of execution of an FFI function #[derive(Debug, Display, Clone, Copy, PartialEq, Eq)] diff --git a/ffi/src/primitives.rs b/ffi/src/primitives.rs index b6009b1f138..2b7301b15c3 100644 --- a/ffi/src/primitives.rs +++ b/ffi/src/primitives.rs @@ -30,8 +30,8 @@ mod wasm { type Ref<'itm> = Transparent; type RefMut<'itm> = Transparent; type Box = Box; - type SliceRef<'itm> = &'itm [Robust]; - type SliceRefMut<'itm> = &'itm mut [Robust]; + type RefSlice<'itm> = &'itm [Robust]; + type RefMutSlice<'itm> = &'itm mut [Robust]; type Vec = Vec; type Arr = Robust; } diff --git a/ffi/src/repr_c.rs b/ffi/src/repr_c.rs index 621b160b173..2a88e9657d6 100644 --- a/ffi/src/repr_c.rs +++ b/ffi/src/repr_c.rs @@ -10,7 +10,7 @@ use core::{mem::ManuallyDrop, ptr::addr_of_mut}; use crate::{ ir::{External, Ir, Opaque, Robust, Transmute, Transparent}, - slice::{OutBoxedSlice, SliceMut, SliceRef}, + slice::{OutBoxedSlice, RefMutSlice, RefSlice}, Extern, FfiConvert, FfiOutPtr, FfiOutPtrRead, FfiOutPtrWrite, FfiReturn, FfiType, FfiWrapperType, LocalRef, LocalSlice, ReprC, Result, WrapperTypeOf, }; @@ -115,11 +115,11 @@ pub trait COutPtrRead: COutPtr + Sized { /// # Example /// /// 1. `&[u8]` implements [`NonLocal`] -/// This type will be converted to [`SliceRef`] and during conversion will not make use -/// of the store (in any direction). The corresponding out-pointer will be `*mut SliceRef` +/// This type will be converted to [`RefSlice`] and during conversion will not make use +/// of the store (in any direction). The corresponding out-pointer will be `*mut RefSlice` /// /// 2. `&[Opaque]` doesn't implement [`NonLocal`] -/// This type will be converted to [`SliceRef<*const T>`] and during conversion will use the +/// This type will be converted to [`RefSlice<*const T>`] and during conversion will use the /// local store `Vec<*const T>`. The corresponding out-pointer will be `*mut OutBoxedSlice<*const T>`. /// /// 3. `&(u32, u32)` @@ -278,7 +278,7 @@ impl<'itm, R: NonLocal + CTypeConvert<'itm, S, R::ReprC> + Clone + 'itm, S: C COutPtrWrite> for Box { unsafe fn write_out(self, out_ptr: *mut Self::OutPtr) { - let mut store = <(Option, R::RustStore)>::default(); + let mut store = <(_, _)>::default(); // NOTE: Bypasses the erroneous lifetime check. // Correct as long as `R::into_repr_c` doesn't return a reference to the store (`R: NonLocal`) let store_borrow = &mut *addr_of_mut!(store); @@ -301,17 +301,101 @@ impl<'itm, R: NonLocal + CTypeConvert<'itm, S, R::ReprC> + Clone + 'itm, S: C } } +impl, S: Cloned> CType> for Box<[R]> { + type ReprC = RefMutSlice; +} +impl<'itm, R: CTypeConvert<'itm, S, C> + Clone, S: Cloned, C: ReprC> + CTypeConvert<'itm, Box<[S]>, RefMutSlice> for Box<[R]> +{ + type RustStore = (Box<[C]>, Box<[R::RustStore]>); + type FfiStore = Box<[R::FfiStore]>; + + fn into_repr_c(self, store: &'itm mut Self::RustStore) -> RefMutSlice { + let boxed_slice = self; + + store.1 = core::iter::repeat_with(Default::default) + .take(boxed_slice.len()) + .collect(); + + store.0 = Vec::from(boxed_slice) + .into_iter() + .zip(&mut *store.1) + .map(|(item, substore)| item.into_repr_c(substore)) + .collect(); + + RefMutSlice::from_slice(Some(&mut store.0)) + } + unsafe fn try_from_repr_c( + source: RefMutSlice, + store: &'itm mut Self::FfiStore, + ) -> Result { + let slice = source.into_rust().ok_or(FfiReturn::ArgIsNull)?; + + *store = core::iter::repeat_with(Default::default) + .take(slice.len()) + .collect(); + + let vec: Box<[_]> = slice + .iter() + .copied() + .zip(&mut **store) + .map(|(item, substore)| R::try_from_repr_c(item, substore).map(ManuallyDrop::new)) + .collect::>()?; + + Ok(vec.iter().cloned().map(ManuallyDrop::into_inner).collect()) + } +} + +impl, S: Cloned> CWrapperType> for Box<[R]> { + type InputType = Box<[R::InputType]>; + type ReturnType = Box<[R::ReturnType]>; +} +impl, S: Cloned> COutPtr> for Box<[R]> { + type OutPtr = OutBoxedSlice; +} +impl<'itm, R: NonLocal + CTypeConvert<'itm, S, R::ReprC> + Clone + 'itm, S: Cloned + 'itm> + COutPtrWrite> for Box<[R]> +{ + unsafe fn write_out(self, out_ptr: *mut Self::OutPtr) { + let mut store = <(_, _)>::default(); + // NOTE: Bypasses the erroneous lifetime check. + // Correct as long as `R::into_repr_c` doesn't return a reference to the store (`R: NonLocal`) + let store_borrow = &mut *addr_of_mut!(store); + CTypeConvert::, _>::into_repr_c(self, store_borrow); + out_ptr.write(OutBoxedSlice::from_boxed_slice(Some(store.0))); + } +} +impl<'itm, R: NonLocal + CTypeConvert<'itm, S, R::ReprC> + Clone + 'itm, S: Cloned + 'itm> + COutPtrRead> for Box<[R]> +{ + unsafe fn try_read_out(out_ptr: Self::OutPtr) -> Result { + let slice = RefMutSlice::from_raw_parts_mut(out_ptr.as_mut_ptr(), out_ptr.len()); + + let mut store = Box::default(); + // NOTE: Bypasses the erroneous lifetime check. + // Correct as long as `R::try_from_repr_c` doesn't return a reference to the store (`R: NonLocal`) + let store_borrow = &mut *addr_of_mut!(store); + let res = Self::try_from_repr_c(slice, store_borrow); + + if !out_ptr.deallocate() { + return Err(FfiReturn::TrapRepresentation); + } + + res + } +} + // NOTE: `CType` cannot be implemented for `&mut [T]` impl, S: Cloned> CType<&[S]> for &[R] { - type ReprC = SliceRef; + type ReprC = RefSlice; } impl<'slice, R: CTypeConvert<'slice, S, C> + Clone, S: Cloned, C: ReprC> - CTypeConvert<'slice, &'slice [S], SliceRef> for &'slice [R] + CTypeConvert<'slice, &'slice [S], RefSlice> for &'slice [R] { - type RustStore = (Vec, Vec); - type FfiStore = (Vec, Vec); + type RustStore = (Box<[C]>, Box<[R::RustStore]>); + type FfiStore = (Box<[R]>, Box<[R::FfiStore]>); - fn into_repr_c(self, store: &'slice mut Self::RustStore) -> SliceRef { + fn into_repr_c(self, store: &'slice mut Self::RustStore) -> RefSlice { let slice = self.to_vec(); store.1 = core::iter::repeat_with(Default::default) @@ -320,26 +404,26 @@ impl<'slice, R: CTypeConvert<'slice, S, C> + Clone, S: Cloned, C: ReprC> store.0 = slice .into_iter() - .zip(&mut store.1) + .zip(&mut *store.1) .map(|(item, substore)| item.into_repr_c(substore)) .collect(); - SliceRef::from_slice(Some(&store.0)) + RefSlice::from_slice(Some(&store.0)) } unsafe fn try_from_repr_c( - source: SliceRef, + source: RefSlice, store: &'slice mut Self::FfiStore, ) -> Result { store.1 = core::iter::repeat_with(Default::default) .take(source.len()) .collect(); - let source: Vec> = source + let source: Box<[_]> = source .into_rust() .ok_or(FfiReturn::ArgIsNull)? .iter() - .zip(&mut store.1) + .zip(&mut *store.1) .map(|(&item, substore)| R::try_from_repr_c(item, substore).map(ManuallyDrop::new)) .collect::>()?; @@ -364,21 +448,21 @@ impl<'itm, R: NonLocal + CTypeConvert<'itm, S, R::ReprC> + Clone, S: Cloned> COutPtrWrite<&'itm [S]> for &'itm [R] { unsafe fn write_out(self, out_ptr: *mut Self::OutPtr) { - let mut store = <(Vec, Vec)>::default(); + let mut store = <(_, _)>::default(); // NOTE: Bypasses the erroneous lifetime check. // Correct as long as `R::into_repr_c` doesn't return a reference to the store (`R: NonLocal`) let store_borrow = &mut *addr_of_mut!(store); CTypeConvert::<&[S], _>::into_repr_c(self, store_borrow); - out_ptr.write(OutBoxedSlice::from_vec(Some(store.0))); + out_ptr.write(OutBoxedSlice::from_boxed_slice(Some(store.0))); } } impl<'itm, R: NonLocal + CTypeConvert<'itm, S, R::ReprC> + Clone + 'itm, S: Cloned + 'itm> COutPtrRead<&'itm [S]> for LocalSlice<'itm, R> { unsafe fn try_read_out(out_ptr: OutBoxedSlice) -> Result { - let slice = SliceRef::from_raw_parts(out_ptr.as_mut_ptr(), out_ptr.len()); + let slice = RefSlice::from_raw_parts(out_ptr.as_mut_ptr(), out_ptr.len()); - let mut store = <(Vec, Vec)>::default(); + let mut store = <(_, _)>::default(); // NOTE: Bypasses the erroneous lifetime check. // Correct as long as `R::try_from_repr_c` doesn't return a reference to the store (`R: NonLocal`) let store_borrow = &mut *addr_of_mut!(store); @@ -394,15 +478,15 @@ impl<'itm, R: NonLocal + CTypeConvert<'itm, S, R::ReprC> + Clone + 'itm, S: C } impl, S: Cloned> CType> for Vec { - type ReprC = SliceMut; + type ReprC = RefMutSlice; } impl<'itm, R: CTypeConvert<'itm, S, C> + Clone, S: Cloned, C: ReprC> - CTypeConvert<'itm, Vec, SliceMut> for Vec + CTypeConvert<'itm, Vec, RefMutSlice> for Vec { - type RustStore = (Vec, Vec); - type FfiStore = Vec; + type RustStore = (Box<[C]>, Box<[R::RustStore]>); + type FfiStore = Box<[R::FfiStore]>; - fn into_repr_c(self, store: &'itm mut Self::RustStore) -> SliceMut { + fn into_repr_c(self, store: &'itm mut Self::RustStore) -> RefMutSlice { let vec = self; store.1 = core::iter::repeat_with(Default::default) @@ -411,14 +495,14 @@ impl<'itm, R: CTypeConvert<'itm, S, C> + Clone, S: Cloned, C: ReprC> store.0 = vec .into_iter() - .zip(&mut store.1) + .zip(&mut *store.1) .map(|(item, substore)| item.into_repr_c(substore)) .collect(); - SliceMut::from_slice(Some(&mut store.0)) + RefMutSlice::from_slice(Some(&mut store.0)) } unsafe fn try_from_repr_c( - source: SliceMut, + source: RefMutSlice, store: &'itm mut Self::FfiStore, ) -> Result { let slice = source.into_rust().ok_or(FfiReturn::ArgIsNull)?; @@ -427,18 +511,14 @@ impl<'itm, R: CTypeConvert<'itm, S, C> + Clone, S: Cloned, C: ReprC> .take(slice.len()) .collect(); - let vec: Vec> = slice + let vec: Box<[_]> = slice .iter() .copied() - .zip(store) + .zip(&mut **store) .map(|(item, substore)| R::try_from_repr_c(item, substore).map(ManuallyDrop::new)) .collect::>()?; - Ok(vec - .iter() - .cloned() - .map(ManuallyDrop::into_inner) - .collect::>()) + Ok(vec.iter().cloned().map(ManuallyDrop::into_inner).collect()) } } @@ -453,21 +533,21 @@ impl<'itm, R: NonLocal + CTypeConvert<'itm, S, R::ReprC> + Clone + 'itm, S: C COutPtrWrite> for Vec { unsafe fn write_out(self, out_ptr: *mut Self::OutPtr) { - let mut store = <(Vec, Vec)>::default(); + let mut store = <(_, _)>::default(); // NOTE: Bypasses the erroneous lifetime check. // Correct as long as `R::into_repr_c` doesn't return a reference to the store (`R: NonLocal`) let store_borrow = &mut *addr_of_mut!(store); CTypeConvert::, _>::into_repr_c(self, store_borrow); - out_ptr.write(OutBoxedSlice::from_vec(Some(store.0))); + out_ptr.write(OutBoxedSlice::from_boxed_slice(Some(store.0))); } } impl<'itm, R: NonLocal + CTypeConvert<'itm, S, R::ReprC> + Clone + 'itm, S: Cloned + 'itm> COutPtrRead> for Vec { unsafe fn try_read_out(out_ptr: Self::OutPtr) -> Result { - let slice = SliceMut::from_raw_parts_mut(out_ptr.as_mut_ptr(), out_ptr.len()); + let slice = RefMutSlice::from_raw_parts_mut(out_ptr.as_mut_ptr(), out_ptr.len()); - let mut store = Vec::default(); + let mut store = Box::default(); // NOTE: Bypasses the erroneous lifetime check. // Correct as long as `R::try_from_repr_c` doesn't return a reference to the store (`R: NonLocal`) let store_borrow = &mut *addr_of_mut!(store); @@ -688,18 +768,18 @@ impl COutPtrRead> for Box { } impl CType> for Box<[R]> { - type ReprC = SliceMut; + type ReprC = RefMutSlice; } -impl CTypeConvert<'_, Box<[Robust]>, SliceMut> for Box<[R]> { +impl CTypeConvert<'_, Box<[Robust]>, RefMutSlice> for Box<[R]> { type RustStore = Self; type FfiStore = (); - fn into_repr_c(self, store: &mut Self::RustStore) -> SliceMut { + fn into_repr_c(self, store: &mut Self::RustStore) -> RefMutSlice { *store = self; - SliceMut::from_slice(Some(store.as_mut())) + RefMutSlice::from_slice(Some(store)) } - unsafe fn try_from_repr_c(source: SliceMut, (): &mut ()) -> Result { + unsafe fn try_from_repr_c(source: RefMutSlice, (): &mut ()) -> Result { source .into_rust() .ok_or(FfiReturn::ArgIsNull) @@ -723,7 +803,7 @@ impl COutPtrWrite> for Box<[R]> { } impl COutPtrRead> for Box<[R]> { unsafe fn try_read_out(out_ptr: Self::OutPtr) -> Result { - let slice = SliceMut::from_raw_parts_mut(out_ptr.as_mut_ptr(), out_ptr.len()); + let slice = RefMutSlice::from_raw_parts_mut(out_ptr.as_mut_ptr(), out_ptr.len()); let res = CTypeConvert::, _>::try_from_repr_c(slice, &mut ()); if !out_ptr.deallocate() { @@ -735,17 +815,17 @@ impl COutPtrRead> for Box<[R]> { } impl CType<&[Robust]> for &[R] { - type ReprC = SliceRef; + type ReprC = RefSlice; } -impl CTypeConvert<'_, &[Robust], SliceRef> for &[R] { +impl CTypeConvert<'_, &[Robust], RefSlice> for &[R] { type RustStore = (); type FfiStore = (); - fn into_repr_c(self, (): &mut ()) -> SliceRef { - SliceRef::from_slice(Some(self)) + fn into_repr_c(self, (): &mut ()) -> RefSlice { + RefSlice::from_slice(Some(self)) } - unsafe fn try_from_repr_c(source: SliceRef, (): &mut ()) -> Result { + unsafe fn try_from_repr_c(source: RefSlice, (): &mut ()) -> Result { source.into_rust().ok_or(FfiReturn::ArgIsNull) } } @@ -773,17 +853,17 @@ impl CWrapperType<&mut [Robust]> for &mut [R] { type ReturnType = Self; } impl CType<&mut [Robust]> for &mut [R] { - type ReprC = SliceMut; + type ReprC = RefMutSlice; } -impl CTypeConvert<'_, &mut [Robust], SliceMut> for &mut [R] { +impl CTypeConvert<'_, &mut [Robust], RefMutSlice> for &mut [R] { type RustStore = (); type FfiStore = (); - fn into_repr_c(self, (): &mut ()) -> SliceMut { - SliceMut::from_slice(Some(self)) + fn into_repr_c(self, (): &mut ()) -> RefMutSlice { + RefMutSlice::from_slice(Some(self)) } - unsafe fn try_from_repr_c(source: SliceMut, (): &mut ()) -> Result { + unsafe fn try_from_repr_c(source: RefMutSlice, (): &mut ()) -> Result { source.into_rust().ok_or(FfiReturn::ArgIsNull) } } @@ -803,18 +883,18 @@ impl COutPtrRead<&mut [Robust]> for &mut [R] { } impl CType> for Vec { - type ReprC = SliceMut; + type ReprC = RefMutSlice; } -impl CTypeConvert<'_, Vec, SliceMut> for Vec { - type RustStore = Self; +impl CTypeConvert<'_, Vec, RefMutSlice> for Vec { + type RustStore = Box<[R]>; type FfiStore = (); - fn into_repr_c(self, store: &mut Self::RustStore) -> SliceMut { - *store = self; - SliceMut::from_slice(Some(store)) + fn into_repr_c(self, store: &mut Self::RustStore) -> RefMutSlice { + *store = self.into_boxed_slice(); + RefMutSlice::from_slice(Some(store)) } - unsafe fn try_from_repr_c(source: SliceMut, (): &mut ()) -> Result { + unsafe fn try_from_repr_c(source: RefMutSlice, (): &mut ()) -> Result { source .into_rust() .ok_or(FfiReturn::ArgIsNull) @@ -831,14 +911,14 @@ impl COutPtr> for Vec { } impl COutPtrWrite> for Vec { unsafe fn write_out(self, out_ptr: *mut Self::OutPtr) { - let mut store = Vec::default(); + let mut store = Box::default(); CTypeConvert::, _>::into_repr_c(self, &mut store); - out_ptr.write(OutBoxedSlice::from_vec(Some(store))); + out_ptr.write(OutBoxedSlice::from_boxed_slice(Some(store))); } } impl COutPtrRead> for Vec { unsafe fn try_read_out(out_ptr: Self::OutPtr) -> Result { - let slice = SliceMut::from_raw_parts_mut(out_ptr.as_mut_ptr(), out_ptr.len()); + let slice = RefMutSlice::from_raw_parts_mut(out_ptr.as_mut_ptr(), out_ptr.len()); let res = CTypeConvert::, _>::try_from_repr_c(slice, &mut ()); if !out_ptr.deallocate() { @@ -916,23 +996,23 @@ impl COutPtrWrite> for Box { } impl CType> for Box<[R]> { - type ReprC = SliceMut<*mut R>; + type ReprC = RefMutSlice<*mut R>; } -impl CTypeConvert<'_, Box<[Opaque]>, SliceMut<*mut R>> for Box<[R]> { +impl CTypeConvert<'_, Box<[Opaque]>, RefMutSlice<*mut R>> for Box<[R]> { type RustStore = Box<[*mut R]>; type FfiStore = (); - fn into_repr_c(self, store: &mut Self::RustStore) -> SliceMut<*mut R> { + fn into_repr_c(self, store: &mut Self::RustStore) -> RefMutSlice<*mut R> { *store = Vec::from(self) .into_iter() - .map(|a: R| Box::new(a)) + .map(Box::new) .map(Box::into_raw) .collect(); - SliceMut::from_slice(Some(store)) + RefMutSlice::from_slice(Some(store)) } - unsafe fn try_from_repr_c(source: SliceMut<*mut R>, (): &mut ()) -> Result { + unsafe fn try_from_repr_c(source: RefMutSlice<*mut R>, (): &mut ()) -> Result { source .into_rust() .ok_or(FfiReturn::ArgIsNull)? @@ -960,21 +1040,21 @@ impl COutPtrWrite> for Box<[R]> { } impl CType<&[Opaque]> for &[R] { - type ReprC = SliceRef<*const R>; + type ReprC = RefSlice<*const R>; } -impl<'slice, R: Clone> CTypeConvert<'slice, &'slice [Opaque], SliceRef<*const R>> +impl<'slice, R: Clone> CTypeConvert<'slice, &'slice [Opaque], RefSlice<*const R>> for &'slice [R] { - type RustStore = Vec<*const R>; - type FfiStore = Vec; + type RustStore = Box<[*const R]>; + type FfiStore = Box<[R]>; - fn into_repr_c(self, store: &mut Self::RustStore) -> SliceRef<*const R> { + fn into_repr_c(self, store: &mut Self::RustStore) -> RefSlice<*const R> { *store = self.iter().map(|item| item as *const R).collect(); - SliceRef::from_slice(Some(store)) + RefSlice::from_slice(Some(store)) } unsafe fn try_from_repr_c( - source: SliceRef<*const R>, + source: RefSlice<*const R>, store: &'slice mut Self::FfiStore, ) -> Result { let source = source.into_rust().ok_or(FfiReturn::ArgIsNull)?; @@ -1000,27 +1080,29 @@ impl COutPtr<&[Opaque]> for &[R] { } impl COutPtrWrite<&[Opaque]> for &[R] { unsafe fn write_out(self, out_ptr: *mut Self::OutPtr) { - let mut store = Vec::default(); + let mut store = Box::default(); CTypeConvert::<&[Opaque], _>::into_repr_c(self, &mut store); - out_ptr.write(OutBoxedSlice::from_vec(Some(store))); + out_ptr.write(OutBoxedSlice::from_boxed_slice(Some(store))); } } impl CType<&mut [Opaque]> for &mut [R] { - type ReprC = SliceMut<*mut R>; + type ReprC = RefMutSlice<*mut R>; } -impl<'slice, R: Clone> CTypeConvert<'slice, &mut [Opaque], SliceMut<*mut R>> for &'slice mut [R] { - type RustStore = Vec<*mut R>; - type FfiStore = Vec; +impl<'slice, R: Clone> CTypeConvert<'slice, &mut [Opaque], RefMutSlice<*mut R>> + for &'slice mut [R] +{ + type RustStore = Box<[*mut R]>; + type FfiStore = Box<[R]>; - fn into_repr_c(self, store: &mut Self::RustStore) -> SliceMut<*mut R> { + fn into_repr_c(self, store: &mut Self::RustStore) -> RefMutSlice<*mut R> { *store = self.iter_mut().map(|item| item as *mut R).collect(); - SliceMut::from_slice(Some(store)) + RefMutSlice::from_slice(Some(store)) } unsafe fn try_from_repr_c( - source: SliceMut<*mut R>, + source: RefMutSlice<*mut R>, store: &'slice mut Self::FfiStore, ) -> Result { let source = source.into_rust().ok_or(FfiReturn::ArgIsNull)?; @@ -1046,25 +1128,25 @@ impl COutPtr<&mut [Opaque]> for &mut [R] { } impl COutPtrWrite<&mut [Opaque]> for &mut [R] { unsafe fn write_out(self, out_ptr: *mut Self::OutPtr) { - let mut store = Vec::default(); + let mut store = Box::default(); CTypeConvert::<&mut [Opaque], _>::into_repr_c(self, &mut store); - out_ptr.write(OutBoxedSlice::from_vec(Some(store))); + out_ptr.write(OutBoxedSlice::from_boxed_slice(Some(store))); } } impl CType> for Vec { - type ReprC = SliceMut<*mut R>; + type ReprC = RefMutSlice<*mut R>; } -impl CTypeConvert<'_, Vec, SliceMut<*mut R>> for Vec { - type RustStore = Vec<*mut R>; +impl CTypeConvert<'_, Vec, RefMutSlice<*mut R>> for Vec { + type RustStore = Box<[*mut R]>; type FfiStore = (); - fn into_repr_c(self, store: &mut Self::RustStore) -> SliceMut<*mut R> { + fn into_repr_c(self, store: &mut Self::RustStore) -> RefMutSlice<*mut R> { *store = self.into_iter().map(Box::new).map(Box::into_raw).collect(); - SliceMut::from_slice(Some(store)) + RefMutSlice::from_slice(Some(store)) } - unsafe fn try_from_repr_c(source: SliceMut<*mut R>, (): &mut ()) -> Result { + unsafe fn try_from_repr_c(source: RefMutSlice<*mut R>, (): &mut ()) -> Result { source .into_rust() .ok_or(FfiReturn::ArgIsNull)? @@ -1085,9 +1167,9 @@ impl COutPtr> for Vec { } impl COutPtrWrite> for Vec { unsafe fn write_out(self, out_ptr: *mut Self::OutPtr) { - let mut store = Vec::default(); + let mut store = Box::default(); CTypeConvert::, _>::into_repr_c(self, &mut store); - out_ptr.write(OutBoxedSlice::from_vec(Some(store))); + out_ptr.write(OutBoxedSlice::from_boxed_slice(Some(store))); } } @@ -1440,12 +1522,12 @@ where type FfiStore = <&'slice [R::Target] as FfiConvert<'slice, C>>::FfiStore; fn into_repr_c(self, store: &'slice mut Self::RustStore) -> C { - transmute_into_target_slice_ref(self).into_ffi(store) + transmute_into_target_ref_slice(self).into_ffi(store) } unsafe fn try_from_repr_c(source: C, store: &'slice mut Self::FfiStore) -> Result { let slice = <&[R::Target]>::try_from_ffi(source, store)?; - transmute_from_target_slice_ref(slice) + transmute_from_target_ref_slice(slice) } } @@ -1471,7 +1553,7 @@ where &'slice [R::Target]: FfiOutPtrWrite, { unsafe fn write_out(self, out_ptr: *mut Self::OutPtr) { - FfiOutPtrWrite::write_out(transmute_into_target_slice_ref(self), out_ptr); + FfiOutPtrWrite::write_out(transmute_into_target_ref_slice(self), out_ptr); } } impl<'itm, R: Transmute> COutPtrRead<&'itm [Transparent]> for &'itm [R] @@ -1480,7 +1562,7 @@ where { unsafe fn try_read_out(out_ptr: Self::OutPtr) -> Result { <&[R::Target]>::try_read_out(out_ptr) - .and_then(|output| transmute_from_target_slice_ref(output)) + .and_then(|output| transmute_from_target_ref_slice(output)) } } @@ -1687,12 +1769,12 @@ unsafe fn transmute_from_target_boxed_slice( ))) } -fn transmute_into_target_slice_ref(source: &[R]) -> &[R::Target] { +fn transmute_into_target_ref_slice(source: &[R]) -> &[R::Target] { let (ptr, len) = (source.as_ptr().cast::(), source.len()); // SAFETY: `R` is guaranteed to be transmutable into `R::Target` unsafe { core::slice::from_raw_parts(ptr, len) } } -unsafe fn transmute_from_target_slice_ref(source: &[R::Target]) -> Result<&[R]> { +unsafe fn transmute_from_target_ref_slice(source: &[R::Target]) -> Result<&[R]> { if !source.iter().all(|item| R::is_valid(item)) { return Err(FfiReturn::TrapRepresentation); } diff --git a/ffi/src/slice.rs b/ffi/src/slice.rs index 8c3edfc9b8e..e47674cca94 100644 --- a/ffi/src/slice.rs +++ b/ffi/src/slice.rs @@ -11,13 +11,13 @@ crate::decl_ffi_fns! { dealloc } /// If the data pointer is set to `null`, the struct represents `Option<&[C]>`. #[repr(C)] #[derive(Debug)] -pub struct SliceRef(*const C, usize); +pub struct RefSlice(*const C, usize); /// Mutable slice `&mut [C]` with a defined C ABI layout. Consists of a data pointer and a length. /// If the data pointer is set to `null`, the struct represents `Option<&mut [C]>`. #[repr(C)] #[derive(Debug)] -pub struct SliceMut(*mut C, usize); +pub struct RefMutSlice(*mut C, usize); /// Owned slice `Box<[C]>` with a defined C ABI layout. Consists of a data pointer and a length. /// Used in place of a function out-pointer to transfer ownership of the slice to the caller. @@ -26,14 +26,14 @@ pub struct SliceMut(*mut C, usize); #[derive(Debug)] pub struct OutBoxedSlice(*mut C, usize); -impl Copy for SliceRef {} -impl Clone for SliceRef { +impl Copy for RefSlice {} +impl Clone for RefSlice { fn clone(&self) -> Self { *self } } -impl Copy for SliceMut {} -impl Clone for SliceMut { +impl Copy for RefMutSlice {} +impl Clone for RefMutSlice { fn clone(&self) -> Self { *self } @@ -45,7 +45,7 @@ impl Clone for OutBoxedSlice { } } -impl SliceRef { +impl RefSlice { /// Set the slice's data pointer to null pub const fn null() -> Self { // TODO: len could be uninitialized @@ -95,7 +95,7 @@ impl SliceRef { Some(slice::from_raw_parts(self.0, self.1)) } } -impl SliceMut { +impl RefMutSlice { /// Set the slice's data pointer to null pub const fn null_mut() -> Self { // TODO: len could be uninitialized @@ -165,7 +165,7 @@ impl OutBoxedSlice { self.1 } - /// Create [`Self`] from a `Box<[T]>` + /// Create [`Self`] from a [`Box<[T]>`] pub fn from_boxed_slice(source: Option>) -> Self { source.map_or_else( || Self(core::ptr::null_mut(), 0), @@ -176,17 +176,6 @@ impl OutBoxedSlice { ) } - /// Create [`Self`] from a `Vec` - pub fn from_vec(source: Option>) -> Self { - source.map_or_else( - || Self(core::ptr::null_mut(), 0), - |boxed_slice| { - let mut boxed_slice = core::mem::ManuallyDrop::new(boxed_slice.into_boxed_slice()); - Self(boxed_slice.as_mut_ptr(), boxed_slice.len()) - }, - ) - } - /// Create a `Vec` directly from the raw components of another vector. /// Unlike [`Vec::from_raw_parts`], data pointer is allowed to be null. /// @@ -218,8 +207,8 @@ impl OutBoxedSlice { } // SAFETY: Robust type with a defined C ABI -unsafe impl ReprC for SliceRef {} +unsafe impl ReprC for RefSlice {} // SAFETY: Robust type with a defined C ABI -unsafe impl ReprC for SliceMut {} +unsafe impl ReprC for RefMutSlice {} // SAFETY: Robust type with a defined C ABI unsafe impl ReprC for OutBoxedSlice {} diff --git a/ffi/src/std_impls.rs b/ffi/src/std_impls.rs index ee579c75fcb..04d9f0e4a48 100644 --- a/ffi/src/std_impls.rs +++ b/ffi/src/std_impls.rs @@ -1,12 +1,9 @@ -// Triggered by `&mut str` expansion -#![allow(clippy::mut_mut, single_use_lifetimes)] - -use alloc::{string::String, vec::Vec}; +use alloc::{boxed::Box, string::String, vec::Vec}; use core::{mem::ManuallyDrop, ptr::NonNull}; use crate::{ ffi_type, - slice::{SliceMut, SliceRef}, + slice::{RefMutSlice, RefSlice}, ReprC, WrapperTypeOf, }; @@ -18,17 +15,25 @@ ffi_type! { type Target = Vec; validation_fn=unsafe {|target| core::str::from_utf8(target).is_ok()}, - niche_value=SliceMut::null_mut() + niche_value=RefMutSlice::null_mut() } } // NOTE: `core::str::as_bytes` uses transmute internally which means that // even though it's a string slice it can be transmuted into byte slice. +ffi_type! { + unsafe impl Transparent for Box { + type Target = Box<[u8]>; + + validation_fn=unsafe {|target| core::str::from_utf8(target).is_ok()}, + niche_value=RefMutSlice::null_mut() + } +} ffi_type! { unsafe impl<'slice> Transparent for &'slice str { type Target = &'slice [u8]; validation_fn=unsafe {|target| core::str::from_utf8(target).is_ok()}, - niche_value=SliceRef::null() + niche_value=RefSlice::null() } } #[cfg(feature = "non_robust_ref_mut")] @@ -37,7 +42,7 @@ ffi_type! { type Target = &'slice mut [u8]; validation_fn=unsafe {|target| core::str::from_utf8(target).is_ok()}, - niche_value=SliceMut::null_mut() + niche_value=RefMutSlice::null_mut() } } ffi_type! { diff --git a/ffi/tests/export_shared_fns.rs b/ffi/tests/export_shared_fns.rs index b254c657d42..49a09691c5e 100644 --- a/ffi/tests/export_shared_fns.rs +++ b/ffi/tests/export_shared_fns.rs @@ -42,7 +42,7 @@ fn export_shared_fns() { let ffi_struct1 = unsafe { let mut ffi_struct = MaybeUninit::new(core::ptr::null_mut()); - let mut store = Vec::new(); + let mut store = Box::default(); assert_eq! {FfiReturn::Ok, FfiStruct1__new(FfiConvert::into_ffi(name.clone(), &mut store), ffi_struct.as_mut_ptr())}; let ffi_struct = ffi_struct.assume_init(); assert!(!ffi_struct.is_null()); diff --git a/ffi/tests/ffi_export.rs b/ffi/tests/ffi_export.rs index da6ebaa4d20..a9d6ee3cabd 100644 --- a/ffi/tests/ffi_export.rs +++ b/ffi/tests/ffi_export.rs @@ -290,12 +290,12 @@ fn get_new_struct_with_params() -> OpaqueStruct { #[webassembly_test::webassembly_test] #[cfg(feature = "non_robust_ref_mut")] fn non_robust_ref_mut() { - use iroha_ffi::slice::SliceMut; + use iroha_ffi::slice::RefMutSlice; let mut owned = "queen".to_owned(); let ffi_struct: &mut str = owned.as_mut(); - let mut output = MaybeUninit::new(SliceMut::from_raw_parts_mut(core::ptr::null_mut(), 0)); - let ffi_type: SliceMut = FfiConvert::into_ffi(ffi_struct, &mut ()); + let mut output = MaybeUninit::new(RefMutSlice::from_raw_parts_mut(core::ptr::null_mut(), 0)); + let ffi_type: RefMutSlice = FfiConvert::into_ffi(ffi_struct, &mut ()); unsafe { assert_eq!( @@ -350,7 +350,7 @@ fn into_iter_item_impl_into() { ]; let mut ffi_struct = get_new_struct(); - let mut tokens_store = Vec::default(); + let mut tokens_store = Box::default(); let tokens_ffi = tokens.clone().into_ffi(&mut tokens_store); let mut output = MaybeUninit::new(core::ptr::null_mut()); diff --git a/ffi/tests/ffi_import.rs b/ffi/tests/ffi_import.rs index 4d560620ad9..7be795cf684 100644 --- a/ffi/tests/ffi_import.rs +++ b/ffi/tests/ffi_import.rs @@ -131,7 +131,7 @@ mod ffi { use std::alloc; use iroha_ffi::{ - slice::{OutBoxedSlice, SliceMut, SliceRef}, + slice::{OutBoxedSlice, RefMutSlice, RefSlice}, FfiOutPtr, FfiReturn, FfiTuple2, FfiType, }; @@ -157,17 +157,17 @@ mod ffi { #[no_mangle] unsafe extern "C" fn __freestanding_returns_local_slice( - input: SliceRef>, + input: RefSlice>, output: *mut OutBoxedSlice>, ) -> FfiReturn { - let input = input.into_rust().map(<[_]>::to_vec); - output.write(OutBoxedSlice::from_vec(input)); + let input = input.into_rust().map(Into::into); + output.write(OutBoxedSlice::from_boxed_slice(input)); FfiReturn::Ok } #[no_mangle] unsafe extern "C" fn __freestanding_returns_boxed_slice( - input: SliceMut, + input: RefMutSlice, output: *mut OutBoxedSlice, ) -> FfiReturn { let input = input.into_rust().map(|slice| (&*slice).into()); @@ -177,11 +177,11 @@ mod ffi { #[no_mangle] unsafe extern "C" fn __freestanding_returns_iterator( - input: SliceMut, + input: RefMutSlice, output: *mut OutBoxedSlice, ) -> FfiReturn { - let input = input.into_rust().map(|slice| slice.to_vec()); - output.write(OutBoxedSlice::from_vec(input)); + let input = input.into_rust().map(|slice| (&*slice).into()); + output.write(OutBoxedSlice::from_boxed_slice(input)); FfiReturn::Ok } diff --git a/ffi/tests/ffi_import_opaque.rs b/ffi/tests/ffi_import_opaque.rs index c9ffe7c4fb4..6b1be273f54 100644 --- a/ffi/tests/ffi_import_opaque.rs +++ b/ffi/tests/ffi_import_opaque.rs @@ -144,7 +144,7 @@ mod ffi { use std::{alloc, collections::BTreeMap}; use iroha_ffi::{ - def_ffi_fns, slice::SliceMut, FfiConvert, FfiOutPtr, FfiOutPtrWrite, FfiReturn, FfiType, + def_ffi_fns, slice::RefMutSlice, FfiConvert, FfiOutPtr, FfiOutPtrWrite, FfiReturn, FfiType, }; iroha_ffi::handles! {ExternOpaqueStruct, ExternValue} @@ -175,7 +175,7 @@ mod ffi { #[no_mangle] unsafe extern "C" fn Value__new( - input: SliceMut, + input: RefMutSlice, output: *mut *mut ExternValue, ) -> FfiReturn { let string = String::from_utf8(input.into_rust().expect("Defined").to_vec()); @@ -205,7 +205,7 @@ mod ffi { output: *mut *mut ExternOpaqueStruct, ) -> iroha_ffi::FfiReturn { let mut handle = *Box::from_raw(handle); - let mut store = Vec::default(); + let mut store = Box::default(); let params: Vec<(u8, ExternValue)> = FfiConvert::try_from_ffi(params, &mut store).expect("Valid"); handle.params = params.into_iter().collect(); diff --git a/ffi/tests/import_getset.rs b/ffi/tests/import_getset.rs index 56d5a733dae..1fa1a74a5b2 100644 --- a/ffi/tests/import_getset.rs +++ b/ffi/tests/import_getset.rs @@ -55,7 +55,7 @@ mod ffi { use std::alloc; use iroha_ffi::{ - def_ffi_fns, slice::SliceMut, FfiConvert, FfiOutPtr, FfiOutPtrWrite, FfiReturn, FfiType, + def_ffi_fns, slice::RefMutSlice, FfiConvert, FfiOutPtr, FfiOutPtrWrite, FfiReturn, FfiType, }; iroha_ffi::handles! {ExternName, ExternFfiStruct} @@ -84,7 +84,7 @@ mod ffi { #[no_mangle] unsafe extern "C" fn Name__new( - input1: SliceMut, + input1: RefMutSlice, output: *mut *mut ExternName, ) -> FfiReturn { let string = String::from_utf8(input1.into_rust().expect("Defined").to_vec()); @@ -95,7 +95,7 @@ mod ffi { #[no_mangle] unsafe extern "C" fn FfiStruct__new( - input1: SliceMut, + input1: RefMutSlice, input2: ::ReprC, output: *mut *mut ExternFfiStruct, ) -> FfiReturn { diff --git a/ffi/tests/import_shared_fns.rs b/ffi/tests/import_shared_fns.rs index cab3d5fd658..00210ef790e 100644 --- a/ffi/tests/import_shared_fns.rs +++ b/ffi/tests/import_shared_fns.rs @@ -35,7 +35,7 @@ fn import_shared_fns() { mod ffi { use std::alloc; - use iroha_ffi::{def_ffi_fns, slice::SliceMut, FfiReturn, FfiType}; + use iroha_ffi::{def_ffi_fns, slice::RefMutSlice, FfiReturn, FfiType}; iroha_ffi::handles! {ExternFfiStruct} @@ -56,7 +56,7 @@ mod ffi { #[no_mangle] unsafe extern "C" fn FfiStruct__new( - input: SliceMut, + input: RefMutSlice, output: *mut *mut ExternFfiStruct, ) -> FfiReturn { let string = String::from_utf8(input.into_rust().expect("Defined").to_vec()); diff --git a/ffi/tests/transparent.rs b/ffi/tests/transparent.rs index 01f93912add..49f6efd8d55 100644 --- a/ffi/tests/transparent.rs +++ b/ffi/tests/transparent.rs @@ -4,7 +4,7 @@ use std::{alloc, marker::PhantomData, mem::MaybeUninit}; use iroha_ffi::{ ffi_export, - slice::{OutBoxedSlice, SliceRef}, + slice::{OutBoxedSlice, RefSlice}, FfiConvert, FfiOutPtrRead, FfiReturn, FfiType, }; @@ -168,7 +168,7 @@ fn transparent_vec_to_vec() { TransparentStruct::new(GenericTransparentStruct::new(3)), ]; - let mut store = Vec::default(); + let mut store = Box::default(); let mut output = MaybeUninit::new(OutBoxedSlice::from_raw_parts(core::ptr::null_mut(), 0)); unsafe { @@ -196,7 +196,7 @@ fn transparent_slice_to_slice() { TransparentStruct::new(GenericTransparentStruct::new(2)), TransparentStruct::new(GenericTransparentStruct::new(3)), ]; - let mut output = MaybeUninit::new(SliceRef::from_raw_parts(core::ptr::null(), 0)); + let mut output = MaybeUninit::new(RefSlice::from_raw_parts(core::ptr::null(), 0)); unsafe { assert_eq!(