RE: Minimal example of extending Guile with Rust?

2024-01-29 Thread M
> (similar to the
>native C arrays numpy exposes to C that allow getting the >speed of C).

For this in particular, there is pointer->bytevector, bytevector->pointer and 
bytevector-TYPE-ref, bytevector-TYPE-set! (it’s not limited to only bytes, also 
floats are available IIRC).

Don’t do bytevector->pointer + pointer->bytevector + … in long sequences 
though, or else this loop will use memory proportional to the length to this 
sequence. (This is intentionally undocumented (*).)

Best regards,
Maxime Devos

(*) For its application bytevector-slice, see 
https://lists.gnu.org/archive/html/guile-devel/2023-01/msg00042.html, which was 
ignored.


Re: Minimal example of extending Guile with Rust?

2024-01-29 Thread Olivier Dion
On Mon, 29 Jan 2024, "Dr. Arne Babenhauserheide"  wrote:

[...]

> Ideally with a fast Scheme-to-Rust-to-Scheme interface (similar to the
> native C arrays numpy exposes to C that allow getting the speed of C).

See .  There is many path to
do this.  The main issue is the calling convention.

Rust functions that you want binding for must follow the C calling
convention by using `extern "C"'.  Otherwise, the calling convention of
the compiler is used (AFAIK, Rust does not define a calling convention).
You can then simply use the system foreign interface as usual as if the
Rust functions were C functions.

There are others thing to consider.  Structures in Rust must have the
attribute `#[repr(C)]' to follow the C ABI for structure members layout.
Otherwise, the compiler is free to re-order members.

Then there is callbacks .. and other things ..

The above link gives comments on all of this but not much details.

Hope that helps.

-- 
Olivier Dion
oldiob.dev



Re: Minimal example of extending Guile with Rust?

2024-01-29 Thread Jean Abou Samra

There are a number of crates with Rust bindings to the Guile C API: 
https://lib.rs/search?q=guile

Most of them are just the result of running the bindgen tool, which 
autogenerates Rust bindings from C header files. A few of them have slightly 
more convenient wrapper but none is really well-developed AFAICS.

Honestly, I think the easiest at this time is to do the interfacing with Guile 
from C. Create a Rust module which exports a function through C FFI, and 
convert between C and Guile types in C. Alternatively, use the Guile FFI 
facilities for the conversion. It is probably simpler than doing these 
conversions in Rust. It is, in any case, safer, because I'm quite sure that the 
Rust compiler will be happy to do optimizations that defeat conservative GC, by 
hiding pointers in local variables (which Rust can more easily do, thanks to 
its aliasing guarantees).

Be careful with calling Guile code from Rust code. This is fraught, because 
Guile code can raise exceptions, which are basically propagated through 
longjmp, and it is UB in Rust to unwind through Rust code with longjmp. 
Basically, if you call Guile from Rust then it must be wrapped in exception 
handling. An exception must not propagate through Rust stack frames. call/cc 
would be a problem too, so you likely want to use with-continuation-barrier.