1use crate::any_pointer;
74use crate::private::arena::{BuilderArena, BuilderArenaImpl};
75use crate::private::arena::{ReaderArena, ReaderArenaImpl};
76use crate::private::layout;
77use crate::private::units::BYTES_PER_WORD;
78use crate::traits::{FromPointerBuilder, SetterInput};
79use crate::traits::{FromPointerReader, Owned};
80use crate::OutputSegments;
81use crate::Result;
82
83#[derive(Clone, Copy, Debug)]
85pub struct ReaderOptions {
86 pub traversal_limit_in_words: Option<usize>,
104
105 pub nesting_limit: i32,
114}
115
116#[cfg(not(target_pointer_width = "16"))]
117pub const DEFAULT_READER_OPTIONS: ReaderOptions = ReaderOptions {
118 traversal_limit_in_words: Some(8 * 1024 * 1024),
119 nesting_limit: 64,
120};
121
122#[cfg(target_pointer_width = "16")]
123pub const DEFAULT_READER_OPTIONS: ReaderOptions = ReaderOptions {
124 traversal_limit_in_words: Some(8 * 1024),
125 nesting_limit: 64,
126};
127
128impl Default for ReaderOptions {
129 fn default() -> Self {
130 DEFAULT_READER_OPTIONS
131 }
132}
133
134impl ReaderOptions {
135 pub const fn new() -> Self {
136 DEFAULT_READER_OPTIONS
137 }
138
139 pub fn nesting_limit(&mut self, value: i32) -> &mut Self {
140 self.nesting_limit = value;
141 self
142 }
143
144 pub fn traversal_limit_in_words(&mut self, value: Option<usize>) -> &mut Self {
145 self.traversal_limit_in_words = value;
146 self
147 }
148}
149
150pub trait ReaderSegments {
152 fn get_segment(&self, idx: u32) -> Option<&[u8]>;
160
161 fn len(&self) -> usize {
163 for i in 0u32.. {
164 if self.get_segment(i).is_none() {
165 return i as usize;
166 }
167 }
168 unreachable!()
169 }
170
171 fn is_empty(&self) -> bool {
172 self.len() == 0
173 }
174}
175
176impl<S> ReaderSegments for &S
187where
188 S: ReaderSegments + ?Sized,
189{
190 fn get_segment(&self, idx: u32) -> Option<&[u8]> {
191 (**self).get_segment(idx)
192 }
193
194 fn len(&self) -> usize {
195 (**self).len()
196 }
197
198 fn is_empty(&self) -> bool {
199 (**self).is_empty()
200 }
201}
202
203pub struct SegmentArray<'a> {
205 segments: &'a [&'a [u8]],
206}
207
208impl<'a> SegmentArray<'a> {
209 pub fn new(segments: &'a [&'a [u8]]) -> SegmentArray<'a> {
210 SegmentArray { segments }
211 }
212}
213
214impl ReaderSegments for SegmentArray<'_> {
215 fn get_segment(&self, id: u32) -> Option<&[u8]> {
216 self.segments.get(id as usize).copied()
217 }
218
219 fn len(&self) -> usize {
220 self.segments.len()
221 }
222}
223
224impl<I> ReaderSegments for [I]
225where
226 I: AsRef<[u8]>,
227{
228 fn get_segment(&self, id: u32) -> Option<&[u8]> {
229 self.get(id as usize).map(|i| i.as_ref())
230 }
231
232 fn len(&self) -> usize {
233 self.len()
234 }
235
236 fn is_empty(&self) -> bool {
237 self.is_empty()
238 }
239}
240
241#[cfg(feature = "alloc")]
242impl<I> ReaderSegments for alloc::vec::Vec<I>
243where
244 I: AsRef<[u8]>,
245{
246 fn get_segment(&self, id: u32) -> Option<&[u8]> {
247 self.get(id as usize).map(|i| i.as_ref())
248 }
249
250 fn len(&self) -> usize {
251 self.len()
252 }
253
254 fn is_empty(&self) -> bool {
255 self.is_empty()
256 }
257}
258
259pub struct Reader<S>
261where
262 S: ReaderSegments,
263{
264 arena: ReaderArenaImpl<S>,
265}
266
267impl<S> Reader<S>
268where
269 S: ReaderSegments,
270{
271 pub fn new(segments: S, options: ReaderOptions) -> Self {
272 Self {
273 arena: ReaderArenaImpl::new(segments, options),
274 }
275 }
276
277 fn get_root_internal(&self) -> Result<any_pointer::Reader<'_>> {
278 let (segment_start, _seg_len) = self.arena.get_segment(0)?;
279 let pointer_reader = unsafe {
280 layout::PointerReader::get_root(
281 &self.arena,
282 0,
283 segment_start,
284 self.arena.nesting_limit(),
285 )
286 }?;
287 Ok(any_pointer::Reader::new(pointer_reader))
288 }
289
290 pub fn get_root<'a, T: FromPointerReader<'a>>(&'a self) -> Result<T> {
292 self.get_root_internal()?.get_as()
293 }
294
295 pub fn into_segments(self) -> S {
296 self.arena.into_segments()
297 }
298
299 pub fn is_canonical(&self) -> Result<bool> {
301 let (segment_start, seg_len) = self.arena.get_segment(0)?;
302
303 if self.arena.get_segment(1).is_ok() {
304 return Ok(false);
309 }
310
311 let pointer_reader = unsafe {
312 layout::PointerReader::get_root(
313 &self.arena,
314 0,
315 segment_start,
316 self.arena.nesting_limit(),
317 )
318 }?;
319 let read_head = ::core::cell::Cell::new(unsafe { segment_start.add(BYTES_PER_WORD) });
320 let root_is_canonical = pointer_reader.is_canonical(&read_head)?;
321 let all_words_consumed = (read_head.get() as usize - segment_start as usize)
322 / BYTES_PER_WORD
323 == seg_len as usize;
324 Ok(root_is_canonical && all_words_consumed)
325 }
326
327 #[cfg(feature = "alloc")]
331 pub fn canonicalize(&self) -> Result<alloc::vec::Vec<crate::Word>> {
332 let root = self.get_root_internal()?;
333 let size = root.target_size()?.word_count + 1;
334 let mut message =
335 Builder::new(HeapAllocator::new().first_segment_words(u32::try_from(size).unwrap()));
336 message.set_root_canonical(root)?;
337 let output_segments = message.get_segments_for_output();
338 assert_eq!(1, output_segments.len());
339 let output = output_segments[0];
340 assert!((output.len() / BYTES_PER_WORD) as u64 <= size);
341 let mut result = crate::Word::allocate_zeroed_vec(output.len() / BYTES_PER_WORD);
342 crate::Word::words_to_bytes_mut(&mut result[..]).copy_from_slice(output);
343 Ok(result)
344 }
345
346 pub fn into_typed<T: Owned>(self) -> TypedReader<S, T> {
347 TypedReader::new(self)
348 }
349
350 pub fn size_in_words(&self) -> usize {
351 self.arena.size_in_words()
352 }
353
354 pub fn get_segments(&self) -> &S {
356 self.arena.get_segments()
357 }
358}
359
360pub struct TypedReader<S, T>
363where
364 S: ReaderSegments,
365 T: Owned,
366{
367 marker: ::core::marker::PhantomData<T>,
368 message: Reader<S>,
369}
370
371impl<S, T> TypedReader<S, T>
372where
373 S: ReaderSegments,
374 T: Owned,
375{
376 pub fn new(message: Reader<S>) -> Self {
377 Self {
378 marker: ::core::marker::PhantomData,
379 message,
380 }
381 }
382
383 pub fn get(&self) -> Result<T::Reader<'_>> {
384 self.message.get_root()
385 }
386
387 pub fn into_inner(self) -> Reader<S> {
388 self.message
389 }
390
391 pub fn get_segments(&self) -> &S {
393 self.message.get_segments()
394 }
395}
396
397impl<S, T> From<Reader<S>> for TypedReader<S, T>
398where
399 S: ReaderSegments,
400 T: Owned,
401{
402 fn from(message: Reader<S>) -> Self {
403 Self::new(message)
404 }
405}
406
407impl<A, T> From<Builder<A>> for TypedReader<Builder<A>, T>
408where
409 A: Allocator,
410 T: Owned,
411{
412 fn from(message: Builder<A>) -> Self {
413 let reader = message.into_reader();
414 reader.into_typed()
415 }
416}
417
418impl<A, T> From<TypedBuilder<T, A>> for TypedReader<Builder<A>, T>
419where
420 A: Allocator,
421 T: Owned,
422{
423 fn from(builder: TypedBuilder<T, A>) -> Self {
424 builder.into_reader()
425 }
426}
427
428pub unsafe trait Allocator {
444 fn allocate_segment(&mut self, minimum_size: u32) -> (core::ptr::NonNull<u8>, u32);
451
452 unsafe fn deallocate_segment(
463 &mut self,
464 ptr: core::ptr::NonNull<u8>,
465 word_size: u32,
466 words_used: u32,
467 );
468}
469
470pub struct Builder<A>
472where
473 A: Allocator,
474{
475 arena: BuilderArenaImpl<A>,
476}
477
478fn _assert_kinds() {
479 fn _assert_send<T: Send>() {}
480 fn _assert_sync<T: Sync>() {}
481 fn _assert_reader<S: ReaderSegments + Send>() {
482 _assert_send::<Reader<S>>();
483 }
484 fn _assert_builder_send<A: Allocator + Send>() {
485 _assert_send::<Builder<A>>();
486 }
487 fn _assert_builder_sync<A: Allocator + Sync>() {
488 _assert_sync::<Builder<A>>();
489 }
490}
491
492impl<A> Builder<A>
493where
494 A: Allocator,
495{
496 pub fn new(allocator: A) -> Self {
497 Self {
498 arena: BuilderArenaImpl::new(allocator),
499 }
500 }
501
502 fn get_root_internal(&mut self) -> any_pointer::Builder<'_> {
503 if self.arena.is_empty() {
504 self.arena
505 .allocate_segment(1)
506 .expect("allocate root pointer");
507 self.arena.allocate(0, 1).expect("allocate root pointer");
508 }
509 let (seg_start, _seg_len) = self.arena.get_segment_mut(0);
510 let location: *mut u8 = seg_start;
511 let Self { arena } = self;
512
513 any_pointer::Builder::new(layout::PointerBuilder::get_root(arena, 0, location))
514 }
515
516 pub fn init_root<'a, T: FromPointerBuilder<'a>>(&'a mut self) -> T {
518 let root = self.get_root_internal();
519 root.init_as()
520 }
521
522 pub fn initn_root<'a, T: FromPointerBuilder<'a>>(&'a mut self, length: u32) -> T {
524 let root = self.get_root_internal();
525 root.initn_as(length)
526 }
527
528 pub fn get_root<'a, T: FromPointerBuilder<'a>>(&'a mut self) -> Result<T> {
530 let root = self.get_root_internal();
531 root.get_as()
532 }
533
534 pub fn get_root_as_reader<'a, T: FromPointerReader<'a>>(&'a self) -> Result<T> {
535 if self.arena.is_empty() {
536 any_pointer::Reader::new(layout::PointerReader::new_default()).get_as()
537 } else {
538 let (segment_start, _segment_len) = self.arena.get_segment(0)?;
539 let pointer_reader = unsafe {
540 layout::PointerReader::get_root(
541 self.arena.as_reader(),
542 0,
543 segment_start,
544 0x7fffffff,
545 )
546 }?;
547 let root = any_pointer::Reader::new(pointer_reader);
548 root.get_as()
549 }
550 }
551
552 pub fn set_root<T: Owned>(&mut self, value: impl SetterInput<T>) -> Result<()> {
554 let mut root = self.get_root_internal();
555 root.set_as(value)
556 }
557
558 pub fn set_root_canonical<T: Owned>(&mut self, value: impl SetterInput<T>) -> Result<()> {
562 if self.arena.is_empty() {
563 self.arena
564 .allocate_segment(1)
565 .expect("allocate root pointer");
566 self.arena.allocate(0, 1).expect("allocate root pointer");
567 }
568 let (seg_start, _seg_len) = self.arena.get_segment_mut(0);
569 let pointer = layout::PointerBuilder::get_root(&mut self.arena, 0, seg_start);
570 SetterInput::set_pointer_builder(pointer, value, true)?;
571 assert_eq!(self.get_segments_for_output().len(), 1);
572 Ok(())
573 }
574
575 pub fn get_segments_for_output(&self) -> OutputSegments<'_> {
576 self.arena.get_segments_for_output()
577 }
578
579 pub fn into_reader(self) -> Reader<Self> {
580 Reader::new(
581 self,
582 ReaderOptions {
583 traversal_limit_in_words: None,
584 nesting_limit: i32::MAX,
585 },
586 )
587 }
588
589 pub fn into_typed<T: Owned>(self) -> TypedBuilder<T, A> {
590 TypedBuilder::new(self)
591 }
592
593 pub fn into_allocator(self) -> A {
596 self.arena.into_allocator()
597 }
598
599 pub fn size_in_words(&self) -> usize {
600 self.arena.size_in_words()
601 }
602}
603
604impl<A> ReaderSegments for Builder<A>
605where
606 A: Allocator,
607{
608 fn get_segment(&self, id: u32) -> Option<&[u8]> {
609 self.get_segments_for_output().get(id as usize).copied()
610 }
611
612 fn len(&self) -> usize {
613 self.get_segments_for_output().len()
614 }
615}
616
617#[cfg(feature = "alloc")]
624pub struct TypedBuilder<T, A = HeapAllocator>
625where
626 T: Owned,
627 A: Allocator,
628{
629 marker: ::core::marker::PhantomData<T>,
630 message: Builder<A>,
631}
632
633#[cfg(not(feature = "alloc"))]
637pub struct TypedBuilder<T, A>
638where
639 T: Owned,
640 A: Allocator,
641{
642 marker: ::core::marker::PhantomData<T>,
643 message: Builder<A>,
644}
645
646#[cfg(feature = "alloc")]
647impl<T> TypedBuilder<T, HeapAllocator>
648where
649 T: Owned,
650{
651 pub fn new_default() -> Self {
652 Default::default()
653 }
654}
655
656#[cfg(feature = "alloc")]
657impl<T> Default for TypedBuilder<T, HeapAllocator>
658where
659 T: Owned,
660{
661 fn default() -> Self {
662 Self::new(Builder::default())
663 }
664}
665
666impl<T, A> TypedBuilder<T, A>
667where
668 T: Owned,
669 A: Allocator,
670{
671 pub fn new(message: Builder<A>) -> Self {
672 Self {
673 marker: ::core::marker::PhantomData,
674 message,
675 }
676 }
677
678 pub fn init_root(&mut self) -> T::Builder<'_> {
679 self.message.init_root()
680 }
681
682 pub fn initn_root(&mut self, length: u32) -> T::Builder<'_> {
683 self.message.initn_root(length)
684 }
685
686 pub fn get_root(&mut self) -> Result<T::Builder<'_>> {
687 self.message.get_root()
688 }
689
690 pub fn get_root_as_reader(&self) -> Result<T::Reader<'_>> {
691 self.message.get_root_as_reader()
692 }
693
694 pub fn set_root(&mut self, value: T::Reader<'_>) -> Result<()> {
695 self.message.set_root(value)
696 }
697
698 pub fn into_inner(self) -> Builder<A> {
699 self.message
700 }
701
702 pub fn borrow_inner(&self) -> &Builder<A> {
703 &self.message
704 }
705
706 pub fn borrow_inner_mut(&mut self) -> &mut Builder<A> {
707 &mut self.message
708 }
709
710 pub fn into_reader(self) -> TypedReader<Builder<A>, T> {
711 TypedReader::new(self.message.into_reader())
712 }
713}
714
715impl<T, A> From<Builder<A>> for TypedBuilder<T, A>
716where
717 T: Owned,
718 A: Allocator,
719{
720 fn from(builder: Builder<A>) -> Self {
721 Self::new(builder)
722 }
723}
724
725#[derive(Debug)]
727#[cfg(feature = "alloc")]
728pub struct HeapAllocator {
729 next_size: u32,
731
732 allocation_strategy: AllocationStrategy,
734
735 max_segment_words: u32,
737}
738
739#[derive(Clone, Copy, Debug)]
740pub enum AllocationStrategy {
741 FixedSize,
744
745 GrowHeuristically,
747}
748
749pub const SUGGESTED_FIRST_SEGMENT_WORDS: u32 = 1024;
750pub const SUGGESTED_ALLOCATION_STRATEGY: AllocationStrategy = AllocationStrategy::GrowHeuristically;
751
752#[cfg(feature = "alloc")]
753impl Default for HeapAllocator {
754 fn default() -> Self {
755 Self {
756 next_size: SUGGESTED_FIRST_SEGMENT_WORDS,
757 allocation_strategy: SUGGESTED_ALLOCATION_STRATEGY,
758 max_segment_words: 1 << 29,
759 }
760 }
761}
762
763#[cfg(feature = "alloc")]
764impl HeapAllocator {
765 pub fn new() -> Self {
766 Self::default()
767 }
768
769 pub fn first_segment_words(mut self, value: u32) -> Self {
771 assert!(value <= self.max_segment_words);
772 self.next_size = value;
773 self
774 }
775
776 pub fn allocation_strategy(mut self, value: AllocationStrategy) -> Self {
778 self.allocation_strategy = value;
779 self
780 }
781
782 pub fn max_segment_words(mut self, value: u32) -> Self {
784 assert!(self.next_size <= value);
785 self.max_segment_words = value;
786 self
787 }
788}
789
790#[cfg(feature = "alloc")]
791unsafe impl Allocator for HeapAllocator {
792 fn allocate_segment(&mut self, minimum_size: u32) -> (core::ptr::NonNull<u8>, u32) {
793 let size = core::cmp::max(minimum_size, self.next_size);
794 if size == 0 {
795 return (core::ptr::NonNull::dangling(), 0);
797 }
798 let layout =
799 alloc::alloc::Layout::from_size_align(size as usize * BYTES_PER_WORD, 8).unwrap();
800 let ptr = unsafe { alloc::alloc::alloc_zeroed(layout) };
801 let Some(ptr) = core::ptr::NonNull::new(ptr) else {
802 alloc::alloc::handle_alloc_error(layout);
803 };
804 match self.allocation_strategy {
805 AllocationStrategy::GrowHeuristically => {
806 if size < self.max_segment_words - self.next_size {
807 self.next_size += size;
808 } else {
809 self.next_size = self.max_segment_words;
810 }
811 }
812 AllocationStrategy::FixedSize => {}
813 }
814 (ptr, size)
815 }
816
817 unsafe fn deallocate_segment(
818 &mut self,
819 ptr: core::ptr::NonNull<u8>,
820 word_size: u32,
821 _words_used: u32,
822 ) {
823 unsafe {
824 alloc::alloc::dealloc(
825 ptr.as_ptr(),
826 alloc::alloc::Layout::from_size_align(word_size as usize * BYTES_PER_WORD, 8)
827 .unwrap(),
828 );
829 }
830 self.next_size = SUGGESTED_FIRST_SEGMENT_WORDS;
831 }
832}
833
834#[cfg(feature = "alloc")]
835#[test]
836fn test_allocate_max() {
837 let allocation_size = 1 << 24;
838 let mut allocator = HeapAllocator::new()
839 .max_segment_words((1 << 25) - 1)
840 .first_segment_words(allocation_size);
841
842 let (a1, s1) = allocator.allocate_segment(allocation_size);
843 let (a2, s2) = allocator.allocate_segment(allocation_size);
844 let (a3, s3) = allocator.allocate_segment(allocation_size);
845
846 assert_eq!(s1, allocation_size);
847
848 assert_eq!(s2, allocator.max_segment_words);
850 assert_eq!(s3, allocator.max_segment_words);
851
852 unsafe {
853 allocator.deallocate_segment(a1, s1, 0);
854 allocator.deallocate_segment(a2, s2, 0);
855 allocator.deallocate_segment(a3, s3, 0);
856 }
857}
858
859#[cfg(feature = "alloc")]
860impl Builder<HeapAllocator> {
861 pub fn new_default() -> Self {
864 Default::default()
865 }
866}
867
868#[cfg(feature = "alloc")]
869impl Default for Builder<HeapAllocator> {
870 fn default() -> Self {
873 Self::new(HeapAllocator::new())
874 }
875}
876
877#[cfg(feature = "alloc")]
888pub struct ScratchSpaceHeapAllocator<'a> {
889 scratch_space: &'a mut [u8],
890 scratch_space_allocated: bool,
891 allocator: HeapAllocator,
892}
893
894#[cfg(feature = "alloc")]
895impl<'a> ScratchSpaceHeapAllocator<'a> {
896 pub fn new(scratch_space: &'a mut [u8]) -> ScratchSpaceHeapAllocator<'a> {
902 #[cfg(not(feature = "unaligned"))]
903 {
904 if scratch_space.as_ptr() as usize % BYTES_PER_WORD != 0 {
905 panic!(
906 "Scratch space must be 8-byte aligned, or you must enable the \"unaligned\" \
907 feature in the capnp crate"
908 );
909 }
910 }
911
912 for b in &mut scratch_space[..] {
914 *b = 0;
915 }
916 ScratchSpaceHeapAllocator {
917 scratch_space,
918 scratch_space_allocated: false,
919 allocator: HeapAllocator::new(),
920 }
921 }
922
923 pub fn second_segment_words(self, value: u32) -> ScratchSpaceHeapAllocator<'a> {
926 ScratchSpaceHeapAllocator {
927 allocator: self.allocator.first_segment_words(value),
928 ..self
929 }
930 }
931
932 pub fn allocation_strategy(self, value: AllocationStrategy) -> ScratchSpaceHeapAllocator<'a> {
934 ScratchSpaceHeapAllocator {
935 allocator: self.allocator.allocation_strategy(value),
936 ..self
937 }
938 }
939}
940
941#[cfg(feature = "alloc")]
942unsafe impl Allocator for ScratchSpaceHeapAllocator<'_> {
943 fn allocate_segment(&mut self, minimum_size: u32) -> (core::ptr::NonNull<u8>, u32) {
944 if (minimum_size as usize) <= (self.scratch_space.len() / BYTES_PER_WORD)
945 && !self.scratch_space_allocated
946 {
947 self.scratch_space_allocated = true;
948 (
949 core::ptr::NonNull::new(self.scratch_space.as_mut_ptr()).unwrap(),
950 u32::try_from(self.scratch_space.len() / BYTES_PER_WORD).unwrap(),
951 )
952 } else {
953 self.allocator.allocate_segment(minimum_size)
954 }
955 }
956
957 unsafe fn deallocate_segment(
958 &mut self,
959 ptr: core::ptr::NonNull<u8>,
960 word_size: u32,
961 words_used: u32,
962 ) {
963 let seg_ptr = self.scratch_space.as_mut_ptr();
964 if ptr.as_ptr() == seg_ptr {
965 unsafe {
968 core::ptr::write_bytes(
969 seg_ptr, 0u8,
971 (words_used as usize) * BYTES_PER_WORD,
972 );
973 }
974 self.scratch_space_allocated = false;
975 } else {
976 self.allocator
977 .deallocate_segment(ptr, word_size, words_used);
978 }
979 }
980}
981
982pub struct SingleSegmentAllocator<'a> {
997 segment: &'a mut [u8],
998 segment_allocated: bool,
999}
1000
1001impl<'a> SingleSegmentAllocator<'a> {
1002 pub fn new(segment: &'a mut [u8]) -> SingleSegmentAllocator<'a> {
1008 #[cfg(not(feature = "unaligned"))]
1009 {
1010 if segment.as_ptr() as usize % BYTES_PER_WORD != 0 {
1011 panic!(
1012 "Segment must be 8-byte aligned, or you must enable the \"unaligned\" \
1013 feature in the capnp crate"
1014 );
1015 }
1016 }
1017
1018 for b in &mut segment[..] {
1020 *b = 0;
1021 }
1022 SingleSegmentAllocator {
1023 segment,
1024 segment_allocated: false,
1025 }
1026 }
1027}
1028
1029unsafe impl Allocator for SingleSegmentAllocator<'_> {
1030 fn allocate_segment(&mut self, minimum_size: u32) -> (core::ptr::NonNull<u8>, u32) {
1031 let available_word_count = self.segment.len() / BYTES_PER_WORD;
1032 if (minimum_size as usize) > available_word_count {
1033 panic!(
1034 "Allocation too large: asked for {minimum_size} words, \
1035 but only {available_word_count} are available."
1036 )
1037 } else if self.segment_allocated {
1038 panic!("Tried to allocated two segments in a SingleSegmentAllocator.")
1039 } else {
1040 self.segment_allocated = true;
1041 (
1042 core::ptr::NonNull::new(self.segment.as_mut_ptr()).unwrap(),
1043 u32::try_from(self.segment.len() / BYTES_PER_WORD).unwrap(),
1044 )
1045 }
1046 }
1047
1048 unsafe fn deallocate_segment(
1049 &mut self,
1050 ptr: core::ptr::NonNull<u8>,
1051 _word_size: u32,
1052 words_used: u32,
1053 ) {
1054 let seg_ptr = self.segment.as_mut_ptr();
1055 if ptr.as_ptr() == seg_ptr {
1056 unsafe {
1059 core::ptr::write_bytes(
1060 seg_ptr, 0u8,
1062 (words_used as usize) * BYTES_PER_WORD,
1063 );
1064 }
1065 self.segment_allocated = false;
1066 }
1067 }
1068}
1069
1070unsafe impl<A> Allocator for &'_ mut A
1071where
1072 A: Allocator,
1073{
1074 fn allocate_segment(&mut self, minimum_size: u32) -> (core::ptr::NonNull<u8>, u32) {
1075 (*self).allocate_segment(minimum_size)
1076 }
1077
1078 unsafe fn deallocate_segment(
1079 &mut self,
1080 ptr: core::ptr::NonNull<u8>,
1081 word_size: u32,
1082 words_used: u32,
1083 ) {
1084 (*self).deallocate_segment(ptr, word_size, words_used)
1085 }
1086}