Embedded Interpreter for Polyglot C++/Rust programming
Imagine a C++ compiler that runs a C++ interpreter at compile time so it can do dynamic code generation (or FFI glue) to call Rust code directly, without hand-writing bindings. That’s exactly the kind of thing a Circle-style compiler or Cling-style integration would make possible.
The Idea
-
The compiler has an embedded interpreter that can run arbitrary C++ at compile time.
-
At compile time, it:
-
Reads Rust source or crate metadata.
-
Uses
rustcorcargo metadatato extract type signatures. -
Generates the C++ ↔ Rust FFI bridge automatically.
-
Injects those bindings into the final compiled binary.
-
This means from a C++ programmer’s view, calling Rust looks like a normal function call, but under the hood, the compiler has auto-generated the extern "C" shims.
Hypothetical Syntax (Circle-Style)
1import <rust/ffi_generator>; // imaginary compile-time helper
2
3// At compile-time, parse Rust crate metadata and generate glue.
4constexpr void load_rust_module(const char* crate_path) {
5 auto metadata = rust::parse_crate(crate_path);
6 for (auto& fn : metadata.functions) {
7 rust::generate_extern(fn); // emits extern "C" declaration
8 }
9}
10
11@meta {
12 load_rust_module("../my_rust_crate"); // Run at compile-time
13}
14
15// Now, call Rust function directly like C++
16int main() {
17 int result = rust_add(3, 4); // Suppose Rust has fn rust_add(i32, i32) -> i32
18 std::cout << "Result: " << result << "\n";
19}
How it would work
@metais Circle’s syntax for compile-time execution of code.rust::parse_crateandrust::generate_externrun in the compiler’s interpreter, generating the actual extern “C” glue declarations.- The resulting C++ translation unit now has:
1extern "C" int rust_add(int, int);
Behind the scenes
- Rust Side:
You’d expose your Rust code to C via:
1#[no_mangle]
2pub extern "C" fn rust_add(a: i32, b: i32) -> i32 {
3 a + b
4}
Note, I’m still looking at what it would require to generate rust bindings directly in the c++ code, so that any rust function could be called, not just functions that have been exported with #[no_mangle].
- C++ Side (Meta): The compiler’s interpreter:
- Runs
cargo metadataor parsesrustdocJSON. - Auto-generates C function signatures.
- Injects them into the C++ compilation unit.
- Linking:
The compiler links your program against
libmy_rust_crate.a.
Why is this powerful
Normally you’d write bindings by hand or use bindgen separately, but here:
- No separate binding step.
- The compiler runs real C++ code at compile time to integrate Rust code dynamically.
- You can even imagine generating C++ wrappers for Rust traits, enums, etc.