Skip to content

Commit 0184ca8

Browse files
committed
perf(core): rewrite trezor.log and trezor.wire_log in Rust
Requires trezor/micropython#26. [no changelog]
1 parent 1780664 commit 0184ca8

File tree

16 files changed

+167
-147
lines changed

16 files changed

+167
-147
lines changed

core/embed/rust/build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ fn generate_micropython_bindings() {
224224
.allowlist_function("mp_obj_new_attrtuple")
225225
.allowlist_function("mp_obj_get_int_maybe")
226226
.allowlist_function("mp_obj_is_true")
227+
.allowlist_function("mp_obj_get_type_str")
227228
.allowlist_function("mp_call_function_n_kw")
228229
.allowlist_function("trezor_obj_get_ll_checked")
229230
.allowlist_function("trezor_obj_str_from_rom_text")
@@ -286,6 +287,7 @@ fn generate_micropython_bindings() {
286287
.allowlist_function("mp_hal_delay_ms")
287288
// debug
288289
.allowlist_function("mp_print_strn")
290+
.allowlist_function("str_modulo_format")
289291
.allowlist_var("mp_plat_print")
290292
// typ
291293
.allowlist_var("mp_type_type")

core/embed/rust/librust.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ extern mp_obj_module_t mp_module_trezorble;
1414

1515
#if !PYOPT
1616
mp_obj_t ui_debug_layout_type();
17+
extern mp_obj_module_t mp_module_trezorlog;
1718

1819
#ifdef TREZOR_EMULATOR
1920
extern mp_obj_module_t mp_module_coveragedata;

core/embed/rust/librust_qstr.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ static void _librust_qstrs(void) {
249249
MP_QSTR_danger;
250250
MP_QSTR_data_hash;
251251
MP_QSTR_data_len;
252+
MP_QSTR_debug;
252253
MP_QSTR_decode;
253254
MP_QSTR_deinit;
254255
MP_QSTR_description;
@@ -265,6 +266,7 @@ static void _librust_qstrs(void) {
265266
MP_QSTR_entropy__title_confirm;
266267
MP_QSTR_erase;
267268
MP_QSTR_erase_bonds;
269+
MP_QSTR_error;
268270
MP_QSTR_experimental_mode__enable;
269271
MP_QSTR_experimental_mode__only_for_dev;
270272
MP_QSTR_experimental_mode__title;
@@ -309,6 +311,7 @@ static void _librust_qstrs(void) {
309311
MP_QSTR_homescreen__title_set;
310312
MP_QSTR_horizontal;
311313
MP_QSTR_icon_name;
314+
MP_QSTR_iface;
312315
MP_QSTR_iface_num;
313316
MP_QSTR_image;
314317
MP_QSTR_indeterminate;
@@ -757,6 +760,7 @@ static void _librust_qstrs(void) {
757760
MP_QSTR_touch_event;
758761
MP_QSTR_trace;
759762
MP_QSTR_trezorble;
763+
MP_QSTR_trezorlog;
760764
MP_QSTR_trezorproto;
761765
MP_QSTR_trezorui_api;
762766
MP_QSTR_tutorial;
@@ -798,6 +802,7 @@ static void _librust_qstrs(void) {
798802
MP_QSTR_verb_info;
799803
MP_QSTR_verify;
800804
MP_QSTR_version;
805+
MP_QSTR_warning;
801806
MP_QSTR_warning_footer;
802807
MP_QSTR_wipe__info;
803808
MP_QSTR_wipe__title;

core/embed/rust/micropython.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "py/mphal.h"
33
#include "py/nlr.h"
44
#include "py/obj.h"
5+
#include "py/objstr.h"
56
#include "py/runtime.h"
67

78
#include "../upymod/trezorobj.h"
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
use core::str::from_utf8;
2+
3+
use crate::{
4+
error::Error,
5+
micropython::{
6+
buffer::StrBuffer, map::Map, module::Module, obj::Obj, print::print, qstr::Qstr, util,
7+
},
8+
strutil,
9+
trezorhal::time::ticks_ms,
10+
};
11+
12+
fn _log(level: &str, args: &[Obj], kwargs: &Map) -> Result<Obj, Error> {
13+
let [module, fmt, fmt_args @ ..] = args else {
14+
return Err(Error::TypeError);
15+
};
16+
{
17+
let millis = ticks_ms();
18+
let seconds = millis / 1000;
19+
let mut millis_str = [b'0'; 3];
20+
let len = unwrap!(strutil::format_i64((millis % 1000).into(), &mut millis_str)).len();
21+
millis_str.rotate_left(len);
22+
let log_prefix = uformat!(len: 128, "{}.{} \x1b[35m{}\x1b[0m \x1b[{}\x1b[0m ",
23+
seconds, unwrap!(from_utf8(&millis_str)), StrBuffer::try_from(*module)?.as_ref(), level,
24+
);
25+
print(&log_prefix);
26+
}
27+
28+
if let Ok(iface_obj) = kwargs.get(Qstr::MP_QSTR_iface) {
29+
if iface_obj != Obj::const_none() {
30+
let iface_type = iface_obj.type_().ok_or(Error::TypeError)?;
31+
let iface_prefix = uformat!(len: 128, "\x1b[93m[{}]\x1b[0m ", iface_type.name());
32+
print(&iface_prefix);
33+
}
34+
}
35+
36+
let msg: StrBuffer = util::modulo_format(*fmt, fmt_args)?.try_into()?;
37+
print(msg.as_ref());
38+
print("\n");
39+
Ok(Obj::const_none())
40+
}
41+
42+
extern "C" fn py_debug(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
43+
let block = |args: &[Obj], kwargs: &Map| _log("32mDEBUG", args, kwargs);
44+
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
45+
}
46+
47+
extern "C" fn py_info(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
48+
let block = |args: &[Obj], kwargs: &Map| _log("36mINFO", args, kwargs);
49+
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
50+
}
51+
52+
extern "C" fn py_warning(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
53+
let block = |args: &[Obj], kwargs: &Map| _log("33mWARNING", args, kwargs);
54+
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
55+
}
56+
57+
extern "C" fn py_error(n_args: usize, args: *const Obj, kwargs: *mut Map) -> Obj {
58+
let block = |args: &[Obj], kwargs: &Map| _log("31mERROR", args, kwargs);
59+
unsafe { util::try_with_args_and_kwargs(n_args, args, kwargs, block) }
60+
}
61+
62+
#[no_mangle]
63+
#[rustfmt::skip]
64+
pub static mp_module_trezorlog: Module = obj_module! {
65+
Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorlog.to_obj(),
66+
67+
/// mock:global
68+
69+
/// def debug(name: str, msg: str, *args: Any, *, iface: WireInterface | None = None) -> None:
70+
/// ...
71+
Qstr::MP_QSTR_debug => obj_fn_kw!(2, py_debug).as_obj(),
72+
73+
/// def info(name: str, msg: str, *args: Any, *, iface: WireInterface | None = None) -> None:
74+
/// ...
75+
Qstr::MP_QSTR_info => obj_fn_kw!(2, py_info).as_obj(),
76+
77+
/// def warning(name: str, msg: str, *args: Any, *, iface: WireInterface | None = None) -> None:
78+
/// ...
79+
Qstr::MP_QSTR_warning => obj_fn_kw!(2, py_warning).as_obj(),
80+
81+
/// def error(name: str, msg: str, *args: Any, *, iface: WireInterface | None = None) -> None:
82+
/// ...
83+
Qstr::MP_QSTR_error => obj_fn_kw!(2, py_error).as_obj(),
84+
};

core/embed/rust/src/micropython/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,8 @@ pub mod simple_type;
1919
pub mod typ;
2020
pub mod util;
2121

22+
#[cfg(feature = "debug")]
23+
pub mod logging;
24+
2225
#[cfg(test)]
2326
pub mod testutil;

core/embed/rust/src/micropython/util.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,9 @@ where
148148
}
149149
Ok(vec)
150150
}
151+
152+
pub fn modulo_format(format: Obj, args: &[Obj]) -> Result<Obj, Error> {
153+
catch_exception(|| unsafe {
154+
ffi::str_modulo_format(format, args.len(), args.as_ptr(), Obj::const_none())
155+
})
156+
}

core/embed/upymod/qstrdefsport.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -742,8 +742,6 @@ Q(trezor.enums.DebugButton)
742742
Q(trezor.enums.DebugPhysicalButton)
743743
Q(trezor.enums.DebugSwipeDirection)
744744
Q(trezor.enums.DebugWaitType)
745-
Q(trezor.wire.wire_log)
746-
Q(wire_log)
747745
#endif
748746

749747
// generate full alphabet

core/embed/upymod/rustmods.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,7 @@ MP_REGISTER_MODULE(MP_QSTR_trezorble, mp_module_trezorble);
3939
#if defined(TREZOR_EMULATOR) && PYOPT == 0
4040
MP_REGISTER_MODULE(MP_QSTR_coveragedata, mp_module_coveragedata);
4141
#endif
42+
43+
#if !PYOPT
44+
MP_REGISTER_MODULE(MP_QSTR_trezorlog, mp_module_trezorlog);
45+
#endif

core/mocks/generated/trezorlog.pyi

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from typing import *
2+
3+
4+
# rust/src/micropython/logging.rs
5+
def debug(name: str, msg: str, *args: Any, *, iface: WireInterface | None = None) -> None:
6+
...
7+
8+
9+
# rust/src/micropython/logging.rs
10+
def info(name: str, msg: str, *args: Any, *, iface: WireInterface | None = None) -> None:
11+
...
12+
13+
14+
# rust/src/micropython/logging.rs
15+
def warning(name: str, msg: str, *args: Any, *, iface: WireInterface | None = None) -> None:
16+
...
17+
18+
19+
# rust/src/micropython/logging.rs
20+
def error(name: str, msg: str, *args: Any, *, iface: WireInterface | None = None) -> None:
21+
...

0 commit comments

Comments
 (0)