I wanted to mention some of the problems I've encountered in doing the x86_64
port of Rust and query the opinions of people as to whether there are problems
that need to be fixed and---if so---what is the best remedy.
At various points in the C runtime, we have C types that are intended to be
bit-for-bit compatible with corresponding Rust types. The problem is that the
translation of Rust types into LLVM does not always preserve this
compatibility. Both problems I've encountered so far have had to do with tags.
The first problem arises from simple "enum-like" tags. We were translating
this Rust type:
tag task_result {
/* Variant: tr_success */
tr_success;
/* Variant: tr_failure */
tr_failure;
}
into `enum task_result { tr_success, tr_failure }`. This seems reasonable
except that the C compiler was not allocating 64 bits for an enum but rather
32. Rust always allocates a full word for the variant ID of a tag.
The second problem concerns alignment. This type from comm.rs:
tag chan<uniq T> {
chan_t(task::task, port_id);
}
is translated in C as:
struct chan_handle {
rust_task_id task;
rust_port_id port;
};
(where both rust_task_id and rust_port_id are effectively uint64_t). The rust
tag variant translates to char[16]. While both of these types have the same
SIZE in bytes, they have different alignment properties. This causes problems
because the chan_handle/chan<> is then embedded in a struct, and suddenly the
Rust and C code disagree about the offsets of the various fields.
For now, I've been working around these problems by adjusting the C code.
However, it seems like it would be nice to have a simple way to reproduce C
types in Rust and vice-versa. We're fairly close to it now but some tweaks are
needed.
I don't know what's the best translation for tags. It would be nice if it
matched C enums when there is no associated data (i32, it seems, but we could
check the clang source perhaps). If there is associated data, it would be nice
if it matched unions. Sadly, LLVM does not seem to have a union type in its
type system; clang seems to translate unions into structs with the most highly
aligned variant and then use bitcasts.
Niko
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev