3 ms·
I have been hoping for a while that rust would make some progress toward better supporting setjmp/longjump from C: https://github.com/rust-lang/rfcs/issues/262
by jeff-davis 5y ago
I have been hoping for a while that rust would make some progress toward better supporting setjmp/longjump from C:
https://github.com/rust-lang/rfcs/issues/2625 https://github.com/rust-lang/rfcs/issues/2625
It's asking a lot, but it's one of very few weak points in Rust/C interoperability, and it would be great if it were addressed.
Of course, this would obviously be marked as unsafe code, and could only be used in very limited ways. But it would still be very useful for my project here:
https://github.com/jeff-davis/postgres-extension.rs https://github.com/jeff-davis/postgres-extension.rs
Which has code that handles setjmp/longjmp, and as far as I can tell it produces correct assembly, but it's currently undefined behavior as far as rust is concerned.
There's some related work here:
https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html
But it also seems to have slowed down.
- nynx 5y agoThe way you'd want to do this currently would be to catch longjmps on the c side, return an error code, and then begin an unwind on the rust side, catch that, and convert back into a longjmps. But I agree that it's unfortunate that rust doesn't have good support for C++ exceptions unwinding through rust code.
- jeff-davis 5y agoThat's not very practical for what I'm trying to do. A Postgres extension can access a very wide range of internal functions (hundreds), and most of them have the potential to ERROR (longjmp). These functions are of all different kinds with different numbers and types of arguments, so I'd need to wrap each one, or would need some pretty clever macros or code gen. Rust has really powerful macros (which I'm using currently), and I don't think it would work out as well in C. Also, it means a lot of symbol bloat, because each of these new C functions needs a symbol. Also, it would mean that my crate would no longer be pure rust, so I'd have to figure out how to build all this C code on whatever platforms.
- nynx 5y agoI see what you mean. That's too bad. I definitely hope there's better support for what you're asking in the future.
- jeff-davis 5y agoYeah, I mean, I know I'm asking for a lot. No other language comes close to rust as far as C interop, except C++. And rust is actually better at C interop than C++ in some important ways! * Rust doesn't mess with struct definitions if they are declared #[repr(C)]. No extra vtable pointers. That means you can pass a struct back and forth between C and rust, and in the rust code you can do dynamic dispatch on that same C struct (no copying/conversion). That's amazing! * Rust defines Option<&Foo> in a #[repr(C)] struct to be a plain pointer, where NULL means None. That means you can get type safety in rust working with nullable pointers you get from C, to make sure that your rust code checks for None. Again, no conversion or copying, you get this with ordinary nullable pointers coming from C.
- nynx 5y agoBack when I was working on wasm runtimes, I ran into the issue of unwinding an exception through generated code. I had to do something reminiscent of what I mentioned above.