1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-12 01:28:10 +00:00
trezor-firmware/core/embed/rust/src/micropython/list.rs
Jan Pochyla 6257584951 feat(core): Add Rust bindings to MicroPython and trezorhal
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
2021-05-05 16:00:21 +02:00

51 lines
1.5 KiB
Rust

use core::convert::TryFrom;
use crate::error::Error;
use super::{ffi, gc::Gc, obj::Obj};
pub type List = ffi::mp_obj_list_t;
impl List {
pub fn alloc(values: &[Obj]) -> Gc<Self> {
// SAFETY: Altough `values` are copied into the new list and not mutated,
// `mp_obj_new_list` is taking them through a mut pointer.
unsafe {
let list = ffi::mp_obj_new_list(values.len(), values.as_ptr() as *mut Obj);
Gc::from_raw(list.as_ptr().cast())
}
}
pub fn append(&mut self, value: Obj) {
unsafe {
let ptr = self as *mut Self;
let list = Obj::from_ptr(ptr.cast());
ffi::mp_obj_list_append(list, value);
}
}
}
impl From<Gc<List>> for Obj {
fn from(value: Gc<List>) -> Self {
// SAFETY:
// - `value` is an object struct with a base and a type.
// - `value` is GC-allocated.
unsafe { Obj::from_ptr(Gc::into_raw(value).cast()) }
}
}
impl TryFrom<Obj> for Gc<List> {
type Error = Error;
fn try_from(value: Obj) -> Result<Self, Self::Error> {
if unsafe { ffi::mp_type_list.is_type_of(value) } {
// SAFETY: We assume that if `value` is an object pointer with the correct type,
// it is managed by MicroPython GC (see `Gc::from_raw` for details).
let this = unsafe { Gc::from_raw(value.as_ptr().cast()) };
Ok(this)
} else {
Err(Error::InvalidType)
}
}
}