Not sure if the website is being kept still up to date, but www.c2rust.com let’s you try it online. The code is pretty un-idiomatic (using unsafe points instead of references and so on), but note that there is also a refactor step being actively worked on. Based on the video, it doesn’t look like they used that here, but this is where the code lives: https://github.com/immunant/c2rust/tree/master/c2rust-refactor.
Full disclosure: I used to work on this, but I’ve not kept up with developments from the past few months.
Rust intentionally tries to discourage use of raw pointers and pointer arithmetic by not having a syntax sugar for them, so directly translated C code ends up very ugly.
It starts looking OK only after you disambiguate pointers into proper references/slices/optionals. In C it’s not clear whether a pointer argument to a function means 0 or 1, exactly 1, or N elements. Rust has separate types for these cases, and syntax sugar and safety comes with them.
It isn’t immediately clear from the post: is this generated Rust code 100% safe? I mean, I can imagine automatically translating C into unsafe Rust, but that would kind of defeat the purpose. On the other hand, it might make porting easier, if you then manually check and get rid of all the unsafety.
My understanding is that it’s not 100% safe Rust but the unsafe parts are isolated. At least, that’s a goal, iirc. I don’t know how far toward that goal they are. A quick look at the ioq3-rs repo shows a lot of unsafe so they are probably not there yet.
It would be possible to translate the OpenGL2 renderer as well, but it makes significant use of .glsl shader files which the shader compiler compiles down to C source code.
Fascinating, so does ioquake run the vertex transforms on the CPU even though they are written in GLSL?
Also, is there a typo in the flexible array member section? The member vec3_t p[4]; doesn’t look very flexible to me.
I expect that goal of running shaders on CPU was to make it so the OpenGL 2 backend could run on systems that didn’t actually support OpenGL 2. Though now that I write it, it sounds kinda weird.
The member vec3_t p[4]; doesn’t look very flexible to me.
Seems like there might be a misunderstanding here. The OpenGL 2 shader loader does a lot of string mangling with the GLSL code but passes them to the graphics driver for compilation as usual. It doesn’t help that there’s a separate shader_t struct that describes a CPU-side vertex animation. The parser for that format is included in the OpenGL 1 renderer.
I think that’s the point.
You’re right: they cast a larger allocation into winding_t* and access the last member like an array.
Anyone have a snippet of the kind of code that
C2rust
ends up generating? Would be interesting to see how much work cleanup would end up beingI did a fairly deep investigation but it was a while ago, the tools have probably changed since: https://wiki.alopex.li/PortingCToRust
Here is their quake3-rs GitHub repository.
Not sure if the website is being kept still up to date, but www.c2rust.com let’s you try it online. The code is pretty un-idiomatic (using unsafe points instead of references and so on), but note that there is also a refactor step being actively worked on. Based on the video, it doesn’t look like they used that here, but this is where the code lives: https://github.com/immunant/c2rust/tree/master/c2rust-refactor.
Full disclosure: I used to work on this, but I’ve not kept up with developments from the past few months.
Here’s dwm converted with it.
You can see yourself. There’s an online translator: https://c2rust.com/
Rust intentionally tries to discourage use of raw pointers and pointer arithmetic by not having a syntax sugar for them, so directly translated C code ends up very ugly.
It starts looking OK only after you disambiguate pointers into proper references/slices/optionals. In C it’s not clear whether a pointer argument to a function means 0 or 1, exactly 1, or N elements. Rust has separate types for these cases, and syntax sugar and safety comes with them.
It’s a start though! I’d rather start from there, and refactor towards idiomatic than start from scratch in some cases.
It isn’t immediately clear from the post: is this generated Rust code 100% safe? I mean, I can imagine automatically translating C into unsafe Rust, but that would kind of defeat the purpose. On the other hand, it might make porting easier, if you then manually check and get rid of all the unsafety.
My understanding is that it’s not 100% safe Rust but the unsafe parts are isolated. At least, that’s a goal, iirc. I don’t know how far toward that goal they are. A quick look at the ioq3-rs repo shows a lot of
unsafe
so they are probably not there yet.Makes sense. I’m sure they’ll be able to get rid of more unsafes as the project progresses.
Awesome!
Fascinating, so does ioquake run the vertex transforms on the CPU even though they are written in GLSL?
Also, is there a typo in the flexible array member section? The member
vec3_t p[4];
doesn’t look very flexible to me.I expect that goal of running shaders on CPU was to make it so the OpenGL 2 backend could run on systems that didn’t actually support OpenGL 2. Though now that I write it, it sounds kinda weird.
I think that’s the point. XD
Seems like there might be a misunderstanding here. The OpenGL 2 shader loader does a lot of string mangling with the GLSL code but passes them to the graphics driver for compilation as usual. It doesn’t help that there’s a separate
shader_t
struct that describes a CPU-side vertex animation. The parser for that format is included in the OpenGL 1 renderer.You’re right: they cast a larger allocation into
winding_t*
and access the last member like an array.