brotli_decompressor/ffi/
alloc_util.rs

1use core;
2#[cfg(feature="std")]
3use std;
4use ::alloc;
5use super::interface::{c_void, CAllocator};
6#[cfg(feature="std")]
7use std::vec::Vec;
8#[cfg(feature="std")]
9pub use std::boxed::Box;
10
11#[cfg(feature="std")]
12pub struct MemoryBlock<Ty:Sized+Default>(Box<[Ty]>);
13#[cfg(feature="std")]
14impl<Ty:Sized+Default> Default for MemoryBlock<Ty> {
15    fn default() -> Self {
16        MemoryBlock(Vec::<Ty>::new().into_boxed_slice())
17    }
18}
19#[cfg(feature="std")]
20impl<Ty:Sized+Default> alloc::SliceWrapper<Ty> for MemoryBlock<Ty> {
21    fn slice(&self) -> &[Ty] {
22        &self.0[..]
23    }
24}
25#[cfg(feature="std")]
26impl<Ty:Sized+Default> alloc::SliceWrapperMut<Ty> for MemoryBlock<Ty> {
27    fn slice_mut(&mut self) -> &mut [Ty] {
28        &mut self.0[..]
29    }
30}
31#[cfg(feature="std")]
32impl<Ty:Sized+Default> core::ops::Index<usize> for MemoryBlock<Ty> {
33    type Output = Ty;
34    fn index(&self, index:usize) -> &Ty {
35        &self.0[index]
36    }
37}
38#[cfg(feature="std")]
39impl<Ty:Sized+Default> core::ops::IndexMut<usize> for MemoryBlock<Ty> {
40
41    fn index_mut(&mut self, index:usize) -> &mut Ty {
42        &mut self.0[index]
43    }
44}
45#[cfg(feature="std")]
46impl<Ty:Sized+Default> Drop for MemoryBlock<Ty> {
47    fn drop (&mut self) {
48        if self.0.len() != 0 {
49            print!("leaking memory block of length {} element size: {}\n", self.0.len(), core::mem::size_of::<Ty>());
50
51            let to_forget = core::mem::replace(self, MemoryBlock::default());
52            core::mem::forget(to_forget);// leak it -- it's the only safe way with custom allocators
53        }
54    }
55}
56pub struct SubclassableAllocator {
57    alloc: CAllocator
58    // have alternative ty here
59}
60
61impl SubclassableAllocator {
62    pub unsafe fn new(sub_alloc:CAllocator) -> Self {
63        SubclassableAllocator{
64            alloc:sub_alloc,
65        }
66    }
67}
68#[cfg(feature="std")]
69impl<Ty:Sized+Default+Clone> alloc::Allocator<Ty> for SubclassableAllocator {
70    type AllocatedMemory = MemoryBlock<Ty>;
71    fn alloc_cell(&mut self, size:usize) ->MemoryBlock<Ty>{
72        if size == 0 {
73            return MemoryBlock::<Ty>::default();
74        }
75        if let Some(alloc_fn) = self.alloc.alloc_func {
76            let ptr = alloc_fn(self.alloc.opaque, size * core::mem::size_of::<Ty>());
77            let typed_ptr = unsafe {core::mem::transmute::<*mut c_void, *mut Ty>(ptr)};
78            let slice_ref = unsafe {super::slice_from_raw_parts_or_nil_mut(typed_ptr, size)};
79            for item in slice_ref.iter_mut() {
80                unsafe{core::ptr::write(item, Ty::default())};
81            }
82            return MemoryBlock(unsafe{Box::from_raw(slice_ref)})
83        }
84        MemoryBlock(vec![Ty::default();size].into_boxed_slice())
85    }
86    fn free_cell(&mut self, mut bv:MemoryBlock<Ty>) {
87        if (*bv.0).len() != 0 {
88            if let Some(_) = self.alloc.alloc_func {
89                let slice_ptr = (*bv.0).as_mut_ptr();
90                let _box_ptr = Box::into_raw(core::mem::replace(&mut bv.0, Vec::<Ty>::new().into_boxed_slice()));
91                if let Some(free_fn) = self.alloc.free_func {
92                    unsafe {free_fn(self.alloc.opaque, core::mem::transmute::<*mut Ty, *mut c_void>(slice_ptr))};
93                }
94            } else {
95                let _to_free = core::mem::replace(&mut bv.0, Vec::<Ty>::new().into_boxed_slice());
96            }
97        }
98    }
99}
100
101
102
103
104
105
106
107
108
109
110
111#[cfg(not(feature="std"))]
112static mut G_SLICE:&'static mut[u8] = &mut[];
113#[cfg(not(feature="std"))]
114pub struct MemoryBlock<Ty:Sized+Default>(*mut[Ty]);
115#[cfg(not(feature="std"))]
116impl<Ty:Sized+Default> Default for MemoryBlock<Ty> {
117    fn default() -> Self {
118        MemoryBlock(unsafe{core::mem::transmute::<*mut [u8], *mut[Ty]>(G_SLICE.as_mut())})
119    }
120}
121#[cfg(not(feature="std"))]
122impl<Ty:Sized+Default> alloc::SliceWrapper<Ty> for MemoryBlock<Ty> {
123    fn slice(&self) -> &[Ty] {
124        if unsafe{(*self.0).len()} == 0 {
125            &[]
126        } else {
127            unsafe{super::slice_from_raw_parts_or_nil(&(*self.0)[0], (*self.0).len())}
128        }
129    }
130}
131#[cfg(not(feature="std"))]
132impl<Ty:Sized+Default> alloc::SliceWrapperMut<Ty> for MemoryBlock<Ty> {
133    fn slice_mut(&mut self) -> &mut [Ty] {
134        if unsafe{(*self.0).len()} == 0 {
135            &mut []
136        } else {
137            unsafe{super::slice_from_raw_parts_or_nil_mut(&mut (*self.0)[0], (*self.0).len())}
138        }
139    }
140}
141
142#[cfg(not(feature="std"))]
143#[cfg(feature="no-stdlib-ffi-binding")]
144#[panic_handler]
145extern fn panic_impl(_: &::core::panic::PanicInfo) -> ! {
146    loop {}
147}
148#[cfg(not(feature="std"))]
149#[cfg(feature="no-stdlib-ffi-binding")]
150#[lang = "eh_personality"]
151extern "C" fn eh_personality() {
152}
153
154#[cfg(not(feature="std"))]
155impl<Ty:Sized+Default> core::ops::Index<usize> for MemoryBlock<Ty> {
156    type Output = Ty;
157    fn index(&self, index:usize) -> &Ty {
158        unsafe{&(*self.0)[index]}
159    }
160}
161#[cfg(not(feature="std"))]
162impl<Ty:Sized+Default> core::ops::IndexMut<usize> for MemoryBlock<Ty> {
163
164    fn index_mut(&mut self, index:usize) -> &mut Ty {
165        unsafe{&mut (*self.0)[index]}
166    }
167}
168
169#[cfg(not(feature="std"))]
170impl<Ty:Sized+Default+Clone> alloc::Allocator<Ty> for SubclassableAllocator {
171    type AllocatedMemory = MemoryBlock<Ty>;
172    fn alloc_cell(&mut self, size:usize) ->MemoryBlock<Ty>{
173        if size == 0 {
174            return MemoryBlock::<Ty>::default();
175        }
176        if let Some(alloc_fn) = self.alloc.alloc_func {
177            let ptr = alloc_fn(self.alloc.opaque, size * core::mem::size_of::<Ty>());
178            let typed_ptr = unsafe {core::mem::transmute::<*mut c_void, *mut Ty>(ptr)};
179            let slice_ref = unsafe {super::slice_from_raw_parts_or_nil_mut(typed_ptr, size)};
180            for item in slice_ref.iter_mut() {
181                unsafe{core::ptr::write(item, Ty::default())};
182            }
183            return MemoryBlock(slice_ref.as_mut())
184        } else {
185            panic!("Must provide allocators in no-stdlib code");
186        }
187    }
188    fn free_cell(&mut self, mut bv:MemoryBlock<Ty>) {
189        use alloc::SliceWrapper;
190        use alloc::SliceWrapperMut;
191        if bv.slice().len() != 0 {
192            if let Some(_) = self.alloc.alloc_func {
193                if let Some(free_fn) = self.alloc.free_func {
194                    unsafe {free_fn(self.alloc.opaque, core::mem::transmute::<*mut Ty, *mut c_void>(&mut bv.slice_mut()[0]))};
195                }
196                let _ = core::mem::replace(&mut bv,
197                                           MemoryBlock::<Ty>::default());
198            } else {
199                panic!("Must provide allocators in no-stdlib code");
200            }
201        }
202    }
203}
204
205
206#[cfg(not(feature="std"))]
207pub fn free_stdlib<T>(_data: *mut T, _size: usize) {
208    panic!("Must supply allocators if calling divans when compiled with features=no-stdlib");
209}
210#[cfg(not(feature="std"))]
211pub fn alloc_stdlib<T:Sized+Default+Copy+Clone>(_size: usize) -> *mut T {
212    panic!("Must supply allocators if calling divans when compiled with features=no-stdlib");
213}
214
215#[cfg(feature="std")]
216pub unsafe fn free_stdlib<T>(ptr: *mut T, size: usize) {
217    let slice_ref = super::slice_from_raw_parts_or_nil_mut(ptr, size);
218    let _ = Box::from_raw(slice_ref); // free on drop
219}
220#[cfg(feature="std")]
221pub fn alloc_stdlib<T:Sized+Default+Copy+Clone>(size: usize) -> *mut T {
222    std::panic::catch_unwind(|| {
223        let mut newly_allocated = vec![T::default();size].into_boxed_slice();
224        let slice_ptr = newly_allocated.as_mut_ptr();
225        let _box_ptr = Box::into_raw(newly_allocated);
226        slice_ptr
227    }).unwrap_or(core::ptr::null_mut())
228}