Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Rust FFI #1540

Merged
merged 1 commit into from
May 5, 2021
Merged

Add Rust FFI #1540

merged 1 commit into from
May 5, 2021

Conversation

jpochyla
Copy link
Contributor

@jpochyla jpochyla commented Mar 23, 2021

Adds Rust code, together with bindings to MicroPython and some parts of trezorhal.

Needs nightly Rust for the following reasons:

  • #![feature(never_type)] - Used later in the UI layout PR. Possible to get rid of by replacing with an empty enum.
  • #![feature(unsize)], #![feature(coerce_unsized)], #![feature(dispatch_from_dyn)] used in the Gc type to allow boxing unsized values. Needs further investigation, but probably possible to get rid of if we use regular Box with a global allocator plugged into the MicroPython GC.
  • Cargo features = ["host_dep"], solved with the new resolver in Rust 1.51, we can get rid of this easily.

Copy link
Member

@mmilata mmilata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exciting stuff! I'm probably not skilled enough in unsafe Rust & micropython internals to say whether it's safe to merge, would definitely like more people to go through the code, but I guess with enough testing we should be fine? Anyway I left some questions and nitpicks in couple of places.

Also, there's a couple of TODOs, can you please go through them to see if there are any that are critical to resolve before merging?

core/SConscript.unix Outdated Show resolved Hide resolved
core/embed/rust/.gitignore Outdated Show resolved Hide resolved
"-DTREZOR_MODEL=T",
"-DSTM32F405xx",
"-DUSE_HAL_DRIVER",
"-DSTM32_HAL_H=<stm32f4xx.h>",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: add branch with correct defines for T1 (and includes for STM32F2). Test on hw.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, didn't think about T1 too much yet.

core/embed/rust/build.rs Show resolved Hide resolved
core/embed/rust/src/error.rs Show resolved Hide resolved
core/embed/rust/src/micropython/map.rs Show resolved Hide resolved
core/embed/rust/src/micropython/map.rs Show resolved Hide resolved
core/embed/rust/src/micropython/buffer.rs Outdated Show resolved Hide resolved
use super::ffi;

pub struct IterBuf {
iter_buf: ffi::mp_obj_iter_buf_t,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If anyone like me has no idea how micropython iterators work, this is somewhat helpful: https://micropython-usermod.readthedocs.io/en/latest/usermods_11.html


pub fn raise_value_error(msg: &'static CStr) -> ! {
unsafe {
ffi::mp_raise_ValueError(msg.as_ptr());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As previously discussed, I'm wondering whether exceptions raised in python code called from rust cannot bite us in some way. IIUC this means we cannot rely on destructors (Drop::drop()) always being executed. It shouldn't lead to memory leaks since heap is managed by micropython GC, but we have to keep this in mind & review all dependencies whether they rely on Drop for correctness.

Is it feasible to install exception handler (nlr_push()) every time we call rust->python and either panic when caught (imho reasonable for allocation failures), or choose to propagate the exception using Results to the underlying caller?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be feasible, yes. There is some performance hit, but if we're actually calling Python it won't be relatively big, and we could replace the cases of C code that only sometimes call Python or raise exceptions themselves, like most of the conversion methods, with our non-raising variants.

More about leaking here: https://doc.rust-lang.org/nomicon/leaking.html

@jpochyla
Copy link
Contributor Author

jpochyla commented Apr 15, 2021

I've added some commentary and marked the corresponding conversations as resolved. TODO comments are there, I went through them and think that these are all fine at this stage.

core/embed/rust/src/lib.rs Show resolved Hide resolved
core/embed/rust/src/micropython/buffer.rs Show resolved Hide resolved
core/embed/rust/src/micropython/buffer.rs Outdated Show resolved Hide resolved
core/embed/rust/src/micropython/buffer.rs Outdated Show resolved Hide resolved
core/embed/rust/src/micropython/dict.rs Show resolved Hide resolved
core/embed/rust/src/micropython/gc.rs Show resolved Hide resolved
core/embed/rust/src/micropython/iter.rs Outdated Show resolved Hide resolved
core/embed/rust/src/micropython/list.rs Show resolved Hide resolved
core/embed/rust/src/micropython/list.rs Outdated Show resolved Hide resolved
core/embed/rust/src/micropython/macros.rs Show resolved Hide resolved
core/embed/rust/src/micropython/map.rs Show resolved Hide resolved
core/embed/rust/src/micropython/map.rs Show resolved Hide resolved
core/embed/rust/src/micropython/dict.rs Outdated Show resolved Hide resolved
core/embed/rust/src/micropython/map.rs Outdated Show resolved Hide resolved
core/embed/rust/src/micropython/map.rs Show resolved Hide resolved
core/embed/rust/src/micropython/obj.rs Outdated Show resolved Hide resolved
core/embed/rust/src/micropython/obj.rs Show resolved Hide resolved
core/embed/extmod/trezorobj.c Outdated Show resolved Hide resolved
core/embed/rust/src/micropython/typ.rs Show resolved Hide resolved
core/embed/rust/src/trezorhal/display.rs Show resolved Hide resolved
@matejcik matejcik force-pushed the rust-micropython-ffi branch from 333809c to b310f0c Compare May 5, 2021 12:17
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:
https://github.com/rust-embedded/cortex-m-rt/blob/599c58db70c5dd4eb1dfb92e1dad7c80ed848937/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
@matejcik matejcik force-pushed the rust-micropython-ffi branch from b310f0c to d8cb55f Compare May 5, 2021 12:20
@matejcik matejcik merged commit 6257584 into master May 5, 2021
@matejcik matejcik deleted the rust-micropython-ffi branch May 5, 2021 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants