lua-users home
lua-l archive

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


Roberto Ierusalimschy wrote:
>
> [...] proposals to change the implementation are usually
> easy to judge, once we have the new implementation to compare with
> the old. So, the best argument to convince us of such changes is a
> well-implemented working prototype.

What about coroutines at the C-level?  Sure, it can't be done in
ANSI-C and is in fact heavily system dependent but the problem of
yielding anywhere within C-code becomes trivial.

To get an idea how the system dependent part could look like I've
attached some code I'm already using for a while (and afaik, Steve
Dekorte is using it in his programming language Io).

Would system dependent code like that below be acceptable?

Ciao, ET.

---- part of http://goron.de/~froese/httpp/threads.c ----
/*
 * This is the system dependent function.
 * Setup a jmp_buf so when it is longjmp'ed it will invoke 'func' using 'stack'.
 * ('func' will not (and mustn't) return!)
 */
static void
setup_jmpbuf(jmp_buf buf, void (*func)(void), void *stack, void *stackend)
{
    (void)stack;        /* avoid "unused" warnings */
    (void)stackend;     /* avoid "unused" warnings */

    _setjmp(buf);       /* initialize jmp_buf with some sane values */

#if defined(_BSD_PPC_SETJMP_H_)
    /* ppc-os-x */
    memset((char*)stackend-64, 0, 64);  /* very crude... */
    buf[0] = ((int)stackend - 64 + 15) & ~15;
    buf[21] = (int)func;
#elif defined(_IRIX4_SIGJBLEN)
    /* mips irix 4 */
    buf[JB_SP] = (__uint64_t)stackend - 8;
    buf[JB_PC] = (__uint64_t)func;
#elif defined(__MINGW32__) || defined(_MSC_VER)
    /* mingw32 and Win32 Visual C */
    buf[4] = (int)stackend;
    buf[5] = (int)func;
#elif defined(__CYGWIN__)
    /* Win32 - untested */
    buf[7] = (int)stackend;
    buf[8] = (int)func;
#elif defined(_I386_JMP_BUF_H)
    /* x86-linux with libc5 */
    buf->__sp = stackend;
    buf->__pc = func;
#elif defined(JB_GPR1)
    /* Linux ppc */
    memset((char*)stackend-64, 0, 64);  /* very crude... */
    buf->__jmpbuf[JB_GPR1] = ((int)stackend - 64 + 15) & ~15;
    buf->__jmpbuf[JB_LR] = (int)func;
#elif defined(JB_SP)
    /* x86-linux with glibc2 */
    buf->__jmpbuf[JB_SP] = (int)stackend;
    buf->__jmpbuf[JB_PC] = (int)func;
#elif defined(_JBLEN) && (_JBLEN == 81)
    /* FreeBSD/Alpha */
    buf->_jb[2] = (long)func;           /* sc_pc */
    buf->_jb[26+4] = (long)func;        /* sc_regs[R_RA] */
    buf->_jb[27+4] = (long)func;        /* sc_regs[R_T12] */
    buf->_jb[30+4] = (long)stackend;    /* sc_regs[R_SP] */
#elif defined(_JB_ATTRIBUTES)
    /* NetBSD i386? */
    buf[2] = (long)stackend;
    buf[0] = (long)func;
#elif defined(_JBLEN)
    /* i386-FreeBSD and NetBSD on IA32 */
    buf->_jb[2] = (long)stackend;
    buf->_jb[0] = (long)func;
#elif 0 /* untested... */
    /* m68k-linux with glibc2 */
    buf->__jmpbuf->__sp = stackend;
    buf->__jmpbuf->__aregs[0] = (long)func;
#elif 0 /* untested... */
    /* ARM-linux (zaurus) */
    buf->__jmpbuf[__JMP_BUF_SP] = stackend;
    buf->__jmpbuf[__JMP_BUF_SP+1] = (long)func;
#else
#error unsupported architecture
#endif
----end----