On 30-Dec-05, at 9:44 PM, Christian wrote:
Marc: can you give more info? Which parts of the Gambit source do you recommend to try to understand first?
___S8 one, two, three; one = 1; two = 2; three = 3;
return ___CONS(one, ___CONS(two, ___CONS(three, ___NUL)));
Note that you would also have to convert the ___S8 values to ___SCMOBJ, using ___FIX() probably.
Some quick notes about allocating Scheme objects in C code... Scheme objects can be allocated using one of 3 allocation policies: ___MOVABLE the object's location can change as a result of garbage collection ___STILL the object's location cannot change as a result of garbage collection ___PERM the object's location cannot change and it is never reclaimed by the GC The macro ___CONS(car,cdr) allocates movable pairs, ___BEGIN_ALLOC_VECTOR(n) allocates movable vectors, etc. Movable objects are allocated by incrementing the heap pointer (the local variable ___hp which is a copy of the hp field of the processor state structure). Still pairs are allocated with ___make_pair (car,cdr,policy), still vectors are allocated with ___make_vector (length,init,policy), etc. Still objects have a reference count, initialized to 1 at allocation time, which is taken into account by the garbage collector to infer liveness (in **addition** to the normal roots). This makes it easy to manipulate still objects from C code because the garbage collector does not have to be aware of local C variables referencing still objects (as long as the reference count is > 0 the references will stay valid). Although it is technically possible, it is a bad idea to allocate movable objects from C code because any allocation can cause a garbage collection (and the C stack is neither treated as a root or updated by the garbage collector). So the simplest is for C code to only allocate still Scheme objects, and to decrement the reference count back to 0 when the C code returns the object to Scheme code. Below is an example inspired from sample code in the Gambit manual. Marc (c-declare #<<end-c-declare ___SCMOBJ square_alist (int n) { /* builds an association list of the squares of 0 to n-1 */ ___SCMOBJ result = ___NUL; /* start with the empty list */ int i = n; /* build the list starting at the tail */ while (--i >= 0) { ___SCMOBJ elem; ___SCMOBJ new_result; /* * Invariant: result is either the empty list or a ___STILL pair * with reference count equal to 1. This is important because * it is possible that ___make_pair will invoke the garbage * collector and we don't want the reference in result to become * invalid (which would be the case if result was a ___MOVABLE * pair or if it had a zero reference count). */ elem = ___EXT(___make_pair) (___FIX(i), ___FIX(i*i), ___STILL); if (___FIXNUMP(elem)) { ___EXT(___release_scmobj) (result); /* allow GC to reclaim result */ return elem; /* fixnum indicates allocation failed */ } /* * Note that elem will be a ___STILL object with reference count * equal to 1, so there is no risk that it will be reclaimed or * moved if the following call to ___make_pair invokes the * garbage collector. */ new_result = ___EXT(___make_pair) (elem, result, ___STILL); /* * We can zero the reference count of elem and result (if not * the empty list) because the pair now references these objects * and the pair's reference count is > 0 (it can't be reclaimed * or moved by the garbage collector). */ ___EXT(___release_scmobj) (elem); ___EXT(___release_scmobj) (result); result = new_result; if (___FIXNUMP(result)) return result; /* fixnum indicates allocation failed */ } /* * Note that result is either the empty list or a ___STILL pair with * a reference count equal to 1. The reference count must be * decremented to 0 when it is handed back to the Scheme world, so * that it can be reclaimed when the Scheme world no longer * references it. */ ___EXT(___release_scmobj) (result); return result; } end-c-declare ) (define square-alist (c-lambda (int) scheme-object "square_alist")) (pp (square-alist 10)) ; test it