68 86
91
93
WIP re-engineer for more robust operation, less chaining, and biggest-stack-possible chains
on 4:02 PM Jun 5 2026
90
91
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "generator.h"
#include "coroutine.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "cor_platform.h"
_Cor_thread_local Generator *g_active_generator = NULL;
static void on_yield_gen(
void *this
){
Generator *gen = (Generator *)this;
Coroutine_NS(Continue)(gen->caller, Coroutine_NS(GetValue)(gen->coroutine), true);
}
static void on_yield_gen_caller(
void *this
){
(void)this;
}
static void *do_start(
void *this
){
Generator *gen = (Generator *)this;
g_active_generator = this;
assert(gen->state == Generator_Running || gen->state == Generator_Deleting);
void *value;
if (gen->state == Generator_Running){
g_active_generator = gen;
value = gen->start(gen->param);
g_active_generator = NULL;
} else {
// we are being deleted
value = NULL;
}
gen->state = Generator_Complete;
Coroutine_NS(Continue)(gen->caller, value, true);
return value;
}
void Generator_ctor(
Generator *gen,
size_t stack_size,
void *(*start)(void *),
void *param
){
gen->start = start;
gen->param = param;
gen->coroutine = Coroutine_NS(New)(stack_size, do_start);
gen->state = Generator_Running;
}
Generator *Generator_New(
size_t stack_size,
void *(*start)(void *),
void *param
){
Generator *gen = malloc(sizeof(Generator));
Generator_ctor(gen, stack_size, start, param);
return gen;
}
void Generator_dtor(
Generator *gen
){
assert(gen->state != Generator_Deleting);
if (gen->state == Generator_Running){
gen->state = Generator_Deleting;
gen->caller = Coroutine_NS(GetActive)();
Coroutine_NS(Continue)(gen->coroutine, gen, true);
Coroutine_NS(Yield)(NULL, on_yield_gen_caller, gen);
}
assert(gen->state == Generator_Complete);
Coroutine_NS(Delete)(gen->coroutine);
}
void Generator_Delete(
Generator *gen
){
Generator_dtor(gen);
free(gen);
}
bool Generator_Next(
Generator *gen,
void **value
){
assert(gen->state != Generator_Deleting);
if (gen->state == Generator_Complete){
return false;
}
gen->caller = Coroutine_NS(GetActive)();
Coroutine_NS(Continue)(gen->coroutine, gen, true);
*value = Coroutine_NS(Yield)(NULL, on_yield_gen_caller, gen);
return Coroutine_NS(IsRunning)(gen->coroutine);
}
bool Generator_Yield(
void *value
)
{
assert(g_active_generator);
Generator *gen = g_active_generator;
g_active_generator = NULL;
Coroutine_NS(Yield)(value, on_yield_gen, gen);
g_active_generator = gen;
return gen->state == Generator_Running;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "generator.h"
#include "coroutine.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "cor_platform.h"
_Cor_thread_local Generator *g_active_generator = NULL;
static void
on_yield_gen(
void *this
){
Generator *gen = (Generator *)this;
Coroutine_NS(Continue)(gen->caller, Coroutine_NS(GetValue)(gen->coroutine), true);
}
static void
on_yield_gen_caller(
void *this
){
(void)this;
}
static void *
do_start(
void *this
){
Generator *gen = (Generator *)this;
g_active_generator = this;
assert(gen->state == Generator_Running || gen->state == Generator_Deleting);
void *value;
if (gen->state == Generator_Running){
g_active_generator = gen;
value = gen->start(gen->param);
g_active_generator = NULL;
} else {
// we are being deleted
value = NULL;
}
gen->state = Generator_Complete;
Coroutine_NS(Continue)(gen->caller, value, true);
return value;
}
void
Generator_ctor(
Generator *gen,
size_t min_stack,
size_t min_stack_headroom,
void *(*start)(void *),
void *param
){
gen->start = start;
gen->param = param;
gen->coroutine = Coroutine_NS(New)(min_stack, min_stack_headroom, do_start);
gen->state = Generator_Running;
}
Generator *
Generator_New(
size_t min_stack,
size_t min_stack_headroom,
void *(*start)(void *),
void *param
){
Generator *gen = malloc(sizeof(Generator));
Generator_ctor(gen, min_stack, min_stack_headroom, start, param);
return gen;
}
void
Generator_dtor(
Generator *gen
){
assert(gen->state != Generator_Deleting);
if (gen->state == Generator_Running){
gen->state = Generator_Deleting;
gen->caller = Coroutine_NS(GetActive)();
Coroutine_NS(Continue)(gen->coroutine, gen, true);
Coroutine_NS(Yield)(NULL, on_yield_gen_caller, gen);
}
assert(gen->state == Generator_Complete);
Coroutine_NS(Delete)(gen->coroutine);
}
void
Generator_Delete(
Generator *gen
){
Generator_dtor(gen);
free(gen);
}
bool
Generator_Next(
Generator *gen,
void **value
){
assert(gen->state != Generator_Deleting);
if (gen->state == Generator_Complete){
return false;
}
gen->caller = Coroutine_NS(GetActive)();
Coroutine_NS(Continue)(gen->coroutine, gen, true);
*value = Coroutine_NS(Yield)(NULL, on_yield_gen_caller, gen);
return Coroutine_NS(IsRunning)(gen->coroutine);
}
bool
Generator_Yield(
void *value
)
{
assert(g_active_generator);
Generator *gen = g_active_generator;
g_active_generator = NULL;
Coroutine_NS(Yield)(value, on_yield_gen, gen);
g_active_generator = gen;
return gen->state == Generator_Running;
}