On Apr 11, 2020, at 6:16 AM, Jörg F. Wittenberger Joerg.Wittenberger@softeyes.net wrote:
Thanks for your reply.
On Fri, 10 Apr 2020 15:49:15 -0400 Marc Feeley feeley@iro.umontreal.ca wrote:
There are a few issues with your code. First of all, you should use “___return(…);” to return a result (the assignment to ___result_voidstar is deprecated).
OK. Is there some documentation wrt. these things?
The Gambit manual (doc/gambit.pdf) has this to say:
When c-name-or-code is not a valid C identifier, it is treated as an arbitrary piece of C code. Within the C code the variables ‘___arg1’, ‘___arg2’, etc. can be referenced to access the converted arguments. Note that the C return statement can’t be used to return from the procedure. Instead, the ___return macro must be used. A procedure whose result-type is not void must pass the procedure’s result as the single argument to the ___return macro, for example ‘___return(123);’ to return the value 123. When result-type is void, the ___return macro must be called without a parameter list, for example ‘___return;’.
An alternative would be to create your own type with a release function, but that is probably overkill in this situation.
Interesting: you consider a type with release function to be the overkill? I had the impression that the use of wills would be the overly complex way.
Nevertheless: In your suggestion you still use malloc to allocate. I do see situations where I'd tend to do this too. Still I wonder if it was cheaper/faster to allocate on the Scheme heap. And if so, how?
In your C code you could allocate a “still” u8vector object using:
___SCMOBJ obj = ___EXT(___alloc_scmobj) (___PSTATE, ___sU8VECTOR, length_in_bytes);
/* * '___alloc_scmobj (___ps, subtype, bytes)' allocates a permanent or * still Scheme object (depending on '___ps') of subtype ‘subtype' * with a body containing 'bytes' bytes, and returns it as an encoded * Scheme object. When '___ps' is NULL, a permanent object is * allocated, and when '___ps' is not NULL, a still object is * allocated in the heap of that processor's VM. The initialization * of the object's body must be done by the caller. In the case of * still objects this initialization must be done before the next * allocation is requested. The 'refcount' field of still objects is * initially 1. A fixnum error code is returned when there is an * error. */
and then decrement the reference count so that in the future the Gambit garbage collector will be solely responsible for determining if the object can be reclaimed:
___EXT(___release_scmobj) (obj);
To access the content of the object you can use the ___BODY(obj) macro to get a pointer to the content of the object:
char *body = ___CAST(char*,___BODY(obj)); body[0] = 11; body[1] = 22;
I don’t know if there is a significant performance difference between this and the other method I explained (but it does a single call to malloc rather than two). You’ll have to benchmark it to see which one is faster.
Marc