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

Reply via email to