
Rustgo: Calling Rust from Go with near-zero overhead (2017) - ingve
https://blog.filippo.io/rustgo/
======
FiloSottile
A nuance I wish I had expressed better in this article is that it's targeting
functions that would otherwise be written in assembly: they'd have to be quick
(not to undermine the scheduler) and non-recursive (not to blow the stack).
For just calling larger Rust functions one can use cgo.

~~~
scottlamb
+1. There's a reason cgo sets up another stack; calling into Rust instead of C
doesn't change that.

What are the consequences if you blow the stack in Go [edit: to clarify, I
mean if your code in another language that doesn't understand Go's stack
copying calling convention blows Go's stack]? Is there a guard page (so
SIGSEGV) or does it just corrupt memory?

------
Animats
If you have to reverse-engineer the undocumented Go calling sequence to call
Rust, you probably shouldn't be using that for security-critical crypto
functions. The next time somebody changes something, there will be trouble.

This is especially an issue in a garbage collected language. If the only
reference to something was passed from Go to Rust, will Go's GC marker find
it? If it doesn't, everything will work just fine, until someday a garbage
collection happens at the wrong moment.

In security critical code, that's probably exploitable if you can force a GC
from another thread.

~~~
yencabulator
> If the only reference to something was passed from Go to Rust, will Go's GC
> marker find it?

No, and rightly so. I would expect [https://golang.org/cmd/cgo/#hdr-
Passing_pointers](https://golang.org/cmd/cgo/#hdr-Passing_pointers) to apply
just as much here as with CGo (the criteria is "foreign allocator", not CGo).

~~~
Animats
Which is a problem here, because the OP is calling Rust from Go using the Go
calling sequence. So Go's checking doesn't know it's calling non-Go code.
There's a defined way to call C from Go, but the OP is not using that
interface.

~~~
yencabulator
It's fine as long as you don't store Go pointers in non-Go memory.

If the local variable is the last reference to the thing,
[https://golang.org/pkg/runtime/#KeepAlive](https://golang.org/pkg/runtime/#KeepAlive)
makes sure the Go side doesn't drop it before the call is complete.

------
hu3
> I'll be upfront: I don't know Rust, and don't feel compelled to do my day-
> to-day programming in it.

I wonder if this changed. A quick glance over the blog hints me towards a no.

~~~
jaChEWAg
That line pretty much sums up the experience a lot of devs feel towards Rust

~~~
ludamad
General purpose languages are a tough sell these days. Rust is tailored
towards a niche and that's OK

~~~
Refefer
Systems Languages are considered niche these days?

~~~
ludamad
But it's not the first systems language, so it does need to carve a niche in
that space

------
jzelinskie
Filippo also gave a talk at GothamGo on this subject:
[https://www.youtube.com/watch?v=eymMKjymgGA](https://www.youtube.com/watch?v=eymMKjymgGA)

------
Myrmornis
I've been finding learning Rust an extremely valuable experience and I really
like the language. Also I don't have any experience with replacing assembly
code with a higher-level language. But...

If you're looking for a replacement for hand-crafted assembly, don't the
strict lifetime-checker and borrow-checker make Rust a non-obvious choice?
E.g. they might prevent you from doing certain memory access patterns that you
actually explicitly want your assembly to do? (I.e. wouldn't C or C++ be more
the thing?) Or do you just make liberal use of unsafe blocks where necessary?
Or is it actually fine and appropriate to write {lifetime,borrow}-checker
compliant replacements for hand-crafted assembly?

------
heinrich5991
Previous discussion:
[https://news.ycombinator.com/item?id=15017519](https://news.ycombinator.com/item?id=15017519)
(68 comments)

------
killercup
(2017)

