[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: pcall() and coroutine.yield()
- From: Edgar Toernig <froese@...>
- Date: Wed, 20 Oct 2004 03:33:21 +0200
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----