[gambit-list] Returning homogeneous numeric vectors from C to Scheme

Marc Feeley feeley at iro.umontreal.ca
Sat Jul 18 13:40:49 EDT 2020


Lassi, the first parameter of ___alloc_scmobj indicates if the object is a permanently allocated object (NULL) or a garbage collectible “still” object (processor state pointer).  Here is the documentation in lib/mem.c:

/*
 * '___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.
 */

So you probably want to pass “___ps” (or “___PSTATE”) as the first parameter, and check that there wasn’t a heap overflow:

if (___FIXNUMP(result)) ___return(___FAL);

Ideally Gambit's C-interface (FFI) should support passing Scheme homogeneous vectors to C and returning C arrays to Scheme (converted to the appropriate Scheme vector type), but this is not obvious to do because typically C arrays don’t have a statically known length, so the C-interface would need to pass Scheme homogeneous vectors to C as 2 parameters, a pointer and a size_t length (but in which order, and maybe you don’t care to pass the length).  And should the array be copied (slow) or not (fast but possible problems with GC).  Suggestions are welcome…

Marc



> On Jul 18, 2020, at 7:10 AM, Lassi Kortela <lassi at lassi.io> wrote:
> 
>> ___SCMOBJ result = ___EXT(___alloc_scmobj) (NULL, ___sF64VECTOR, count*sizeof(___F64));
>> double *ptr = ___CAST(double*,___BODY(result));
>> ...
>> ___EXT(___release_scmobj)(result);
>> return result;
> 
> Nice. Thanks for the super-quick reply!
> 
> (define get-test-s64vector
>  (c-lambda () scheme-object #<<c-lambda-end
>    static ___S64 c_ints[32];
>    size_t nbytes = sizeof(c_ints);
>    size_t n = nbytes / sizeof(___S64);
>    size_t i;
>    for (i = 0; i < n; i += 2) c_ints[i] = i;
>    for (i = 1; i < n; i += 2) c_ints[i] = -i;
>    ___SCMOBJ result = ___EXT(___alloc_scmobj)(NULL, ___sS64VECTOR, nbytes);
>    ___S64 *scheme_ints = ___CAST(___S64 *, ___BODY(result));
>    for (i = 0; i < n; i++) scheme_ints[i] = c_ints[i];
>    ___EXT(___release_scmobj)(result);
>    ___return(result);
> c-lambda-end
> ))
> 
> $ gsc test.scm
> $ gsi test.o1 -e "(pp (get-test-s64vector))"
> #s64(0 -1 2 -3 4 -5 6 -7 8 -9 10 -11 12 -13 14 -15 16 -17 18 -19 20 -21 22 -23 24 -25 26 -27 28 -29 30 -31)
> 
> _______________________________________________
> Gambit-list mailing list
> Gambit-list at iro.umontreal.ca
> https://mailman.iro.umontreal.ca/cgi-bin/mailman/listinfo/gambit-list
> 





More information about the Gambit-list mailing list