Rewrite Tor in Rust
trac.torproject.org
trac.torproject.org
Most platform officially specify their C ABI, and many also specify their C++ ABI (usually in therm of the C one). Itanium C++ ABI (plus the platform specific psABIs) has become the de facto C++ ABI for many unix and unix-like platforms.
But yeah, the reverse requires a C layer. rust-bindgen has experimental C++ support which we use for spidermonkey but it isn't perfect.
Can you tell me more about this?
$ cat hello.rs
#[no_mangle]
pub extern fn plus_one(x: isize) -> isize {
x + 1
}
$ cat hello.c
#include<stdio.h>
extern int plus_one(int);
int main() {
int result = plus_one(5);
printf("result is %d\n", result);
return 0;
}
$ rustc hello.rs --crate-type=dylib
$ gcc hello.c -lhello -L .
$ LD_LIBRARY_PATH=. ./a.out
result is 6What happens is that C ABI == OS ABI, when the OS is written in C. This is not the case in the mainframe OSes that are still alive, for example.
So people have come to expect C ABI as being some kind of standard.
On an OS written in pure C++, the OS vendor C++ compiler would be the ABI.
Having said this, there are efforts to partially standardize the C++ ABI:
https://isocpp.org/blog/2014/05/n4028
Also many vendors use the Intel's C++ Itanium ABI as reference.
a) each platform to document its C++ABI. b) each platform to offer a ABI stable variant of the standard library as an option.
Both points are really already the norm and the default on many platforms. For example GCC on most OSs follows the documented Itanium ABI while libstdc++ has been ABI stable for a long time at least on Linux.
The notable exception is windows and MSVC. While the C ABI is documented, I believe that C++ ABI is pretty much "whatever MSVC does" and had to be reverse enginereed. Additionally MSVC reservers the right to break its library ABI at every major release (and in fact it does).
However being mainly a .NET/JVM developer nowadays, I just follow C++ standardization on the sidelines.
Thanks for correction.
I wanted to up-vote that bit.
int get_a_string(char **out) // returns error code
could be translated literally as fn get_a_string(out: *mut *mut c_char) -> c_int
but much preferable would be fn get_a_string() -> Result<String, Errcode>
[where Result and String are standard library types; Errcode would be a custom enum.]I suppose you could go from the first to the second incrementally, then refactor to the third. But I'm not sure it'd work well.
.and_then calls themselves aren't too bad, with the right whitespace.
https://github.com/rust-lang/rfcs/pull/243 (note that what was actually accepted differs from the text of the RFC, you need to scroll to the bottom)
As steveklabnik says, there's nothing resembling generalized monadic do notation for now.
Edit: Video about it [2]
[1] https://github.com/GaloisInc/haskell-tor [2] https://www.youtube.com/watch?v=oHcHTFleNtg