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