
Translating Quake 3 into Rust - K0nserv
https://immunant.com/blog/2020/01/quake3/
======
floatingatoll
One highlight of this post is their work exposing a memory safety error in the
original source code:

> _The Rust compiler also flagged a similar but actually buggy example in
> G_TryPushingEntity where the conditional is >, not >=. The out of bounds
> pointer was then dereferenced after the conditional, which is an actual
> memory safety bug._

~~~
Avamander
Interestingly I've too found bugs in original source similar to this when
rewriting in just TypeScript, so I suspect it's just someone taking a look
that allows the bug to be discovered.

~~~
ShorsHammer
Sourcecode?

~~~
floatingatoll
Linked from that paragraph in the article.

~~~
vijaybritto
I think they are asking for the Typescript source

------
ahomescu1
Author here: I wanted to let everyone know we made some small edits to the
text, and added two new branches to our repository: _transpiled_ containing
the raw transpiler output [1], and _refactored_ containing the same code [2]
after a few refactoring commands.

1\.
[https://github.com/immunant/ioq3/tree/transpiled/quake3-rs](https://github.com/immunant/ioq3/tree/transpiled/quake3-rs)

2\.
[https://github.com/immunant/ioq3/tree/refactored/quake3-rs](https://github.com/immunant/ioq3/tree/refactored/quake3-rs)

~~~
phkahler
Is there any progress on C++ to Rust? I know the whole language is huge, so
maybe even a little support could be opening a can of worms.

~~~
simcop2387
Most of the language probably isn't too far from C to be done, but I can't
even guess at what would have to be done for C++'s templates.

~~~
zozbot234
The closest Rusty feature to C++ templates is most likely macros. I don't
think even const generics, specialization etc. (which are WIP anyway at the
moment) would be enough to replicate templates in the fully general case.

~~~
heavenlyblue
I most surely misunderstand something: why are templates not replaceable with
Rust generics?

~~~
mathw
The simple answer is that C++ templates can do more than Rust generics can,
including some things that in Rust you'd use the macro system for, and
probably some things that you'd have to translate by expanding out the
template and turning that result into Rust.

------
wyldfire
I recall seeing a presentation of c2rust by Andrei at a conference a while
back. It's great to hear that it's making good progress. I'm curious at how
good c2rust is at producing idiomatic rust code. It seems like that would be
difficult and yet very valuable.

> we'd love to hear what you want to see translated next.

qemu [1] is all in C (probably C89 or "gnu89") and would make an interesting
project, IMO.

[1] [https://github.com/qemu/qemu](https://github.com/qemu/qemu)

~~~
smolder
The long tail of patterns c2rust would need to recognize to reliably make
_idiomatic_ code seems like a much larger problem. With that as the goal, it
might make sense to build a separate rust-to-rust "idiomaticizer" that can
recognize opportunities to reduce code complexity through refactoring, and
apply idiomatic patterns without changing application behavior.

~~~
harpocrates
As I've already posted elsewhere on this thread, such a tool has been
developed in parallel (and with the intent to consume the output of) c2rust.
Development on that occurs here:
[https://github.com/immunant/c2rust/tree/master/c2rust-
refact...](https://github.com/immunant/c2rust/tree/master/c2rust-refactor).

~~~
smolder
Thanks, I hadn't seen this by the time I posted. Very cool.

------
giovannibajo1
Out of curiosity, how do compilation times look, for a fresh build and for the
edit-compile cycle?

------
tombert
Out of curiosity, has anyone here tried taking something like Quake 2 or 3 and
porting it to run on the JVM?

This project kind of makes me want to try porting Quake 3 into Clojure, but I
want to know the limitations in doing so.

~~~
cs02rm0
I'd imagine the graphics libraries is where the JVM falls down.

~~~
flatiron
Not that Minecraft runs well or is a marvel of graphical technology but at
least it proves you can do FPS 3D with the JVM enough to the the most popular
game around.

~~~
phit_
Minecraft uses [https://www.lwjgl.org/](https://www.lwjgl.org/)

------
arendtio
I would love to see them translating the Linux kernel, but that might be a bit
too ambitious.

------
jtaft
This is some awesome PR too! Didn't expect them to be a software security
consultancy.

~~~
steveklabnik
Some of this work was even funded by DARPA...

------
kstenerud
That's super cool!

What I'd really like to see is benchmarks that compare the rust version to C.

~~~
AdmiralAsshat
What is the realistic best-case scenario? Has anyone demonstrated that well-
written Rust code should run _faster_ than C, or is the hope simply to get
performance parity with C while maintaining memory safety?

~~~
almindor
Rust will outperform C consistently soon. It already does in some cases. It
will also do so with safe idiomatic code in most cases. The reason behind my
statement is simply more opportunity for the optimizer. Rusts rules allow for
a more aggressive optimization. The reasons why it's not outperforming C yet
are LLVM bugs and some missing Rust language features and fixes. LLVM in
particular is driven by C needs so they rarely fix bugs present only Rustc
generated IR.

~~~
dodobirdlord
This is grey, but shouldn’t be. I assume people are downing it because it
doesn’t give examples of the optimization opportunities it claims. So here are
two that I think are likely most significant.

1\. Rust’s aliasing semantics are more powerful than C’s unless you use the
‘restrict’ keyword everywhere, which most people don’t. It’s well recognized
that FORTRAN continues to generally outperform C in many numeric applications
because FORTRAN compilers are free to perform optimizations that C compilers
cannot or don’t, due to the fact that multi-aliasing memory is undefined
behavior in FORTRAN. The rust compiler currently doesn’t pass the relevant
hints to the generated LLVM IR due to a long history of LLVM having bugs in
‘noalias’ handling, in large part due to the fact that those code paths are so
rarely executed while compiling C code, itself due to the relatively low usage
of the ‘restrict’ keyword.

2\. Implicit arena allocations. The Rust compiler has access to information
about possible aliasing and overlapping lifetimes that it can use to replace
multiple allocations with similar lifetimes with offsets into a single
allocation that is then all freed together. This is a complicated topic, but
work is ongoing to make this a reality.

~~~
jashmatthews
2 might sound overly optimistic like "Rust will eventually beat C" but V8
already has an allocation folding optimization which combines multiple objects
into a single site. There's also run time profiling to try and figure out the
allocation lifetime.

[https://static.googleusercontent.com/media/research.google.c...](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/42478.pdf)
and
[https://static.googleusercontent.com/media/research.google.c...](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43823.pdf)

------
bbmario
Is the final code readable/maintainable?

~~~
ahomescu1
We added the transpiled code in a new branch at
[https://github.com/immunant/ioq3/tree/transpiled/quake3-rs](https://github.com/immunant/ioq3/tree/transpiled/quake3-rs)
and also a more cleaned up refactored code base at
[https://github.com/immunant/ioq3/tree/refactored/quake3-rs](https://github.com/immunant/ioq3/tree/refactored/quake3-rs)

------
Waffle5
Would be interested in a performance comparison - c (using opengl1, etc etc)
vs c2rust.

------
willvarfar
It would be really cool to see snippets or even the whole original and
transpiled code side-by-side.

When I was working on compilers I spent as much time making such a script in a
web-browser with scrolling etc as I did studying the results.

~~~
ahomescu1
We added the transpiled code in a new branch at
[https://github.com/immunant/ioq3/tree/transpiled/quake3-rs](https://github.com/immunant/ioq3/tree/transpiled/quake3-rs)
and also a more cleaned up refactored code base at
[https://github.com/immunant/ioq3/tree/refactored/quake3-rs](https://github.com/immunant/ioq3/tree/refactored/quake3-rs)

------
faebi
Does it mean we could translate languages like Ruby and Python to Rust?

~~~
K0nserv
While it might be possible my guess is it would be much more difficult than C.
AFAIK Rust is more or less a superset of C whereas Python and Ruby have
numerous advanced features that aren't present in Rust and would likely
require a bespoke Rust runtime to emulate the behaviour. Types is also a whole
can of worms here.

I think in relation to Ruby, Python and other languages like them Rust's best
application is leveraging the support for C FFIs to replace hot paths. While
Rust has a significant learning curve it's probably much simpler, for say a
ruby programmer, to pick it up and write safe performant code than C.

~~~
jashmatthews
There's an effort to write a Ruby implementation in Rust:
[https://github.com/artichoke/artichoke](https://github.com/artichoke/artichoke)

At the moment it wraps the mruby VM, but I think Ryan's plan is to switch to
the CRuby YARV VM and then replace it with a VM written in Rust.

I'm also working on a CRuby JIT compiler written in Rust using CraneLift (a
new compiler written in Rust).

------
johnklos
Why is there such a push to use this new language that's so inaccessible to
much of the world? Not everyone has a multi-gigahertz, multi-core, multi-
gigabyte computer to develop in Rust. It seems like unnecessary stratification
for nebulous gain.

Perhaps the Rust team should make their compiler work on reasonable resources,
like 32 bit processors, before marching off to try to convert the world.

Or perhaps we should have rust2c instead, so people can take all this Rust
code that everyone is pushing and compile it on modest machines.

~~~
AceJohnny2
> _Perhaps the Rust team should make their compiler work on reasonable
> resources, like 32 bit processors_

Rust compiles for and runs on STM32, a 32-bit microcontroller:

[https://docs.rust-embedded.org/discovery/](https://docs.rust-
embedded.org/discovery/)

And here's an index of supported embedded hardware:

[https://github.com/rust-embedded/awesome-embedded-
rust#drive...](https://github.com/rust-embedded/awesome-embedded-rust#driver-
crates)

~~~
andai
_> Perhaps the Rust team should make their compiler work on reasonable
resources, like 32 bit processors_

 _> Rust compiles for and runs on STM32, a 32-bit microcontroller_

Cool, but it can't run the _compiler,_ right? I think that's what GP meant.

~~~
sedatk
I wouldn't call 32-bit processors reasonable anymore. Maybe a decade ago, yes.
64-bit is the norm now. It doesn't make sense to demand 32-bit support.

