[gambit-list] How to properly allocate foreign object?
Marc Feeley
feeley at iro.umontreal.ca
Sat Apr 11 09:53:58 EDT 2020
> On Apr 11, 2020, at 6:16 AM, Jörg F. Wittenberger <Joerg.Wittenberger at softeyes.net> wrote:
>
> Thanks for your reply.
>
> On Fri, 10 Apr 2020 15:49:15 -0400
> Marc Feeley <feeley at 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
More information about the Gambit-list
mailing list