[tor-bugs] #24249 [Core Tor/Tor]: Create automated mechanism for C/Rust types to stay in sync

Tor Bug Tracker & Wiki blackhole at torproject.org
Sat Jun 23 03:50:06 UTC 2018


#24249: Create automated mechanism for C/Rust types to stay in sync
--------------------------+-----------------------------------
 Reporter:  chelseakomlo  |          Owner:  chelseakomlo
     Type:  enhancement   |         Status:  needs_information
 Priority:  Medium        |      Milestone:
Component:  Core Tor/Tor  |        Version:
 Severity:  Normal        |     Resolution:
 Keywords:  rust          |  Actual Points:
Parent ID:                |         Points:
 Reviewer:  isis          |        Sponsor:
--------------------------+-----------------------------------

Comment (by chelseakomlo):

 Ok, here is the overall difference between using bindgen (C to Rust) or a
 custom tool (Rust to C).

 == Bindgen (C to Rust):

 Takes C data types and generates FFI bindings for them. https://rust-lang-
 nursery.github.io/rust-bindgen

 As shown in their documentation, a struct in C such as:
 {{{
 typedef struct Person {
     int height;
     char *name;
 } Person;
 }}}

 Becomes in Rust:
 {{{
 #[repr(C)]
 #[derive(Debug, Copy)]
 pub struct Person {
     pub height: ::std::os::raw::c_int,
     pub name: *mut ::std::os::raw::c_char,
 }
 }}}

 and a constant in C

 {{{
 #define PERSON_NAME "HELLO";
 }}}

 becomes in Rust:
 {{{
 pub const PERSON_NAME: &'static [u8; 6usize] = b"HELLO\x00";
 }}}

 If we were to use bindgen, we could generate types, but we would still
 need to write wrapper "glue" to translate specific libc types into Rust
 types (such as a *mut c_char into a String, smartlists into vectors, etc).

 Advantages of using bindgen:
 - Using a library we don't have to maintain
 - Ability to autogenerate multiple types (functions, structs, enums, etc).

 Disadvantages of using bindgen:
 - Hand-writing FFI type translation code
 - More FFI code which is unsafe and (for now) often requires copies

 == Custom library (Rust to C):
 (something like `http://github.com/chelseakomlo/types-parser`)

 Takes Rust data types and generates C equivilant types.

 For example, a struct in Rust such as:
 {{{
 struct Person {
     height: i32,
     name: String,
 }
 }}}

 could be autogenerated to the following struct in C:
 {{{
 typedef struct Person {
     int height;
     char *name;
 } Person;
 }}}

 and a constant in Rust:

 {{{
 const FIRST_CONTSTANT: &'static str = "first_constant";
 }}}

 becomes in C:
 {{{
 #define FIRST_CONTSTANT first_constant
 }}}

 Advantages of using a custom library:
 - Compile types into Rust and C without further translation/error handling
 code

 Disadvantages of using a custom library:
 - Maintain our own library
 - Effort to scale out features. Currently supporting only constants is
 simple, but adding new data types will be effort. (for example, structs
 with smartlists as fields won't be the easiest to compile, I think)

 == Overall Thoughts:

 While I'm not crazy about maintaining our own library, I do prefer the
 option of being able to cleanly keep Rust and C types separate without the
 need to hand write FFI type-conversion glue. However, both approaches
 certainly have drawbacks, and overall this effort should be minimal as we
 are striving to keep the Rust/C FFI interface small to begin with.

 Considering currently we mainly need to keep constants and enums in sync,
 both options are relatively equal. The complexity for both increases for
 more complex of data types to keep in sync.

--
Ticket URL: <https://trac.torproject.org/projects/tor/ticket/24249#comment:9>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online


More information about the tor-bugs mailing list