On 11/24/2012 08:07 PM, Omer Zach wrote:
Hi all,
I'm an undergrad at Carnegie Mellon taking a compilers class right
now. We're implementing compilers for a safe C-like language called C0
(http://c0.typesafety.net/), and one of the options for our last
project is to implement garbage collection for the language. My
partner, Brandon, and I been reading about and playing with Rust, and
want to try writing the runtime for the garbage collector in Rust.
Here’s how we were thinking about implementing the C to Rust calls.
We’ll switch our runtime from a simple C program to a C library. Then
we will link our Rust program against this C library, and call the
“main” function with function pointers to any Rust functions we need
to call from our C0 code (any heap allocation routines). This way, we
can (mostly) avoid dealing with unsafe memory management. See
https://github.com/bkase/rust-ffi-example for a simple example.
Seemed like it would be worth shooting you guys an email before we
dive in—is this a terrible idea or is there anything we should know
before we get started?
Sully pointed out that my previous reply was off the mark and you are
not interested in implementing *the Rust GC* but instead implementing a
GC for another language (implemented in C) in Rust. You want to use
Rust's safe memory management from a C application.
The Rust runtime is not set up to do this yet. Currently, to run Rust
code in any supported way that code must execute in the context of a
Rust task, in the context of the Rust runtime. Calling Rust code from
outside the runtime is not done anywhere. I would suggest that if you
want to take this approach now you make the application a Rust
application that starts the runtime and immediately calls into your C
application in a task context. Then you can use `extern fn` pointers to
call back into Rust code.
The approach of calling arbitrary Rust functions from arbitrary C
requires some redesign of the runtime, tracked here:
https://github.com/mozilla/rust/issues/3608
Here are the main problems you are going to hit:
* Rust functions have their own ABI that your C code will need to
understand. The first argument is a return pointer and the second is an
environment pointer. The return value is unused. The convention for
passing simple word size types is the same as C (cdecl) so stick to
pointers and integers. More complicated types in C sometimes follow
peculiar conventions when passed by value.
* Anything that requires the memory allocator, tasks, etc. needs access
to a thread-local task pointer, which doesn't exist if the runtime isn't
set up
* The thread control block contains a pointer to the current stack
segment, used for stack growth. This is checked on entry to every
function and should be set up correctly before main, even if stack
growth is not used.
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev