Skip to content
This repository was archived by the owner on Nov 27, 2020. It is now read-only.

Commit b1addb0

Browse files
committed
Create PanicAdaptor
1 parent f676515 commit b1addb0

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

src/alloc/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ pub use liballoc::alloc::{handle_alloc_error, Layout};
1313
#[cfg(feature = "std")]
1414
use std::alloc::System;
1515

16+
mod panic_adaptor;
17+
1618
/// Allocate memory with the global allocator.
1719
///
1820
/// This function forwards calls to the [`GlobalAlloc::alloc`] method

src/alloc/panic_adaptor.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//! An allocator adapter that blows up by calling `handle_alloc_error` on all errors.
2+
//!
3+
//! On one hand, concrete allocator implementations should always be written
4+
//! without panicking on user error and OOM to give users maximum
5+
//! flexibility. On the other hand, code that depends on allocation succeeding
6+
//! should depend on `Alloc<Err=!>` to avoid repetitively handling errors from
7+
//! which it cannot recover.
8+
//!
9+
//! This adapter bridges the gap, effectively allowing `Alloc<Err=!>` to be
10+
//! implemented by any allocator.
11+
12+
use core::{ptr::NonNull, usize};
13+
14+
use crate::alloc::*;
15+
16+
/// An allocator adapter that blows up by calling `handle_alloc_error` on all errors.
17+
///
18+
/// See the [module-level documentation](../../std/abort_adapter/index.html) for more.
19+
#[derive(Copy, Clone, Debug, Default)]
20+
pub struct PanicAdapter<Alloc>(pub Alloc);
21+
22+
impl<B: BuildAllocRef> BuildAllocRef for PanicAdapter<B> {
23+
type Ref = PanicAdapter<B::Ref>;
24+
25+
unsafe fn build_alloc_ref(
26+
&mut self,
27+
ptr: NonNull<u8>,
28+
layout: Option<NonZeroLayout>,
29+
) -> Self::Ref {
30+
PanicAdapter(self.0.build_alloc_ref(ptr, layout))
31+
}
32+
}
33+
34+
impl<A: DeallocRef> DeallocRef for PanicAdapter<A> {
35+
type BuildAlloc = PanicAdapter<A::BuildAlloc>;
36+
37+
fn get_build_alloc(&mut self) -> Self::BuildAlloc {
38+
PanicAdapter(self.0.get_build_alloc())
39+
}
40+
41+
unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: NonZeroLayout) {
42+
self.0.dealloc(ptr, layout)
43+
}
44+
}
45+
46+
impl<A: AllocRef> AllocRef for PanicAdapter<A> {
47+
type Error = !;
48+
49+
fn alloc(&mut self, layout: NonZeroLayout) -> Result<NonNull<u8>, Self::Error> {
50+
self.0
51+
.alloc(layout)
52+
.or_else(|_| handle_alloc_error(layout.into()))
53+
}
54+
55+
fn alloc_zeroed(&mut self, layout: NonZeroLayout) -> Result<NonNull<u8>, Self::Error> {
56+
self.0
57+
.alloc_zeroed(layout)
58+
.or_else(|_| handle_alloc_error(layout.into()))
59+
}
60+
61+
fn usable_size(&self, layout: NonZeroLayout) -> (usize, usize) {
62+
self.0.usable_size(layout)
63+
}
64+
65+
unsafe fn grow_in_place(
66+
&mut self,
67+
ptr: NonNull<u8>,
68+
layout: NonZeroLayout,
69+
new_size: NonZeroUsize,
70+
) -> bool {
71+
self.0.grow_in_place(ptr, layout, new_size)
72+
}
73+
74+
unsafe fn shrink_in_place(
75+
&mut self,
76+
ptr: NonNull<u8>,
77+
layout: NonZeroLayout,
78+
new_size: NonZeroUsize,
79+
) -> bool {
80+
self.0.shrink_in_place(ptr, layout, new_size)
81+
}
82+
}
83+
84+
impl<A: ReallocRef> ReallocRef for PanicAdapter<A> {
85+
unsafe fn realloc(
86+
&mut self,
87+
ptr: NonNull<u8>,
88+
old_layout: NonZeroLayout,
89+
new_layout: NonZeroLayout,
90+
) -> Result<NonNull<u8>, Self::Error> {
91+
self.0
92+
.realloc(ptr, old_layout, new_layout)
93+
.or_else(|_| handle_alloc_error(new_layout.into()))
94+
}
95+
}

0 commit comments

Comments
 (0)