@@ -222,7 +222,7 @@ pub(crate) use enabled::*;
222
222
mod enabled {
223
223
use std:: {
224
224
any:: { type_name, Any } ,
225
- mem:: { forget, take, transmute} ,
225
+ mem:: { forget, take, transmute, ManuallyDrop } ,
226
226
ptr, slice,
227
227
} ;
228
228
@@ -641,10 +641,10 @@ mod enabled {
641
641
642
642
type ListStorage < T > = ( * mut T , Box < [ T ] > ) ;
643
643
644
- #[ derive( Default ) ]
644
+ #[ derive( Default , Debug ) ]
645
645
struct FfiBindings {
646
- arg_data : Vec < Box < dyn Any > > ,
647
- other_data : Vec < Box < dyn Any > > ,
646
+ arg_data : Vec < ManuallyDrop < Box < dyn Any > > > ,
647
+ other_data : Vec < ManuallyDrop < Box < dyn Any > > > ,
648
648
args : Vec < Arg > ,
649
649
}
650
650
@@ -654,118 +654,79 @@ mod enabled {
654
654
self . args . pop ( ) . unwrap ( ) ;
655
655
self . other_data . push ( self . arg_data . pop ( ) . unwrap ( ) ) ;
656
656
}
657
- fn alloc_and_push_ptr_to < T : Any + Copy + std :: fmt :: Debug > ( & mut self , arg : T ) -> * mut ( ) {
658
- let mut bx = Box :: < T > :: new ( arg) ;
659
- let ptr: * mut T = & mut * bx ;
657
+ fn alloc_and_push_ptr_to < T : Any > ( & mut self , arg : T ) -> * mut ( ) {
658
+ let mut arg = Box :: new ( arg) ;
659
+ let ptr: * mut T = arg . as_mut ( ) ;
660
660
dbgln ! ( " create *mut {}: {ptr:p}" , type_name:: <T >( ) ) ;
661
- self . arg_data . push ( Box :: new ( ( ptr, bx) ) ) ;
662
- self . args . push ( Arg :: new (
663
- & ( self . arg_data . last ( ) . unwrap ( ) )
664
- . downcast_ref :: < ( * mut T , Box < T > ) > ( )
665
- . unwrap_or_else ( || {
666
- panic ! (
667
- "Value wasn't expected type {}" ,
668
- type_name:: <( * mut T , Box <T >) >( )
669
- )
670
- } )
671
- . 0 ,
672
- ) ) ;
661
+ let pair = Box :: new ( ( ptr, arg) ) ;
662
+ self . args . push ( Arg :: new ( & pair. 0 ) ) ;
663
+ self . arg_data . push ( ManuallyDrop :: new ( pair) ) ;
673
664
ptr as * mut ( )
674
665
}
675
- fn push_raw_ptr < T : ' static > ( & mut self , ptr : * mut T ) {
676
- self . arg_data . push ( Box :: new ( ptr) ) ;
677
- self . args . push ( Arg :: new (
678
- ( self . arg_data . last ( ) . unwrap ( ) . downcast_ref :: < * mut T > ( ) ) . unwrap_or_else ( || {
679
- panic ! ( "Value wasn't expected type {}" , type_name:: <* mut T >( ) )
680
- } ) ,
681
- ) ) ;
666
+ fn push_raw_ptr < T : Any > ( & mut self , ptr : * mut T ) {
667
+ let value = Box :: new ( ptr) ;
668
+ self . args . push ( Arg :: new ( value. as_ref ( ) ) ) ;
669
+ self . arg_data . push ( ManuallyDrop :: new ( value) ) ;
682
670
}
683
671
fn push_value < T : Any > ( & mut self , arg : T ) -> * mut ( ) {
684
- self . arg_data . push ( Box :: new ( arg) ) ;
685
- self . args . push ( Arg :: new (
686
- ( self . arg_data . last ( ) . unwrap ( ) . downcast_ref :: < T > ( ) )
687
- . unwrap_or_else ( || panic ! ( "Value wasn't expected type {}" , type_name:: <T >( ) ) ) ,
688
- ) ) ;
689
- ( self . arg_data . last ( ) . unwrap ( ) . downcast_ref :: < T > ( ) )
690
- . unwrap_or_else ( || panic ! ( "Value wasn't expected type {}" , type_name:: <T >( ) ) )
691
- as * const T as * mut ( )
672
+ let value = Box :: new ( arg) ;
673
+ let ptr = value. as_ref ( ) as * const T as * mut ( ) ;
674
+ self . args . push ( Arg :: new ( value. as_ref ( ) ) ) ;
675
+ self . arg_data . push ( ManuallyDrop :: new ( value) ) ;
676
+ ptr as * const T as * mut ( )
692
677
}
693
678
fn push_repr ( & mut self , arg : Vec < u8 > ) -> * mut ( ) {
694
- self . arg_data . push ( Box :: new ( arg) ) ;
695
- self . args . push ( Arg :: new (
696
- & ( self . arg_data . last ( ) . unwrap ( ) )
697
- . downcast_ref :: < Vec < u8 > > ( )
698
- . unwrap ( ) [ 0 ] ,
699
- ) ) ;
700
- ( self . arg_data . last ( ) . unwrap ( ) . downcast_ref :: < Vec < u8 > > ( ) )
701
- . unwrap_or_else ( || panic ! ( "Value wasn't expected type {}" , type_name:: <Vec <u8 >>( ) ) )
702
- . as_ptr ( ) as * mut ( )
679
+ let value = Box :: new ( arg) ;
680
+ self . args . push ( Arg :: new ( & value[ 0 ] ) ) ;
681
+ let ptr = value. as_ref ( ) . as_ptr ( ) ;
682
+ self . arg_data . push ( ManuallyDrop :: new ( value) ) ;
683
+ ptr as * mut ( )
703
684
}
704
685
fn push_repr_ptr ( & mut self , mut arg : Vec < u8 > ) -> * mut ( ) {
705
686
let ptr = arg. as_mut_ptr ( ) ;
706
- self . arg_data . push ( Box :: new ( ( ptr, arg) ) ) ;
707
- self . args . push ( Arg :: new (
708
- & ( self . arg_data . last ( ) . unwrap ( ) )
709
- . downcast_ref :: < ( * mut u8 , Vec < u8 > ) > ( )
710
- . unwrap_or_else ( || {
711
- panic ! (
712
- "Value wasn't expected type {}" ,
713
- type_name:: <( * mut u8 , Vec <u8 >) >( )
714
- )
715
- } )
716
- . 0 ,
717
- ) ) ;
687
+ let pair = Box :: new ( ( ptr, arg) ) ;
688
+ self . args . push ( Arg :: new ( & pair. 0 ) ) ;
689
+ self . arg_data . push ( ManuallyDrop :: new ( pair) ) ;
718
690
ptr as * mut ( )
719
691
}
720
692
fn push_string ( & mut self , arg : String ) -> * mut c_char {
721
- let list : Box < [ c_char ] > = arg
722
- . chars ( )
723
- . map ( |c| c as c_char )
724
- . chain ( [ '\0' as c_char ] )
725
- . collect ( ) ;
726
- self . push_list :: < c_char > ( list )
693
+ let arg = CString :: new ( arg) . expect ( "string should not contain NUL" ) ;
694
+ let ptr = Box :: into_raw ( arg . into_bytes_with_nul ( ) . into_boxed_slice ( ) ) ;
695
+ // SAFETY: the pointer was created using `Box::into_raw`
696
+ // and `[i8]` is compatible with `[u8]`
697
+ let arg = unsafe { Box :: from_raw ( ptr as * mut [ c_char ] ) } ;
698
+ self . push_list ( arg )
727
699
}
728
- fn push_list < T : Any + ' static > ( & mut self , mut arg : Box < [ T ] > ) -> * mut T {
700
+ fn push_list < T : Any > ( & mut self , mut arg : Box < [ T ] > ) -> * mut T {
729
701
let ptr = if arg. is_empty ( ) {
702
+ // TODO: is this special case necessary?
730
703
ptr:: null_mut ( )
731
704
} else {
732
- & mut arg[ 0 ] as * mut T
705
+ arg. as_mut_ptr ( )
733
706
} ;
734
707
dbgln ! ( " create *mut {}: {ptr:p}" , type_name:: <T >( ) ) ;
735
- let storage = ( ptr, arg) ;
736
- self . arg_data . push ( Box :: new ( storage) ) ;
737
- self . args . push ( Arg :: new (
738
- & ( self . arg_data . last_mut ( ) . unwrap ( ) )
739
- . downcast_mut :: < ListStorage < T > > ( )
740
- . unwrap_or_else ( || {
741
- panic ! (
742
- "Value wasn't expected type {}" ,
743
- type_name:: <ListStorage <T >>( )
744
- )
745
- } )
746
- . 0 ,
747
- ) ) ;
708
+ let storage: ListStorage < _ > = ( ptr, arg) ;
709
+ let value = Box :: new ( storage) ;
710
+ self . args . push ( Arg :: new ( & value. 0 ) ) ;
711
+ self . arg_data . push ( ManuallyDrop :: new ( value) ) ;
748
712
ptr
749
713
}
750
714
fn get < T : Any > ( & self , index : usize ) -> & T {
751
- self . try_get ( index) . map ( |( t, _) | t) . unwrap_or_else ( || {
752
- panic ! (
753
- "Value wasn't expected type {}, {}, or {}" ,
754
- type_name:: <T >( ) ,
755
- type_name:: <( * mut T , Box <T >) >( ) ,
756
- type_name:: <ListStorage <T >>( )
757
- )
758
- } )
715
+ self . try_get ( index)
716
+ . unwrap_or_else ( || {
717
+ panic ! (
718
+ "Value wasn't expected type {}, {}, or {}" ,
719
+ type_name:: <T >( ) ,
720
+ type_name:: <( * mut T , Box <T >) >( ) ,
721
+ type_name:: <ListStorage <T >>( )
722
+ )
723
+ } )
724
+ . 0
759
725
}
760
726
fn get_maybe_null < T : Any > ( & self , index : usize ) -> Option < ( & T , Option < * mut T > ) > {
761
727
self . try_get ( index)
762
728
. map ( Some )
763
- . or_else ( || {
764
- self . arg_data [ index]
765
- . downcast_ref :: < * mut ( ) > ( )
766
- . is_some ( )
767
- . then_some ( None )
768
- } )
729
+ . or_else ( || self . arg_data [ index] . is :: < * mut ( ) > ( ) . then_some ( None ) )
769
730
. unwrap_or_else ( || {
770
731
panic ! (
771
732
"Value wasn't expected type {}, {}, {}, or {}" ,
@@ -777,47 +738,45 @@ mod enabled {
777
738
} )
778
739
}
779
740
fn try_get < T : Any > ( & self , index : usize ) -> Option < ( & T , Option < * mut T > ) > {
780
- let any = & self . arg_data [ index] ;
781
- any. downcast_ref :: < T > ( )
741
+ self . try_get_as :: < T > ( index)
782
742
. map ( |t| {
783
743
dbgln ! ( " exact type" ) ;
784
744
( t, None )
785
745
} )
786
746
. or_else ( || {
787
- any . downcast_ref :: < ( * mut T , Box < T > ) > ( ) . map ( |( p, _) | {
747
+ self . try_get_as :: < ( * mut T , Box < T > ) > ( index ) . map ( |( p, _) | {
788
748
dbgln ! ( " ptr type" ) ;
789
- ( unsafe { & * * p } , Some ( * p) )
749
+ // SAFETY: TODO
750
+ ( unsafe { p. as_ref ( ) . unwrap_unchecked ( ) } , Some ( * p) )
790
751
} )
791
752
} )
792
753
. or_else ( || {
793
- any . downcast_ref :: < ListStorage < T > > ( ) . map ( |( _, b) | {
754
+ self . try_get_as :: < ListStorage < T > > ( index ) . map ( |( _, b) | {
794
755
dbgln ! ( " list type" ) ;
795
- ( & b[ 0 ] , Some ( & b [ 0 ] as * const T as * mut T ) )
756
+ ( & b[ 0 ] , Some ( b . as_ref ( ) . as_ptr ( ) as * mut T ) )
796
757
} )
797
758
} )
798
759
}
799
- fn get_list_mut < T : ' static > ( & mut self , index : usize ) -> ( * mut T , & mut Box < [ T ] > ) {
800
- let ( ptr, vec) = self . arg_data [ index]
801
- . downcast_mut :: < ListStorage < T > > ( )
802
- . unwrap_or_else ( || {
803
- panic ! (
804
- "Value wasn't expected type {}" ,
805
- type_name:: <ListStorage <T >>( )
806
- )
807
- } ) ;
760
+ fn get_as_mut < T : Any > ( & mut self , index : usize ) -> & mut T {
761
+ self . try_get_as_mut ( index)
762
+ . unwrap_or_else ( || panic ! ( "Value wasn't expected type {}" , type_name:: <T >( ) ) )
763
+ }
764
+ fn get_as < T : Any > ( & self , index : usize ) -> & T {
765
+ self . try_get_as ( index)
766
+ . unwrap_or_else ( || panic ! ( "Value wasn't expected type {}" , type_name:: <T >( ) ) )
767
+ }
768
+ fn try_get_as_mut < T : Any > ( & mut self , index : usize ) -> Option < & mut T > {
769
+ self . arg_data [ index] . downcast_mut ( )
770
+ }
771
+ fn try_get_as < T : Any > ( & self , index : usize ) -> Option < & T > {
772
+ self . arg_data [ index] . downcast_ref ( )
773
+ }
774
+ fn get_list_mut < T : Any > ( & mut self , index : usize ) -> ( * mut T , & mut Box < [ T ] > ) {
775
+ let ( ptr, vec) = self . get_as_mut :: < ListStorage < T > > ( index) ;
808
776
( * ptr, vec)
809
777
}
810
778
fn get_repr ( & self , index : usize ) -> & [ u8 ] {
811
- self . arg_data [ index]
812
- . downcast_ref :: < ( * mut u8 , Vec < u8 > ) > ( )
813
- . unwrap_or_else ( || {
814
- panic ! (
815
- "Value wasn't expected type {}" ,
816
- type_name:: <( * mut u8 , Vec <u8 >) >( )
817
- )
818
- } )
819
- . 1
820
- . as_slice ( )
779
+ self . get_as :: < ( * mut u8 , Vec < u8 > ) > ( index) . 1 . as_slice ( )
821
780
}
822
781
823
782
fn bind_arg ( & mut self , i : usize , ty : & FfiType , val : & Value ) -> Result < * mut ( ) , String > {
0 commit comments