mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-31 18:40:56 +00:00
refactor(core/rust): expose obj types and (debug only) type names
This commit is contained in:
parent
ccddc8f5f3
commit
b91e225076
@ -222,6 +222,8 @@ fn generate_micropython_bindings() {
|
||||
// module
|
||||
.allowlist_type("mp_obj_module_t")
|
||||
.allowlist_var("mp_type_module")
|
||||
// qstr
|
||||
.allowlist_function("qstr_data")
|
||||
// `ffi::mp_map_t` type is not allowed to be `Clone` or `Copy` because we tie it
|
||||
// to the data lifetimes with the `MapRef` type, see `src/micropython/map.rs`.
|
||||
// TODO: We should disable `Clone` and `Copy` for all types and only allow-list
|
||||
|
@ -441,4 +441,21 @@ impl Obj {
|
||||
let is_type_str = unsafe { ffi::mp_type_str.is_type_of(self) };
|
||||
is_type_str || self.is_qstr()
|
||||
}
|
||||
|
||||
pub fn type_<'a>(self) -> Option<&'a super::typ::Type> {
|
||||
if self.is_ptr() {
|
||||
// SAFETY:
|
||||
// Safe for pointers, for as long as MicroPython behaves sanely.
|
||||
// We assume that:
|
||||
// * The pointer is a valid MicroPython object, which has `ObjBase`
|
||||
// as its first element.
|
||||
// * The type pointer points to a valid type object.
|
||||
// * The pointee has a 'static lifetime, i.e., either is
|
||||
// ROM-based, or GC allocated.
|
||||
let base = self.as_ptr() as *const ObjBase;
|
||||
unsafe { (*base).type_.as_ref() }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,11 @@
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use core::convert::TryFrom;
|
||||
use core::{convert::TryFrom, slice, str::from_utf8};
|
||||
|
||||
use crate::{error::Error, micropython::obj::Obj};
|
||||
use crate::error::Error;
|
||||
|
||||
use super::{ffi, obj::Obj};
|
||||
|
||||
impl Qstr {
|
||||
pub const fn to_obj(self) -> Obj {
|
||||
@ -30,6 +32,19 @@ impl Qstr {
|
||||
// TODO: Change the internal representation of Qstr to u16.
|
||||
Self(val as _)
|
||||
}
|
||||
|
||||
pub fn as_str(self) -> &'static str {
|
||||
let mut len = 0usize;
|
||||
let slice = unsafe {
|
||||
// SAFETY: qstr_data should always return a valid string, even for unknown ids.
|
||||
let ptr = ffi::qstr_data(self.0 as _, &mut len as *mut _);
|
||||
slice::from_raw_parts(ptr, len)
|
||||
};
|
||||
// SAFETY: Qstr pools are either ROM-based or permanently allocated in the GC
|
||||
// arena. The MicroPython runtime holds the respective head pointers so we don't
|
||||
// need to care.
|
||||
unwrap!(from_utf8(slice))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u16> for Qstr {
|
||||
|
@ -7,21 +7,22 @@ pub type Type = ffi::mp_obj_type_t;
|
||||
|
||||
impl Type {
|
||||
pub fn is_type_of(&'static self, obj: Obj) -> bool {
|
||||
if obj.is_ptr() {
|
||||
// SAFETY: If `obj` is a pointer, it should always point to an object having
|
||||
// `ObjBase` as the first field, making this cast safe.
|
||||
unsafe {
|
||||
let base = obj.as_ptr() as *const ObjBase;
|
||||
(*base).type_ == self
|
||||
}
|
||||
} else {
|
||||
false
|
||||
match obj.type_() {
|
||||
Some(type_) => core::ptr::eq(type_, self),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn as_base(&'static self) -> ObjBase {
|
||||
ObjBase { type_: self }
|
||||
}
|
||||
|
||||
#[cfg(feature = "debug")]
|
||||
pub fn name(&self) -> &'static str {
|
||||
use super::qstr::Qstr;
|
||||
|
||||
Qstr::from(self.name).as_str()
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: We are in a single-threaded environment.
|
||||
|
Loading…
Reference in New Issue
Block a user