Isaac Jurado <dipto...@gmail.com> writes: > On Thu, Jun 27, 2019 at 9:52 PM Greg Troxel <g...@lexort.com> wrote: > >> I have been down this path before, with guile and with lua. Basically, >> if C (or non-scheme) has a pointer to a scheme object, then you need to >> hold a logical reference for it and protect the scheme object, and when >> the C pointer is dropped decrease the refcnt. >> >> I am unclear on the details of how you have a ref that gc is made aware >> of. One way is to have a scheme array of the object and a count, and >> have the code null out the object when the count goes to zero or >> something like that. But the point is that you need to have a proxy in >> the scheme world, visible to gc, when a pointer to a scheme object is >> held outside of the scheme world. >> > > That's more or less what I had in mind, although instead of an array I > would use a hash table indexed by a fundamental type (e.g. integer) which > can be converted painlessly between Scheme and C.
Sure - it just needs to be something the gc will find. > I prepared a minimal case of the kind of C interactions that I'm trying. > I'm attaching the files, the C code has to be compiled with: > > gcc -shared -fPIC -o mysalsa.so mysalsa.c > > Running the Scheme script yields something like the following: > > Captured: Closure without collection > Argument: noitcelloc tuohtiw erusolC > Captured: Closure with garbate collected > Argument: > > So primitive values seem to be garbage collected, but closures are treated > slightly differently. This is very interesting, since working with > closures eliminates the need of those common "void *userdata" extra > arguments. > > Testing continuation is going to be interesting too. Just because something wasn't collected doesn't mean it is safe. You don't actually know that the closure wasn't garbage collected, just that when you used it the bits were still there. You might try running under valgrind. Or modify guile to clear all objects that are garbage collected, which I'm guessing it doesn't do. In my experience, it's definitely not ok to capture a pointer to a scheme object and store it for later use without protecting the scheme object from gc by holding a reference.