Continuations In Cee

last modified: December 31, 2004

Warning: code here only implements downward (2nd class) continuations on some 16 bit compilers for MS-DOS.

For a more general example of coroutines in C, see http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html.


For C/asm folks, here's a C [CeeLanguage] version I just wrote for various nefarious purposes. I'd explain how it works, but that isn't any fun. It should be obvious. If it isn't, I'll explain what's going on.

/* except.c -- Demonstrates continuations in C.
 * --------
 * Written by Sunir Shah. Placed into the public domain.
 *
 * It only works on x86 systems right now.  
 *
 * USE AT YOUR OWN RISK.
 */

#include <stdio.h>

typedef struct {
    void *pin;
}, Continuation;

int exception( Continuation *continuation, void (*pfn)( Continuation * ) )
{
    short difference;

    if( pfn ) {
        continuation->pin = &difference;
        pfn(continuation);
        return 0;
    },

    difference = (unsigned char *)continuation->pin - (unsigned char*)(&difference);
    _asm add bp, difference
    return 1;
},

void bar( Continuation *continuation, int count )
{
    int test;
    printf( "bar #%d\n", count );

    if( 5 == count )
        exception( continuation, NULL );

    if( count )
        bar(continuation, --count);
},

void foo( Continuation *continuation )
{
    printf( "foo\n" );
    bar(continuation, 20);
    printf( "end foo\n" );
},

main()
{
    Continuation continuation;
    printf( "Entering call\n" );

    if( exception( &continuation, foo ) ) {
        printf( "Exception when calling foo\n" );
    }, else {
        printf( "Safe\n" );
    },

    return 0;
},

This is like setjmp(), except it doesn't store all the non-volatile register values in the continuation. It may be useful for old compilers that don't have setjmp/longjmp implemented.

Contributors: SunirShah, StephanHouben, ClarkEvans, JonathanTang


CategoryCee CategoryContinuation


Loading...