@@ -43,10 +43,27 @@ pub enum StrongPtr<T> {
4343 byte_offset : usize ,
4444 // Local buffer for deref(). None until first access.
4545 // Read-through: refreshed from alloc on every deref() call.
46- cell : RefCell < Option < T > > ,
46+ cell : RefCell < Option < Vec < T > > > ,
4747 } ,
4848}
4949
50+ fn read_reinterpreted_region < T : ByteRepr > (
51+ data : & dyn OriginalAlloc ,
52+ offset : usize ,
53+ ) -> ( Vec < u8 > , Vec < T > ) {
54+ let elem_size = std:: mem:: size_of :: < T > ( ) ;
55+ let num_elems = data
56+ . total_byte_len ( )
57+ . saturating_sub ( offset)
58+ . checked_div ( elem_size)
59+ . unwrap_or ( 0 ) ;
60+ assert ! ( num_elems > 0 , "ub: dereference out of bounds" ) ;
61+ let mut buf = vec ! [ 0u8 ; num_elems * elem_size] ;
62+ data. read_bytes ( offset, & mut buf) ;
63+ let vals = buf. chunks_exact ( elem_size) . map ( T :: from_bytes) . collect ( ) ;
64+ ( buf, vals)
65+ }
66+
5067impl < T : ByteRepr > StrongPtr < T > {
5168 pub fn deref ( & self ) -> Ref < ' _ , T > {
5269 match self {
@@ -59,10 +76,9 @@ impl<T: ByteRepr> StrongPtr<T> {
5976 cell,
6077 } => {
6178 // Read-through: always re-read from the original allocation.
62- let mut buf = vec ! [ 0u8 ; std:: mem:: size_of:: <T >( ) ] ;
63- alloc. read_bytes ( * byte_offset, & mut buf) ;
64- * cell. borrow_mut ( ) = Some ( T :: from_bytes ( & buf) ) ;
65- Ref :: map ( cell. borrow ( ) , |opt| opt. as_ref ( ) . unwrap ( ) )
79+ let ( _, vals) = read_reinterpreted_region :: < T > ( & * * alloc, * byte_offset) ;
80+ * cell. borrow_mut ( ) = Some ( vals) ;
81+ Ref :: map ( cell. borrow ( ) , |opt| & opt. as_ref ( ) . unwrap ( ) [ 0 ] )
6682 }
6783 }
6884 }
@@ -442,11 +458,12 @@ impl<T> Ptr<T> {
442458 f ( & mut borrow[ self . offset ] )
443459 }
444460 PtrKind :: Reinterpreted ( data) => {
445- let mut buf = vec ! [ 0u8 ; std:: mem:: size_of:: <T >( ) ] ;
446- data. read_bytes ( self . offset , & mut buf) ;
447- let mut val = T :: from_bytes ( & buf) ;
448- let ret = f ( & mut val) ;
449- val. to_bytes ( & mut buf) ;
461+ let ( mut buf, mut vals) = read_reinterpreted_region :: < T > ( & * * data, self . offset ) ;
462+ let elem_size = std:: mem:: size_of :: < T > ( ) ;
463+ let ret = f ( & mut vals[ 0 ] ) ;
464+ for ( i, val) in vals. iter ( ) . enumerate ( ) {
465+ val. to_bytes ( & mut buf[ i * elem_size..( i + 1 ) * elem_size] ) ;
466+ }
450467 data. write_bytes ( self . offset , & buf) ;
451468 ret
452469 }
@@ -475,10 +492,8 @@ impl<T> Ptr<T> {
475492 f ( & borrow[ self . offset ] )
476493 }
477494 PtrKind :: Reinterpreted ( data) => {
478- let mut buf = vec ! [ 0u8 ; std:: mem:: size_of:: <T >( ) ] ;
479- data. read_bytes ( self . offset , & mut buf) ;
480- let val = T :: from_bytes ( & buf) ;
481- f ( & val)
495+ let ( _, vals) = read_reinterpreted_region :: < T > ( & * * data, self . offset ) ;
496+ f ( & vals[ 0 ] )
482497 }
483498 }
484499 }
0 commit comments