chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Chicken-users] Help with foreign code and lists on the stack and heap


From: Alex Stuart
Subject: [Chicken-users] Help with foreign code and lists on the stack and heap
Date: Tue, 06 May 2014 03:39:31 -0600

Greetings,

I need some help. I am calling a foreign C function that calls back to
Scheme (using CHICKEN_apply). The callback returns a list as its value.
The foreign function creates a static reference to this list (using
CHICKEN_new_gc_root). The foreign function then creates a different list
on the stack (using C_list).

I want to append the latter list to the former and pass it to a second
callback function. I'm trying to do this by setting the cdr of the first
list's last pair (using C_set_block_item). However, the appended list is
wrong.

I'm guessing that garbage collection is messing with the list even
though I dereference my GC root to read the first part of it. Things
work fine if I just pass that part, but appending the other part doesn't
work.

Is the problem that the first list is heap-allocated and the second list
is stack-allocated? Am I approaching this the wrong way? I would much
appreciate any advice I can get.

--Alex



Here is the kind of code I am using:

/* RETRIEVE LIST NUMBER 1 */
CHICKEN_apply( CHICKEN_gc_root_ref( callback1 ), arg_list, first_list );
void *gc_root = CHICKEN_new_gc_root();
CHICKEN_gc_root_set( gc_root, first_list );

...

... (no callbacks) ...

...

/* CREATE LIST NUMBER 2 */
C_word *second_list_mem = C_alloc( C_SIZEOF_LIST( second_list_size ) +
second_list_size * C_SIZEOF_POINTER );
C_word second_list = C_list( &second_list_mem, second_list_size );
C_word list_pos = second_list
int k = 0;
while ( !C_truep( C_i_nullp( list_pos ) ) )
{
    C_set_block_item( list_pos, 0, C_mpointer( &second_list_mem,
second_list_array[k] ) );
    list_pos = C_u_i_cdr( list_pos );
    k += 1;
}

/* APPEND LIST 2 ONTO LIST 1 */
first_list = CHICKEN_gc_root_ref( gc_root );
if ( !C_truep( C_i_nullp( first_list ) ) )
{
    list_pos = first_list;
    for ( int k = 0; k < first_list_size; k++ )
    {
        list_pos = C_u_i_cdr( list_pos );
    }
    C_set_block_item( list_pos, 1, second_list );
}
else
{
    first_list = second_list;
}

/* PASS THE COMBINED LIST TO THE OTHER CALLBACK */
callback2( first_list );




reply via email to

[Prev in Thread] Current Thread [Next in Thread]