Implement Arena::fuse()

PiperOrigin-RevId: 627983487
pull/16617/head
Jakob Buchgraber 2024-04-25 00:36:14 -07:00 committed by Copybara-Service
parent 59d8afde6b
commit dcc5db4c56
1 changed files with 20 additions and 0 deletions

View File

@ -142,6 +142,25 @@ impl Arena {
slice::from_raw_parts_mut(alloc, data.len())
}
}
/// Fuse two arenas so they share the same lifetime.
///
/// `fuse` will make it so that the memory allocated by `self` or `other` is
/// guaranteed to last until both `self` and `other` have been dropped.
/// The pointers returned by `Arena::alloc` will continue to be valid so
/// long as either `self` or `other` has not been dropped.
///
pub fn fuse(&self, other: &Arena) {
// SAFETY: `self.raw()` and `other.raw()` are both valid UPB arenas.
let success = unsafe { upb_Arena_Fuse(self.raw(), other.raw()) };
if !success {
// Fusing can fail if any of the arenas has an initial block i.e. the arena is
// backed by a preallocated chunk of memory that it doesn't own and thus cannot
// lifetime extend. This function panics because this is typically not a
// recoverable error but a logic bug in a program.
panic!("Could not fuse two UPB arenas.");
}
}
}
impl Default for Arena {
@ -164,6 +183,7 @@ extern "C" {
fn upb_Arena_New() -> Option<RawArena>;
fn upb_Arena_Free(arena: RawArena);
fn upb_Arena_Malloc(arena: RawArena, size: usize) -> *mut u8;
fn upb_Arena_Fuse(arena1: RawArena, arena2: RawArena) -> bool;
}
#[cfg(test)]