mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-26 23:32:03 +00:00
feat(core/rust): Add obj_module! macro
[no changelog] Co-authored-by: Martin Milata <martin@martinmilata.cz>
This commit is contained in:
parent
420a031a32
commit
36829cfa8f
@ -115,7 +115,10 @@ fn generate_micropython_bindings() {
|
|||||||
.allowlist_function("mp_hal_ticks_ms")
|
.allowlist_function("mp_hal_ticks_ms")
|
||||||
.allowlist_function("mp_hal_delay_ms")
|
.allowlist_function("mp_hal_delay_ms")
|
||||||
// typ
|
// typ
|
||||||
.allowlist_var("mp_type_type");
|
.allowlist_var("mp_type_type")
|
||||||
|
// module
|
||||||
|
.allowlist_type("mp_obj_module_t")
|
||||||
|
.allowlist_var("mp_type_module");
|
||||||
|
|
||||||
// `ffi::mp_map_t` type is not allowed to be `Clone` or `Copy` because we tie it
|
// `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`.
|
// to the data lifetimes with the `MapRef` type, see `src/micropython/map.rs`.
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/// Create an object for an exported function taking 1 arg.
|
||||||
macro_rules! obj_fn_1 {
|
macro_rules! obj_fn_1 {
|
||||||
($f:expr) => {{
|
($f:expr) => {{
|
||||||
#[allow(unused_unsafe)]
|
#[allow(unused_unsafe)]
|
||||||
@ -14,6 +15,7 @@ macro_rules! obj_fn_1 {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create an object for an exported function taking 2 args.
|
||||||
macro_rules! obj_fn_2 {
|
macro_rules! obj_fn_2 {
|
||||||
($f:expr) => {{
|
($f:expr) => {{
|
||||||
#[allow(unused_unsafe)]
|
#[allow(unused_unsafe)]
|
||||||
@ -30,6 +32,7 @@ macro_rules! obj_fn_2 {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create an object for an exported function taking 3 args.
|
||||||
macro_rules! obj_fn_3 {
|
macro_rules! obj_fn_3 {
|
||||||
($f:expr) => {{
|
($f:expr) => {{
|
||||||
#[allow(unused_unsafe)]
|
#[allow(unused_unsafe)]
|
||||||
@ -46,6 +49,7 @@ macro_rules! obj_fn_3 {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create an object for an exported function taking a variable number of args.
|
||||||
macro_rules! obj_fn_var {
|
macro_rules! obj_fn_var {
|
||||||
($min:expr, $max:expr, $f:expr) => {{
|
($min:expr, $max:expr, $f:expr) => {{
|
||||||
#[allow(unused_unsafe)]
|
#[allow(unused_unsafe)]
|
||||||
@ -63,6 +67,7 @@ macro_rules! obj_fn_var {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create an object for an exported function taking key-value args.
|
||||||
macro_rules! obj_fn_kw {
|
macro_rules! obj_fn_kw {
|
||||||
($min:expr, $f:expr) => {{
|
($min:expr, $f:expr) => {{
|
||||||
#[allow(unused_unsafe)]
|
#[allow(unused_unsafe)]
|
||||||
@ -111,6 +116,7 @@ macro_rules! obj_dict {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compose a `Type` object definition.
|
||||||
macro_rules! obj_type {
|
macro_rules! obj_type {
|
||||||
(name: $name:expr,
|
(name: $name:expr,
|
||||||
$(locals: $locals:expr,)?
|
$(locals: $locals:expr,)?
|
||||||
@ -134,8 +140,8 @@ macro_rules! obj_type {
|
|||||||
$(call = Some($call_fn);)?
|
$(call = Some($call_fn);)?
|
||||||
|
|
||||||
// TODO: This is safe only if we pass in `Dict` with fixed `Map` (created by
|
// TODO: This is safe only if we pass in `Dict` with fixed `Map` (created by
|
||||||
// `Map::fixed()`), because only then will Micropython treat `locals_dict` as
|
// `Map::fixed()`, usually through `obj_map!`), because only then will
|
||||||
// immutable, and make the mutable cast safe.
|
// MicroPython treat `locals_dict` as immutable, and make the mutable cast safe.
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
#[allow(unused_assignments)]
|
#[allow(unused_assignments)]
|
||||||
let mut locals_dict = ::core::ptr::null_mut();
|
let mut locals_dict = ::core::ptr::null_mut();
|
||||||
@ -164,3 +170,36 @@ macro_rules! obj_type {
|
|||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct an extmod definition.
|
||||||
|
macro_rules! obj_module {
|
||||||
|
($($key:expr => $val:expr),*) => ({
|
||||||
|
#[allow(unused_unsafe)]
|
||||||
|
unsafe {
|
||||||
|
use $crate::micropython::ffi;
|
||||||
|
|
||||||
|
static DICT: ffi::mp_obj_dict_t = ffi::mp_obj_dict_t {
|
||||||
|
base: ffi::mp_obj_base_t {
|
||||||
|
/// SAFETY: Reasonable to assume the pointer stays valid.
|
||||||
|
type_: unsafe { &ffi::mp_type_dict },
|
||||||
|
},
|
||||||
|
map: Map::from_fixed_static(&[
|
||||||
|
$(
|
||||||
|
Map::at($key, $val),
|
||||||
|
)*
|
||||||
|
])
|
||||||
|
};
|
||||||
|
ffi::mp_obj_module_t {
|
||||||
|
base: ffi::mp_obj_base_t {
|
||||||
|
type_: &ffi::mp_type_module,
|
||||||
|
},
|
||||||
|
// This is safe only because we are passing in a static dict with fixed `Map`
|
||||||
|
// (created by `Map::from_fixed_static()`). Only then will MicroPython treat
|
||||||
|
// `globals` as immutable, making the mutable cast safe.
|
||||||
|
globals: &DICT as *const _ as *mut _,
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
($($key:expr => $val:expr),* ,) => ({
|
||||||
|
obj_module!($($key => $val),*)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -10,6 +10,7 @@ pub mod gc;
|
|||||||
pub mod iter;
|
pub mod iter;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
pub mod map;
|
pub mod map;
|
||||||
|
pub mod module;
|
||||||
pub mod obj;
|
pub mod obj;
|
||||||
pub mod qstr;
|
pub mod qstr;
|
||||||
pub mod runtime;
|
pub mod runtime;
|
||||||
|
6
core/embed/rust/src/micropython/module.rs
Normal file
6
core/embed/rust/src/micropython/module.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
use super::ffi;
|
||||||
|
|
||||||
|
pub type Module = ffi::mp_obj_module_t;
|
||||||
|
|
||||||
|
// SAFETY: We are in a single-threaded environment.
|
||||||
|
unsafe impl Sync for Module {}
|
Loading…
Reference in New Issue
Block a user