… | |
… | |
29 | OP **retstack; |
29 | OP **retstack; |
30 | I32 retstack_ix; |
30 | I32 retstack_ix; |
31 | I32 retstack_max; |
31 | I32 retstack_max; |
32 | COP *curcop; |
32 | COP *curcop; |
33 | |
33 | |
|
|
34 | AV *defav; |
|
|
35 | |
34 | SV *proc; |
36 | SV *proc; |
35 | }; |
37 | }; |
36 | |
38 | |
37 | typedef struct coro *Coro__State; |
39 | typedef struct coro *Coro__State; |
38 | typedef struct coro *Coro__State_or_hashref; |
40 | typedef struct coro *Coro__State_or_hashref; |
… | |
… | |
61 | c->savestack_ix = PL_savestack_ix; \ |
63 | c->savestack_ix = PL_savestack_ix; \ |
62 | c->savestack_max = PL_savestack_max; \ |
64 | c->savestack_max = PL_savestack_max; \ |
63 | c->retstack = PL_retstack; \ |
65 | c->retstack = PL_retstack; \ |
64 | c->retstack_ix = PL_retstack_ix; \ |
66 | c->retstack_ix = PL_retstack_ix; \ |
65 | c->retstack_max = PL_retstack_max; \ |
67 | c->retstack_max = PL_retstack_max; \ |
66 | c->curcop = PL_curcop; |
68 | c->curcop = PL_curcop; \ |
|
|
69 | c->defav = GvAV (PL_defgv); |
67 | |
70 | |
68 | #define LOAD(c) \ |
71 | #define LOAD(c) \ |
69 | PL_dowarn = c->dowarn; \ |
72 | PL_dowarn = c->dowarn; \ |
70 | PL_curstackinfo = c->curstackinfo; \ |
73 | PL_curstackinfo = c->curstackinfo; \ |
71 | PL_curstack = c->curstack; \ |
74 | PL_curstack = c->curstack; \ |
… | |
… | |
89 | PL_savestack_ix = c->savestack_ix; \ |
92 | PL_savestack_ix = c->savestack_ix; \ |
90 | PL_savestack_max = c->savestack_max; \ |
93 | PL_savestack_max = c->savestack_max; \ |
91 | PL_retstack = c->retstack; \ |
94 | PL_retstack = c->retstack; \ |
92 | PL_retstack_ix = c->retstack_ix; \ |
95 | PL_retstack_ix = c->retstack_ix; \ |
93 | PL_retstack_max = c->retstack_max; \ |
96 | PL_retstack_max = c->retstack_max; \ |
94 | PL_curcop = c->curcop; |
97 | PL_curcop = c->curcop; \ |
|
|
98 | GvAV (PL_defgv) = c->defav; |
95 | |
99 | |
96 | /* this is an EXACT copy of S_nuke_stacks in perl.c, which is unfortunately static */ |
100 | /* this is an EXACT copy of S_nuke_stacks in perl.c, which is unfortunately static */ |
97 | STATIC void |
101 | STATIC void |
98 | S_nuke_stacks(pTHX) |
102 | S_nuke_stacks(pTHX) |
99 | { |
103 | { |
… | |
… | |
137 | transfer(prev,next) |
141 | transfer(prev,next) |
138 | Coro::State_or_hashref prev |
142 | Coro::State_or_hashref prev |
139 | Coro::State_or_hashref next |
143 | Coro::State_or_hashref next |
140 | CODE: |
144 | CODE: |
141 | |
145 | |
142 | PUTBACK; |
146 | if (prev != next) |
143 | SAVE (prev); |
|
|
144 | |
|
|
145 | /* |
|
|
146 | * this could be done in newprocess which would to |
|
|
147 | * extremely elegant and fast (just PUTBACK/SAVE/LOAD/SPAGAIN) |
|
|
148 | * code here, but lazy allocation of stacks has also |
|
|
149 | * some virtues and the overhead of the if() is nil. |
|
|
150 | */ |
|
|
151 | if (next->mainstack) |
|
|
152 | { |
147 | { |
153 | LOAD (next); |
|
|
154 | next->mainstack = 0; /* unnecessary but much cleaner */ |
|
|
155 | SPAGAIN; |
148 | PUTBACK; |
156 | } |
149 | SAVE (prev); |
157 | else |
150 | |
158 | { |
|
|
159 | /* |
151 | /* |
160 | * emulate part of the perl startup here. |
152 | * this could be done in newprocess which would to |
|
|
153 | * extremely elegant and fast (just PUTBACK/SAVE/LOAD/SPAGAIN) |
|
|
154 | * code here, but lazy allocation of stacks has also |
|
|
155 | * some virtues and the overhead of the if() is nil. |
161 | */ |
156 | */ |
|
|
157 | if (next->mainstack) |
|
|
158 | { |
|
|
159 | LOAD (next); |
|
|
160 | next->mainstack = 0; /* unnecessary but much cleaner */ |
|
|
161 | SPAGAIN; |
|
|
162 | } |
|
|
163 | else |
|
|
164 | { |
|
|
165 | /* |
|
|
166 | * emulate part of the perl startup here. |
|
|
167 | */ |
162 | UNOP myop; |
168 | UNOP myop; |
163 | |
169 | |
164 | init_stacks (); |
170 | init_stacks (); |
165 | PL_op = (OP *)&myop; |
171 | PL_op = (OP *)&myop; |
166 | /*PL_curcop = 0;*/ |
172 | /*PL_curcop = 0;*/ |
|
|
173 | GvAV (PL_defgv) = newAV (); |
167 | |
174 | |
168 | SPAGAIN; |
175 | SPAGAIN; |
169 | Zero(&myop, 1, UNOP); |
176 | Zero(&myop, 1, UNOP); |
170 | myop.op_next = Nullop; |
177 | myop.op_next = Nullop; |
171 | myop.op_flags = OPf_WANT_VOID; |
178 | myop.op_flags = OPf_WANT_VOID; |
172 | |
179 | |
173 | EXTEND (SP,1); |
180 | EXTEND (SP,1); |
174 | PUSHs (next->proc); |
181 | PUSHs (next->proc); |
175 | |
182 | |
176 | PUTBACK; |
183 | PUTBACK; |
177 | /* |
184 | /* |
178 | * the next line is slightly wrong, as PL_op->op_next |
185 | * the next line is slightly wrong, as PL_op->op_next |
179 | * is actually being executed so we skip the first op |
186 | * is actually being executed so we skip the first op |
180 | * that doens't matter, though, since it is only |
187 | * that doens't matter, though, since it is only |
181 | * pp_nextstate and we never return... |
188 | * pp_nextstate and we never return... |
182 | */ |
189 | */ |
183 | PL_op = Perl_pp_entersub(aTHX); |
190 | PL_op = Perl_pp_entersub(aTHX); |
184 | SPAGAIN; |
191 | SPAGAIN; |
185 | |
192 | |
186 | ENTER; |
193 | ENTER; |
|
|
194 | } |
187 | } |
195 | } |
188 | |
196 | |
189 | void |
197 | void |
190 | DESTROY(coro) |
198 | DESTROY(coro) |
191 | Coro::State coro |
199 | Coro::State coro |
… | |
… | |
198 | PUTBACK; |
206 | PUTBACK; |
199 | SAVE((&temp)); |
207 | SAVE((&temp)); |
200 | LOAD(coro); |
208 | LOAD(coro); |
201 | |
209 | |
202 | S_nuke_stacks (); |
210 | S_nuke_stacks (); |
|
|
211 | SvREFCNT_dec ((SV *)GvAV (PL_defgv)); |
203 | |
212 | |
204 | LOAD((&temp)); |
213 | LOAD((&temp)); |
205 | SPAGAIN; |
214 | SPAGAIN; |
206 | } |
215 | } |
207 | |
216 | |