@@ -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
@@ -639,10 +639,10 @@ mod enabled {
639639
640640 type ListStorage < T > = ( * mut T , Box < [ T ] > ) ;
641641
642- #[ derive( Default ) ]
642+ #[ derive( Default , Debug ) ]
643643 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 > > > ,
646646 args : Vec < Arg > ,
647647 }
648648
@@ -652,118 +652,79 @@ mod enabled {
652652 self . args . pop ( ) . unwrap ( ) ;
653653 self . other_data . push ( self . arg_data . pop ( ) . unwrap ( ) ) ;
654654 }
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 ( ) ;
658658 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) ) ;
671662 ptr as * mut ( )
672663 }
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) ) ;
680668 }
681669 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 ( )
690675 }
691676 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 ( )
701682 }
702683 fn push_repr_ptr ( & mut self , mut arg : Vec < u8 > ) -> * mut ( ) {
703684 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) ) ;
716688 ptr as * mut ( )
717689 }
718690 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 )
725697 }
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 {
727699 let ptr = if arg. is_empty ( ) {
700+ // TODO: is this special case necessary?
728701 ptr:: null_mut ( )
729702 } else {
730- & mut arg[ 0 ] as * mut T
703+ arg. as_mut_ptr ( )
731704 } ;
732705 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) ) ;
746710 ptr
747711 }
748712 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
757723 }
758724 fn get_maybe_null < T : Any > ( & self , index : usize ) -> Option < ( & T , Option < * mut T > ) > {
759725 self . try_get ( index)
760726 . 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 ) )
767728 . unwrap_or_else ( || {
768729 panic ! (
769730 "Value wasn't expected type {}, {}, {}, or {}" ,
@@ -775,47 +736,45 @@ mod enabled {
775736 } )
776737 }
777738 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)
780740 . map ( |t| {
781741 dbgln ! ( " exact type" ) ;
782742 ( t, None )
783743 } )
784744 . or_else ( || {
785- any . downcast_ref :: < ( * mut T , Box < T > ) > ( ) . map ( |( p, _) | {
745+ self . try_get_as :: < ( * mut T , Box < T > ) > ( index ) . map ( |( p, _) | {
786746 dbgln ! ( " ptr type" ) ;
787- ( unsafe { & * * p } , Some ( * p) )
747+ // SAFETY: TODO
748+ ( unsafe { p. as_ref ( ) . unwrap_unchecked ( ) } , Some ( * p) )
788749 } )
789750 } )
790751 . or_else ( || {
791- any . downcast_ref :: < ListStorage < T > > ( ) . map ( |( _, b) | {
752+ self . try_get_as :: < ListStorage < T > > ( index ) . map ( |( _, b) | {
792753 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 ) )
794755 } )
795756 } )
796757 }
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) ;
806774 ( * ptr, vec)
807775 }
808776 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 ( )
819778 }
820779
821780 fn bind_arg ( & mut self , i : usize , ty : & FfiType , val : & Value ) -> Result < * mut ( ) , String > {
0 commit comments