… | |
… | |
214 | |
214 | |
215 | #define PERL_MAGIC_coro PERL_MAGIC_ext |
215 | #define PERL_MAGIC_coro PERL_MAGIC_ext |
216 | |
216 | |
217 | static MGVTBL vtbl_coro = {0, 0, 0, 0, coro_cv_free}; |
217 | static MGVTBL vtbl_coro = {0, 0, 0, 0, coro_cv_free}; |
218 | |
218 | |
|
|
219 | #define CORO_MAGIC(cv) \ |
|
|
220 | SvMAGIC (cv) \ |
|
|
221 | ? SvMAGIC (cv)->mg_type == PERL_MAGIC_coro \ |
|
|
222 | ? SvMAGIC (cv) \ |
|
|
223 | : mg_find ((SV *)cv, PERL_MAGIC_coro) \ |
|
|
224 | : 0 |
|
|
225 | |
219 | /* the next two functions merely cache the padlists */ |
226 | /* the next two functions merely cache the padlists */ |
220 | static void |
227 | static void |
221 | get_padlist (CV *cv) |
228 | get_padlist (CV *cv) |
222 | { |
229 | { |
223 | MAGIC *mg = mg_find ((SV *)cv, PERL_MAGIC_coro); |
230 | MAGIC *mg = CORO_MAGIC (cv); |
|
|
231 | AV *av; |
224 | |
232 | |
225 | if (mg && AvFILLp ((AV *)mg->mg_obj) >= 0) |
233 | if (mg && AvFILLp ((av = (AV *)mg->mg_obj)) >= 0) |
226 | CvPADLIST (cv) = (AV *)av_pop ((AV *)mg->mg_obj); |
234 | CvPADLIST (cv) = (AV *)AvARRAY (av)[AvFILLp (av)--]; |
227 | else |
235 | else |
228 | { |
236 | { |
229 | #if 0 |
237 | #if 0 |
230 | /* this is probably cleaner, but also slower? */ |
238 | /* this is probably cleaner, but also slower? */ |
231 | CV *cp = Perl_cv_clone (cv); |
239 | CV *cp = Perl_cv_clone (cv); |
… | |
… | |
239 | } |
247 | } |
240 | |
248 | |
241 | static void |
249 | static void |
242 | put_padlist (CV *cv) |
250 | put_padlist (CV *cv) |
243 | { |
251 | { |
244 | MAGIC *mg = mg_find ((SV *)cv, PERL_MAGIC_coro); |
252 | MAGIC *mg = CORO_MAGIC (cv); |
|
|
253 | AV *av; |
245 | |
254 | |
246 | if (!mg) |
255 | if (!mg) |
247 | { |
256 | { |
248 | sv_magic ((SV *)cv, 0, PERL_MAGIC_coro, 0, 0); |
257 | sv_magic ((SV *)cv, 0, PERL_MAGIC_coro, 0, 0); |
249 | mg = mg_find ((SV *)cv, PERL_MAGIC_coro); |
258 | mg = mg_find ((SV *)cv, PERL_MAGIC_coro); |
250 | mg->mg_virtual = &vtbl_coro; |
259 | mg->mg_virtual = &vtbl_coro; |
251 | mg->mg_obj = (SV *)newAV (); |
260 | mg->mg_obj = (SV *)newAV (); |
252 | } |
261 | } |
253 | |
262 | |
254 | av_push ((AV *)mg->mg_obj, (SV *)CvPADLIST (cv)); |
263 | av = (AV *)mg->mg_obj; |
|
|
264 | |
|
|
265 | if (AvFILLp (av) >= AvMAX (av)) |
|
|
266 | av_extend (av, AvMAX (av) + 1); |
|
|
267 | |
|
|
268 | AvARRAY (av)[++AvFILLp (av)] = (SV *)CvPADLIST (cv); |
255 | } |
269 | } |
256 | |
270 | |
257 | #define SB do { |
271 | #define SB do { |
258 | #define SE } while (0) |
272 | #define SE } while (0) |
259 | |
273 | |
… | |
… | |
278 | CV *cv; |
292 | CV *cv; |
279 | |
293 | |
280 | /* now do the ugly restore mess */ |
294 | /* now do the ugly restore mess */ |
281 | while ((cv = (CV *)POPs)) |
295 | while ((cv = (CV *)POPs)) |
282 | { |
296 | { |
283 | AV *padlist = (AV *)POPs; |
|
|
284 | |
|
|
285 | if (padlist) |
|
|
286 | { |
|
|
287 | put_padlist (cv); /* mark this padlist as available */ |
297 | put_padlist (cv); /* mark this padlist as available */ |
288 | CvPADLIST(cv) = padlist; |
298 | CvDEPTH (cv) = PTR2IV (POPs); |
289 | } |
299 | CvPADLIST (cv) = (AV *)POPs; |
290 | |
|
|
291 | ++CvDEPTH(cv); |
|
|
292 | } |
300 | } |
293 | |
301 | |
294 | PUTBACK; |
302 | PUTBACK; |
295 | } |
303 | } |
296 | } |
304 | } |
… | |
… | |
318 | PERL_CONTEXT *cx = &ccstk[cxix--]; |
326 | PERL_CONTEXT *cx = &ccstk[cxix--]; |
319 | |
327 | |
320 | if (CxTYPE(cx) == CXt_SUB) |
328 | if (CxTYPE(cx) == CXt_SUB) |
321 | { |
329 | { |
322 | CV *cv = cx->blk_sub.cv; |
330 | CV *cv = cx->blk_sub.cv; |
|
|
331 | |
323 | if (CvDEPTH(cv)) |
332 | if (CvDEPTH (cv)) |
324 | { |
333 | { |
325 | EXTEND (SP, CvDEPTH(cv)*2); |
334 | EXTEND (SP, 3); |
326 | |
|
|
327 | while (--CvDEPTH(cv)) |
|
|
328 | { |
|
|
329 | /* this tells the restore code to increment CvDEPTH */ |
|
|
330 | PUSHs (Nullsv); |
|
|
331 | PUSHs ((SV *)cv); |
|
|
332 | } |
|
|
333 | |
335 | |
334 | PUSHs ((SV *)CvPADLIST(cv)); |
336 | PUSHs ((SV *)CvPADLIST(cv)); |
|
|
337 | PUSHs (INT2PTR (SV *, CvDEPTH (cv))); |
335 | PUSHs ((SV *)cv); |
338 | PUSHs ((SV *)cv); |
336 | |
339 | |
|
|
340 | CvDEPTH (cv) = 0; |
337 | get_padlist (cv); |
341 | get_padlist (cv); |
338 | } |
342 | } |
339 | } |
343 | } |
340 | #ifdef CXt_FORMAT |
344 | #ifdef CXt_FORMAT |
341 | else if (CxTYPE(cx) == CXt_FORMAT) |
345 | else if (CxTYPE(cx) == CXt_FORMAT) |