Gankra / abi-cafe

Pair your compilers up at The ABI Cafe!
https://faultlore.com/abi-cafe/book/
225 stars 15 forks source link

add tagged union support to the C backend? #28

Open Gankra opened 4 months ago

Gankra commented 4 months ago

Currently the C backend bails out everywhere it finds a rust-like tagged union:

https://github.com/Gankra/abi-cafe/blob/6ba68656bd74d05692e3abb83a51a0bfc2b7ce32/src/abis/c/declare.rs#L259-L267

This is fair since C doesn't have any such notion, but, RFC#2195 "really tagged unions" exists precisely to define the layouts of tagged unions when you slap repr(C), repr(u8) or repr(C, u8) on a rust tagged union.

This is implemented by cbindgen and used by firefox's webrender bindings.

I am a bit on the fence as to whether it is in scope for abi-cafe to provide this feature. If you did provide it you'd have to do some careful and tedious analysis of the attributes on the tagged union since repr(u8) and repr(C) have substantially different layouts.

Gankra commented 4 months ago

A quick TL;DR of the RFC:

The repr(C) layout is the most obvious lowering to a struct containing a c-style enum and a union. The enum says which case of the union is currently valid.

The repr(u8) layout (also repr(u32), etc.) is similar but the enum specifically has that integer type, and instead of being stored in a wrapper struct it's stored as the first field of every variant of the union. This is a more compact layout because space doesn't need to be wasted for padding between the enum and the union. Also it's more reliable because C refuses to specify what the backing integer of a normal enum is so rustc just guesses based on the platform.

repr(C, u8) says to use the tag size of repr(u8) but the layout of repr(C).