mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-13 01:58:08 +00:00

Features `micropython` and `protobuf` are defined. Protobuf implies micropython because our protobuf impl is pretty much _for_ micropython. The respective subdirs are included only if the matching feature is defined. util.rs is moved to micropython because it mostly concerns micropython interop ResultExt, useful only for ui_debug, is moved to ui::util. A new module `trezorhal::time` is provided. It mirrors functionality of `micropython::time` via stmlib functions. The intended use is to always use functions from `trezorhal::time`. The right micropython variants are used when micropython is available, otherwise the pure stmlib versions are called. ui::*::layout is conditional for micropython feature, because it only concerns micropython layouts. If we want to reuse layouts defined there, we will need to export them to not depend on Objs and Qstrs etc.
84 lines
2.5 KiB
Rust
84 lines
2.5 KiB
Rust
use core::slice;
|
|
|
|
use crate::{
|
|
error::Error,
|
|
micropython::{
|
|
map::{Map, MapElem},
|
|
obj::Obj,
|
|
runtime::raise_exception,
|
|
},
|
|
};
|
|
|
|
/// Perform a call and convert errors into a raised MicroPython exception.
|
|
/// Should only called when returning from Rust to C. See `raise_exception` for
|
|
/// details.
|
|
pub unsafe fn try_or_raise<T>(func: impl FnOnce() -> Result<T, Error>) -> T {
|
|
func().unwrap_or_else(|err| unsafe {
|
|
raise_exception(err);
|
|
})
|
|
}
|
|
|
|
/// Extract kwargs from a C call and pass them into Rust. Raise exception if an
|
|
/// error occurs. Should only called when returning from Rust to C. See
|
|
/// `raise_exception` for details.
|
|
pub unsafe fn try_with_kwargs(
|
|
kwargs: *const Map,
|
|
func: impl FnOnce(&Map) -> Result<Obj, Error>,
|
|
) -> Obj {
|
|
let block = || {
|
|
let kwargs = unsafe { kwargs.as_ref() }.ok_or(Error::MissingKwargs)?;
|
|
|
|
func(kwargs)
|
|
};
|
|
unsafe { try_or_raise(block) }
|
|
}
|
|
|
|
/// Extract args and kwargs from a C call and pass them into Rust. Raise
|
|
/// exception if an error occurs. Should only called when returning from Rust to
|
|
/// C. See `raise_exception` for details.
|
|
pub unsafe fn try_with_args_and_kwargs(
|
|
n_args: usize,
|
|
args: *const Obj,
|
|
kwargs: *const Map,
|
|
func: impl FnOnce(&[Obj], &Map) -> Result<Obj, Error>,
|
|
) -> Obj {
|
|
let block = || {
|
|
let args = if args.is_null() {
|
|
&[]
|
|
} else {
|
|
unsafe { slice::from_raw_parts(args, n_args) }
|
|
};
|
|
let kwargs = unsafe { kwargs.as_ref() }.ok_or(Error::MissingKwargs)?;
|
|
|
|
func(args, kwargs)
|
|
};
|
|
unsafe { try_or_raise(block) }
|
|
}
|
|
|
|
/// Extract args and kwargs from a C call where args and kwargs are inlined, and
|
|
/// pass them into Rust. Raise exception if an error occurs. Should only called
|
|
/// when returning from Rust to C. See `raise_exception` for details.
|
|
pub unsafe fn try_with_args_and_kwargs_inline(
|
|
n_args: usize,
|
|
n_kw: usize,
|
|
args: *const Obj,
|
|
func: impl FnOnce(&[Obj], &Map) -> Result<Obj, Error>,
|
|
) -> Obj {
|
|
let block = || {
|
|
let args_slice: &[Obj];
|
|
let kwargs_slice: &[MapElem];
|
|
|
|
if args.is_null() {
|
|
args_slice = &[];
|
|
kwargs_slice = &[];
|
|
} else {
|
|
args_slice = unsafe { slice::from_raw_parts(args, n_args) };
|
|
kwargs_slice = unsafe { slice::from_raw_parts(args.add(n_args).cast(), n_kw) };
|
|
}
|
|
|
|
let kw_map = Map::from_fixed(kwargs_slice);
|
|
func(args_slice, &kw_map)
|
|
};
|
|
unsafe { try_or_raise(block) }
|
|
}
|