Hello.
I'm trying to find an elegant way to longjmp to the callee
(aka "generators for C")
So far I've come to this experimental program (gcc only as it uses
__builtin_frame_address, although we can do without it):
================================================== ====================
/* longjmp to the callee */
#include <setjmp.h>
#include <stdio.h>
jmp_buf F;
jmp_buf F2;
static inline char* bfr ()
{
return __builtin_frame_address (0);
}
char *top;
int foo()
{
int i;
for (i = 0; i < 5; i++) {
printf (".i=%i\n", i);
if (i == 2) {
if (!setjmp (F2)) {
top = bfr();
//printf ("Mytop=%p\n", top);
longjmp (F, 1);
} else {
printf ("resumed...\n");
}
}
printf ("i=%i\n", i);
}
return 0;
}
int bar ()
{
return foo ();
}
int potatoe ()
{
int i, j;
for (i = 0, j = 10; i < j; i++)
printf ("%i ", i);
printf ("\n");
return 132;
}
int main ()
{
int i, j;
char *thistop;
for (i = 0; i < 3; i++)
if (!setjmp (F)) {
printf ("trying...\n");
bar();
} else {
/* preserve the stack */
j=40;
char CAP1[j];
thistop = bfr();
char GAP2 [top-thistop];
printf ("caught...\n");
/* test that stack is not polluted */
potatoe ();
/* longjmp to the callee and resume */
longjmp (F2, 2);
}
return 0;
}
================================================== ===========
Notes:
longjmp already supports jumping to a callee. The problem
is that we have to preserve the stack (and thus the function
potatoe() which is supposed to polute it).
The solution I found is to use C99 variable-length arrays to
displace the stacktop beyond the region we want to preserve.
I'm looking for ideas/enhancements to make this more portable,
safe, fast, etc. It must have been done before, right?
jf