24
loading...
This website collects cookies to deliver better user experience
beedef(iter, int n;)
{
... // code to be executed here.
beereturn;
}
iter
(a pointer to a structure) is defined.bee_fly_iter()
is defined.typedef struct iter_s {
struct bee_s bee_;
int n; // <- This is the preserved var
} *iter;
int bee_fly_iter(iter bee)
{
if (bee == NULL) goto bee_return;
switch(bee->bee_.line) {
default: goto bee_return;
case 0: {
... // code to be executed here.
}
}
bee_return: bee->bee_.line = -1;
return BEE_DONE;
}
bee_s
holds the basic information: typedef struct bee_s {
int32_t line;
int (*fly)();
} *bee_t;
line
is set to 0
, so the first time the fly function is called the switch
will execute the code following case 0:
.line
will be set to the current line number and a new case
entry is created as you can see from the beeyeld
definition:#define beeyeld do { \
bee->bee_.line = __LINE__ ; \
return BEE_READY; \
case __LINE__ : ; \
} while(0)
fly
function returns to the caller and next time it is called, the switch will start the execution from the case __LINE__:
statement.1: #include "bee.h"
2:
3: beedef(iter, int n;)
4: {
5: for (bee->n = 0; bee->n < 10; bee->n++) {
6: beeyeld;
7: }
8: beereturn;
9: }
10:
11: int main(int argc, char *argv[])
12: {
13: iter counter = beenew(iter);
14: while (beefly(counter)) {
15: printf("%d\n",counter->n);
16: }
17: }
typedef struct iter_s {
struct bee_s bee_;
int n;
} *iter;
int bee_fly_iter(iter bee)
{
if (bee == ((void *)0)) goto bee_return;
switch(bee->bee_.line) {
default: goto bee_return;
case 0: {
for (bee->n = 0; bee->n < 10; bee->n++) {
do {
bee->bee_.line = 6;
return 1;
case 6: ;
} while(0);
}
}
}
bee_return: bee->bee_.line = -1;
return 0;
}
int main(int argc, char *argv[])
{
iter counter = bee_new(sizeof(struct iter_s), bee_fly_iter);
while (beefly(counter)) {
printf("%d\n",counter->n);
}
}
6
is the line where beeyeld
appears.for
loop nested in a switch
statement. The evil is that when resuming, we'll jump straight into the loop body.24