@@ -222,7 +222,7 @@ pub(crate) use enabled::*;
222222mod enabled {
223223 use std:: {
224224 any:: { type_name, Any } ,
225- mem:: { forget, take, transmute} ,
225+ mem:: { forget, take, transmute, ManuallyDrop } ,
226226 ptr, slice,
227227 } ;
228228
@@ -641,10 +641,10 @@ mod enabled {
641641
642642 type ListStorage < T > = ( * mut T , Box < [ T ] > ) ;
643643
644- #[ derive( Default ) ]
644+ #[ derive( Default , Debug ) ]
645645 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 > > > ,
648648 args : Vec < Arg > ,
649649 }
650650
@@ -654,118 +654,79 @@ mod enabled {
654654 self . args . pop ( ) . unwrap ( ) ;
655655 self . other_data . push ( self . arg_data . pop ( ) . unwrap ( ) ) ;
656656 }
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 ( ) ;
660660 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) ) ;
673664 ptr as * mut ( )
674665 }
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) ) ;
682670 }
683671 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 ( )
692677 }
693678 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 ( )
703684 }
704685 fn push_repr_ptr ( & mut self , mut arg : Vec < u8 > ) -> * mut ( ) {
705686 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) ) ;
718690 ptr as * mut ( )
719691 }
720692 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 )
727699 }
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 {
729701 let ptr = if arg. is_empty ( ) {
702+ // TODO: is this special case necessary?
730703 ptr:: null_mut ( )
731704 } else {
732- & mut arg[ 0 ] as * mut T
705+ arg. as_mut_ptr ( )
733706 } ;
734707 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) ) ;
748712 ptr
749713 }
750714 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
759725 }
760726 fn get_maybe_null < T : Any > ( & self , index : usize ) -> Option < ( & T , Option < * mut T > ) > {
761727 self . try_get ( index)
762728 . 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 ) )
769730 . unwrap_or_else ( || {
770731 panic ! (
771732 "Value wasn't expected type {}, {}, {}, or {}" ,
@@ -777,47 +738,45 @@ mod enabled {
777738 } )
778739 }
779740 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)
782742 . map ( |t| {
783743 dbgln ! ( " exact type" ) ;
784744 ( t, None )
785745 } )
786746 . or_else ( || {
787- any . downcast_ref :: < ( * mut T , Box < T > ) > ( ) . map ( |( p, _) | {
747+ self . try_get_as :: < ( * mut T , Box < T > ) > ( index ) . map ( |( p, _) | {
788748 dbgln ! ( " ptr type" ) ;
789- ( unsafe { & * * p } , Some ( * p) )
749+ // SAFETY: TODO
750+ ( unsafe { p. as_ref ( ) . unwrap_unchecked ( ) } , Some ( * p) )
790751 } )
791752 } )
792753 . or_else ( || {
793- any . downcast_ref :: < ListStorage < T > > ( ) . map ( |( _, b) | {
754+ self . try_get_as :: < ListStorage < T > > ( index ) . map ( |( _, b) | {
794755 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 ) )
796757 } )
797758 } )
798759 }
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) ;
808776 ( * ptr, vec)
809777 }
810778 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 ( )
821780 }
822781
823782 fn bind_arg ( & mut self , i : usize , ty : & FfiType , val : & Value ) -> Result < * mut ( ) , String > {
0 commit comments