mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-06-30 20:02:34 +00:00

core: Remove dangling module decls
core: Use new Cargo feature resolver, use external MacOS debug info
core: Rust docs improvements
core: Upgrade bindgen
core: Add test target to Rust
ci: build rust sources
build(core): .ARM.exidx.text.__aeabi_ui2f in t1 firmware size
It's an unwind table for softfloat function inserted by rustc, probably
can be removed to save 8 bytes:
599c58db70/link.x.in (L175-L182)
scons: Remove dead code
core: Move Rust target to build/rust
core: Replace extern with a FFI version
core: Add some explanatory Rust comments
core: Use correct path for the Rust lib
core: Remove Buffer::as_mut()
Mutable buffer access needs MP_BUFFER_WRITE flag. TBD in the Protobuf PR.
core: Improve docs for micropython::Buffer
core: Minor Rust docs changes
core: Rewrite trezor_obj_get_ll_checked
core: Fix incorrect doc comment
core: Remove cc from deps
fixup! core: Rewrite trezor_obj_get_ll_checked
core: update safety comments
82 lines
2.8 KiB
Rust
82 lines
2.8 KiB
Rust
use core::{
|
|
alloc::Layout,
|
|
marker::Unsize,
|
|
ops::{CoerceUnsized, Deref, DispatchFromDyn},
|
|
ptr::{self, NonNull},
|
|
};
|
|
|
|
use super::ffi;
|
|
|
|
/// A pointer type for values on the garbage-collected heap.
|
|
///
|
|
/// Although a garbage-collected pointer type technically should implement
|
|
/// `Copy` and `Clone`, we avoid doing this until proven necessary.
|
|
pub struct Gc<T: ?Sized>(NonNull<T>);
|
|
|
|
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Gc<U>> for Gc<T> {}
|
|
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Gc<U>> 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) -> Self {
|
|
let layout = Layout::for_value(&v);
|
|
// TODO: Assert that `layout.align()` is the same as the GC alignment.
|
|
// SAFETY:
|
|
// - Unfortunately we cannot respect `layout.align()` as MicroPython GC does
|
|
// not support custom alignment.
|
|
// - `ptr` is guaranteed to stay valid as long as it's reachable from the stack
|
|
// or the MicroPython heap.
|
|
unsafe {
|
|
let raw = ffi::gc_alloc(layout.size(), 0).cast();
|
|
ptr::write(raw, v);
|
|
Self::from_raw(raw)
|
|
}
|
|
}
|
|
|
|
/// Return a mutable reference to the value.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// `Gc` values can originate in the MicroPython interpreter, and these can
|
|
/// be both shared and mutable. Before calling this function, you have to
|
|
/// ensure that `this` is unique for the whole lifetime of the
|
|
/// returned mutable reference.
|
|
pub unsafe fn as_mut(this: &mut Self) -> &mut T {
|
|
// SAFETY: The caller must guarantee that `this` meets all the requirements for
|
|
// a mutable reference.
|
|
unsafe { this.0.as_mut() }
|
|
}
|
|
}
|
|
|
|
impl<T: ?Sized> Gc<T> {
|
|
/// Construct a `Gc` from a raw pointer.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// This function is unsafe because the caller has to guarantee that `ptr`
|
|
/// is pointing to a memory understood by the MicroPython GC, that is:
|
|
/// - previously allocated through `Gc::new()` or `gc_alloc()`, or
|
|
/// - through the MicroPython interpreter, or
|
|
/// - one of the GC roots (sys.argv, sys.modules, etc.).
|
|
pub unsafe fn from_raw(ptr: *mut T) -> Self {
|
|
// SAFETY: The caller must guarantee that `ptr` is something the MicroPython GC
|
|
// can reason about.
|
|
unsafe { Self(NonNull::new_unchecked(ptr)) }
|
|
}
|
|
|
|
/// Convert `this` into a raw pointer. This will _not_ drop the contained
|
|
/// value.
|
|
pub fn into_raw(this: Self) -> *mut T {
|
|
this.0.as_ptr()
|
|
}
|
|
}
|
|
|
|
impl<T: ?Sized> Deref for Gc<T> {
|
|
type Target = T;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
unsafe { self.0.as_ref() }
|
|
}
|
|
}
|