mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-18 19:31:04 +00:00
feat(core/rust): add option to Gc-allocate with finaliser
[no changelog]
This commit is contained in:
parent
288c855868
commit
813d9b7687
@ -235,6 +235,7 @@ fn generate_micropython_bindings() {
|
||||
.allowlist_var("mp_type_fun_builtin_var")
|
||||
// gc
|
||||
.allowlist_function("gc_alloc")
|
||||
.allowlist_var("GC_ALLOC_FLAG_HAS_FINALISER")
|
||||
// iter
|
||||
.allowlist_type("mp_obj_iter_buf_t")
|
||||
.allowlist_function("mp_getiter")
|
||||
|
@ -21,8 +21,17 @@ impl<T: ?Sized> Copy for Gc<T> {}
|
||||
|
||||
impl<T> Gc<T> {
|
||||
/// Allocate memory on the heap managed by the MicroPython garbage collector
|
||||
/// and then place `v` into it. `v` will _not_ get its destructor called.
|
||||
pub fn new(v: T) -> Result<Self, Error> {
|
||||
/// and then place `v` into it.
|
||||
///
|
||||
/// `flags` can be an int value built out of constants in the ffi module.
|
||||
/// The current MicroPython only supports GC_ALLOC_FLAG_HAS_FINALISER, which
|
||||
/// will cause the __del__ method to be called when the object is
|
||||
/// garbage collected.
|
||||
///
|
||||
/// SAFETY:
|
||||
/// Flag GC_ALLOC_FLAG_HAS_FINALISER can only be used with Python objects
|
||||
/// that have a base as their first element
|
||||
unsafe fn alloc(v: T, flags: u32) -> Result<Self, Error> {
|
||||
let layout = Layout::for_value(&v);
|
||||
// TODO: Assert that `layout.align()` is the same as the GC alignment.
|
||||
// SAFETY:
|
||||
@ -32,7 +41,7 @@ impl<T> Gc<T> {
|
||||
// or the MicroPython heap.
|
||||
// EXCEPTION: Returns null instead of raising.
|
||||
unsafe {
|
||||
let raw = ffi::gc_alloc(layout.size(), 0);
|
||||
let raw = ffi::gc_alloc(layout.size(), flags);
|
||||
if raw.is_null() {
|
||||
return Err(Error::AllocationFailed);
|
||||
}
|
||||
@ -41,6 +50,30 @@ impl<T> Gc<T> {
|
||||
Ok(Self::from_raw(typed))
|
||||
}
|
||||
}
|
||||
|
||||
/// Allocate memory on the heap managed by the MicroPython garbage collector
|
||||
/// and then place `v` into it. `v` will _not_ get its destructor called.
|
||||
pub fn new(v: T) -> Result<Self, Error> {
|
||||
unsafe {
|
||||
// SAFETY: No flag is used
|
||||
Self::alloc(v, 0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Allocate memory on the heap managed by the MicroPython garbage
|
||||
/// collector, place `v` into it, and register for finalisation.
|
||||
///
|
||||
/// `v` will **not** get its destructor called automatically! However, if
|
||||
/// `v` is a Python-style object (has a base as its first field), and
|
||||
/// has a `__del__` method, it will be called when the object is garbage
|
||||
/// collected. You can use this to implement custom finalisation, in
|
||||
/// which you can, e.g., invoke the Drop implementation.
|
||||
/// SAFETY:
|
||||
/// Can only be used with Python objects that have a base as their
|
||||
/// first element
|
||||
pub unsafe fn new_with_custom_finaliser(v: T) -> Result<Self, Error> {
|
||||
unsafe { Self::alloc(v, ffi::GC_ALLOC_FLAG_HAS_FINALISER) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> Gc<[T]> {
|
||||
|
Loading…
Reference in New Issue
Block a user