[gambit-list] Converting uint32 to scheme object

Marc Feeley feeley at iro.umontreal.ca
Thu Jan 7 08:43:29 EST 2016


The FFI always allocates “still” objects when it converts from a C type to a Scheme type.  So the (possibly) bignum that is allocated by ___U32_to_SCMOBJ is a still object.  Still objects are managed by a mark and sweep GC algorithm.  They have the property that they will never move to a different address during their lifetime.  This is a nice property when manipulating these objects from C because if the C code triggers a garbage collection (by allocating other objects), then the reference to the bignum in ___result will still point to the right place.

Still objects contain a reference count which indicates how many references to the object exist from ***C***.  A still object will be reclaimed by the GC when there is no reference to the object from the Scheme stack and heap ***and*** the reference count is 0.  When a still object is allocated its reference count is initialized to 1.  When the C code drops a reference to the object it calls ___release_scmobj to decrement the reference count.  This doesn’t reclaim the object (when the reference count is 0).  It only notifies the GC that it can eventually reclaim the object if there are no references to it from the Sheme stack and heap.

This approach allows allocating several Scheme objects in a given C function (for example to create a Scheme list of things) without too much code to protect the manipulated objects from being reclaimed by the GC in the middle of the function.

Marc

> On Jan 7, 2016, at 5:00 AM, Alex Silva <asandroq at gmail.com> wrote:
> 
> Hallo,
> 
> On 06/01/16 15:37, Marc Feeley wrote:
>> Of course one way would be to return a double (which has 53 bits of precision) and use NaN to encode “missing tag”.  I’m not kidding!
>> 
>> If you don’t like this approach, and I can understand why you wouldn’t, then you have to do the conversion to ___SCMOBJ by directly calling the conversion macros.  Something like this:
>> 
>> (define uint32_tag
>>  (c-lambda
>>   (TIFF* ttag_t)
>>   scheme-object
>>   "
>>    ___U32 val;
>>    if (TIFFGetField(___arg1, ___arg2, &val) == 1) {
>>      if ((___err = ___U32_to_SCMOBJ (___PSTATE, val, &___result, ___RETURN_POS)) == ___FIX(___NO_ERR)) {
>>        ___release_scmobj (___result);
>>      }
>>    } else {
>>      ___result = ___FAL;
>>    }
>>   "))
>> 
> 
> Thanks, this looks promising. But I do not understand the call to
> `___release_scmobj`, wouldn't that release the object that we are
> returning? Or is it just decrementing some reference count?
> 
> Cheers,
> -- 
> -alex
> http://unendli.ch/




More information about the Gambit-list mailing list