daily pastebin goal
84%
SHARE
TWEET

Untitled

a guest Mar 19th, 2019 60 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. mod some_lib {
  2.     use crate::rel_ptr::RelPtr;
  3.  
  4.     mod ffi {
  5.         pub
  6.         struct Context ([u8; 3]);
  7.  
  8.         pub
  9.         struct Thing (());
  10.  
  11.         pub
  12.         unsafe extern "C" fn mk_context () -> Context
  13.         { Context([0; 3]) }
  14.  
  15.         pub
  16.         unsafe extern "C" fn mk_thing (_: *mut Context) -> Thing
  17.         { Thing(()) }
  18.  
  19.         pub
  20.         unsafe extern "C" fn free_thing (ctx: *mut Context, thing: *mut Thing)
  21.         {
  22.             eprintln!(
  23.                 "[C] Freeing thing at {:p}, with context at {:p}",
  24.                 thing,
  25.                 ctx,
  26.             );
  27.         }
  28.  
  29.         pub
  30.         unsafe extern "C" fn free_context (ctx: *mut Context)
  31.         {
  32.             eprintln!( "[C] Freeing context at {:p}", ctx);
  33.         }
  34.     }
  35.  
  36.     #[repr(transparent)]
  37.     pub
  38.     struct Context (ffi::Context);
  39.     impl Context {
  40.         pub
  41.         fn new () -> Self
  42.         {
  43.             Context(unsafe { ffi::mk_context() })
  44.         }
  45.     }
  46.     impl Drop for Context { fn drop (&mut self) {
  47.         unsafe { ffi::free_context(&mut self.0) }
  48.     }}
  49.  
  50.     pub
  51.     struct Thing (
  52.         Option<(ffi::Thing, RelPtr<Context>)>
  53.     );
  54.     impl Thing {
  55.         pub
  56.         fn new () -> Self {
  57.             Thing(None)
  58.         }
  59.  
  60.         /// # Safety
  61.         ///
  62.         /// The relative offset between `*self` and `*context` must not change
  63.         pub
  64.         unsafe fn init (
  65.             self: &'_ mut Self,
  66.             context: &'_ mut Context,
  67.         )
  68.         {
  69.             *self = Thing(Some((
  70.                 ffi::mk_thing(&mut context.0),
  71.                 RelPtr::default(),
  72.             )));
  73.             if let Thing(Some((_, ref mut rel_ptr))) = *self {
  74.                 rel_ptr.set(context)
  75.             } else {
  76.                 ::std::hint::unreachable_unchecked()
  77.             }
  78.         }
  79.  
  80.         pub
  81.         fn get_thing (
  82.             self: &'_ Self,
  83.         ) -> Option<&'_ ffi::Thing>
  84.         {
  85.             Some(&self.0.as_ref()?.0)
  86.         }
  87.  
  88.         pub
  89.         unsafe fn get_context_mut (
  90.             self: &'_ mut Self,
  91.         ) -> Option<&'_ mut ffi::Context>
  92.         {
  93.             Some(&mut self.0.as_mut()?.1.get_mut()?.0)
  94.         }
  95.        
  96.         pub
  97.         fn drop (&mut self)
  98.         { unsafe {
  99.             if let Thing(Some(ref mut slf)) = *self {
  100.                 let thing = &mut slf.0;
  101.                 slf.1.get_mut().map(|context| {
  102.                     ffi::free_thing(
  103.                        &mut context.0,
  104.                        &mut *thing,
  105.                     );
  106.                 });
  107.                 self.0 = None;
  108.             }
  109.         }}
  110.     }
  111.     impl Drop for Thing { fn drop (&mut self) {
  112.         self.drop()
  113.     }}
  114. }
  115.  
  116. use some_lib::{
  117.     Context,
  118.     Thing,
  119. };
  120.  
  121. // use core::mem::ManuallyDrop;
  122.  
  123. #[repr(packed)]
  124. pub
  125. struct SelfRef {
  126.     _pad: u8,
  127.     thing: Thing,
  128.     context: Context,
  129. }
  130.  
  131. impl SelfRef {
  132.     pub
  133.     fn new () -> Self
  134.     {
  135.         unsafe {
  136.             let mut ret = SelfRef {
  137.                 _pad: 0,
  138.                 context: Context::new(),
  139.                 thing: /*ManuallyDrop::new(*/Thing::new()/*)*/,
  140.             };
  141.             ret.thing.init(&mut ret.context);
  142.             ret
  143.         }
  144.     }
  145. }
  146.  
  147. impl Drop for SelfRef { fn drop (&mut self) {
  148.    
  149.         self.thing.drop() // ManuallyDrop::drop(&mut self.thing)
  150.    
  151. }}
  152.  
  153. fn main ()
  154. {
  155.     let mut self_ref = SelfRef::new();
  156.     eprintln!("thing at {:p}", unsafe {
  157.         self_ref.thing.get_thing().unwrap()
  158.     });
  159.     eprintln!("thing thinks context is at {:p}", unsafe {
  160.         self_ref.thing.get_context_mut().unwrap()
  161.     });
  162.     eprintln!("context at {:p}", &self_ref.context);
  163. }
  164.  
  165. mod rel_ptr {
  166.     use ::std::*;
  167.  
  168.     #[derive(Debug)]
  169.     pub
  170.     struct RelPtr<T : Sized> /* = */ {
  171.         offset: Option<num::NonZeroUsize>,
  172.         marker: marker::PhantomData<*mut T>,
  173.     }
  174.  
  175.     impl<T : Sized> Default for RelPtr<T> { fn default () -> Self {
  176.         RelPtr {
  177.             offset: None,
  178.             marker: marker::PhantomData,
  179.         }
  180.     }}
  181.  
  182.     impl<T : Sized> RelPtr<T> {
  183.         pub
  184.         fn set(
  185.             self: &'_ mut Self,
  186.             target: &'_ mut T,
  187.         )
  188.         {
  189.             unsafe {
  190.                 self.offset = Some(num::NonZeroUsize::
  191.                     new_unchecked(usize::wrapping_sub(
  192.                         target as *mut T as _,
  193.                         self as *mut Self as _,
  194.                     ))
  195.                 );
  196.             }
  197.         }
  198.  
  199.         pub
  200.         unsafe fn get_mut (
  201.             self: &'_ mut Self,
  202.         ) -> Option<&'_ mut T>
  203.         {
  204.             <*mut T>::as_mut(
  205.                 usize::wrapping_add(
  206.                     self as *mut Self as usize,
  207.                     self.offset?.get(),
  208.                 ) as *mut T
  209.             )
  210.         }
  211.     }
  212. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top