mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-31 09:50:58 +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")
|
.allowlist_var("mp_type_fun_builtin_var")
|
||||||
// gc
|
// gc
|
||||||
.allowlist_function("gc_alloc")
|
.allowlist_function("gc_alloc")
|
||||||
|
.allowlist_var("GC_ALLOC_FLAG_HAS_FINALISER")
|
||||||
// iter
|
// iter
|
||||||
.allowlist_type("mp_obj_iter_buf_t")
|
.allowlist_type("mp_obj_iter_buf_t")
|
||||||
.allowlist_function("mp_getiter")
|
.allowlist_function("mp_getiter")
|
||||||
|
@ -21,8 +21,17 @@ impl<T: ?Sized> Copy for Gc<T> {}
|
|||||||
|
|
||||||
impl<T> Gc<T> {
|
impl<T> Gc<T> {
|
||||||
/// Allocate memory on the heap managed by the MicroPython garbage collector
|
/// Allocate memory on the heap managed by the MicroPython garbage collector
|
||||||
/// and then place `v` into it. `v` will _not_ get its destructor called.
|
/// and then place `v` into it.
|
||||||
pub fn new(v: T) -> Result<Self, Error> {
|
///
|
||||||
|
/// `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);
|
let layout = Layout::for_value(&v);
|
||||||
// TODO: Assert that `layout.align()` is the same as the GC alignment.
|
// TODO: Assert that `layout.align()` is the same as the GC alignment.
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
@ -32,7 +41,7 @@ impl<T> Gc<T> {
|
|||||||
// or the MicroPython heap.
|
// or the MicroPython heap.
|
||||||
// EXCEPTION: Returns null instead of raising.
|
// EXCEPTION: Returns null instead of raising.
|
||||||
unsafe {
|
unsafe {
|
||||||
let raw = ffi::gc_alloc(layout.size(), 0);
|
let raw = ffi::gc_alloc(layout.size(), flags);
|
||||||
if raw.is_null() {
|
if raw.is_null() {
|
||||||
return Err(Error::AllocationFailed);
|
return Err(Error::AllocationFailed);
|
||||||
}
|
}
|
||||||
@ -41,6 +50,30 @@ impl<T> Gc<T> {
|
|||||||
Ok(Self::from_raw(typed))
|
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]> {
|
impl<T: Default> Gc<[T]> {
|
||||||
|
Loading…
Reference in New Issue
Block a user