Skip Menu |

This queue is for tickets about the Params-Lazy CPAN distribution.

Report information
The Basics
Id: 99807
Status: open
Priority: 0/
Queue: Params-Lazy

People
Owner: Nobody in particular
Requestors: 'spro^^*%*^6ut# [...] &$%*c
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: [PATCH] Fix for bleadperl and more
The attached file contains four patches, which are self-explanatory. You should be able to feed the attachment straight to ‘git am’ to apply them all at once. I have not tested these patches fully except in bleadperl.
Subject: patches.txt
From: Father Chrysostomos <sprout@cpan.org> op_lastsib support In bleadperl, ops now have a lastsib field and debugging builds will fail assertions if it has the wrong value. The new op_sibling_splice function takes care of setting op_lastsib, so use it for op_sibling manipulation where appropriate. (Some cases of op_sibling manipulation weren’t causing any assertion failures, so I left them as they were.) diff -rup Params-Lazy-0.005-fW8fCO-orig/Lazy.xs Params-Lazy-0.005-fW8fCO/Lazy.xs --- Params-Lazy-0.005-fW8fCO-orig/Lazy.xs 2014-10-25 22:20:10.000000000 -0700 +++ Params-Lazy-0.005-fW8fCO/Lazy.xs 2014-10-25 23:20:48.000000000 -0700 @@ -779,21 +779,18 @@ use_caller_args_hint(pTHX) } STATIC OP * -replace_with_delayed(pTHX_ OP* aop) { +wrap_with_delayed(pTHX_ OP* aop) { MAGIC *mg; - OP* new_op; OP* const kid = aop; - OP* const sib = kid->op_sibling; SV* magic_sv = newSVpvs("STATEMENT"); OP *listop; delay_ctx *ctx; Newx(ctx, 1, delay_ctx); - /* Disconnect the op we're delaying, then wrap it in + /* Wrap the op we're delaying in * a OP_LIST */ - kid->op_sibling = 0; /* Make GIMME in the deferred op be OPf_WANT_LIST */ op_contextualize(kid, G_ARRAY); @@ -846,9 +843,7 @@ replace_with_delayed(pTHX_ OP* aop) { /* Then put that SV place of the OPs we removed, but wrap * as a ref. */ - new_op = (OP*)newSVOP(OP_CONST, 0, newRV_noinc(magic_sv)); - new_op->op_sibling = sib; - return new_op; + return (OP*)newSVOP(OP_CONST, 0, newRV_noinc(magic_sv)); } static OP * @@ -898,13 +893,24 @@ THX_ck_delay(pTHX_ OP *entersubop, GV *n STRLEN protolen, len = 0; char * protopv = SvPV(proto, protolen); OP *aop, *prev; +#ifdef op_sibling_splice + OP *parent; +#endif PERL_UNUSED_ARG(namegv); aop = cUNOPx(entersubop)->op_first; - if (!aop->op_sibling) + if (!aop->op_sibling) { +#ifdef op_sibling_splice + parent = aop; +#endif aop = cUNOPx(aop)->op_first; + } +#ifdef op_sibling_splice + else + parent = entersubop; +#endif prev = aop; @@ -919,8 +925,17 @@ THX_ck_delay(pTHX_ OP *entersubop, GV *n /* Fallthrough */ case '^': { - aop = replace_with_delayed(aTHX_ aop); +#ifdef op_sibling_splice + op_sibling_splice(parent, prev, 1, NULL); + aop = wrap_with_delayed(aTHX_ aop); + op_sibling_splice(parent, prev, 0, aop); +#else + OP * const sib = aop->op_sibling; + aop->op_sibling = NULL; + aop = wrap_with_delayed(aTHX_ aop); prev->op_sibling = aop; + aop->op_sibling = sib; +#endif protopv[len] = '$'; break; } @@ -943,11 +958,22 @@ THX_ck_delay_caller_args(pTHX_ OP *enter OP* op = THX_ck_delay(aTHX_ entersubop, namegv, ckobj); UNOP *newop; OP *aop; +#ifdef op_sibling_splice + OP *parent; +#endif aop = cUNOPx(op)->op_first; - if (!aop->op_sibling) + if (!aop->op_sibling) { +#ifdef op_sibling_splice + parent = aop; +#endif aop = cUNOPx(aop)->op_first; + } +#ifdef op_sibling_splice + else + parent = op; +#endif for (aop = aop->op_sibling; aop->op_sibling; aop = aop->op_sibling) { } @@ -957,7 +983,11 @@ THX_ck_delay_caller_args(pTHX_ OP *enter newop->op_ppaddr = S_pp_delay; newop->op_private = use_caller_args_hint(); +#ifdef op_sibling_splice + op_sibling_splice(parent, aop, 0, (OP *)newop); +#else aop->op_sibling = (OP*)newop; +#endif return op; } From: Father Chrysostomos <sprout@cpan.org> List refgen support diff -rup Params-Lazy-0.005-fW8fCO-orig/Lazy.xs Params-Lazy-0.005-9c4xOW/Lazy.xs --- Params-Lazy-0.005-fW8fCO-orig/Lazy.xs 2014-10-25 22:20:10.000000000 -0700 +++ Params-Lazy-0.005-9c4xOW/Lazy.xs 2014-10-25 23:33:24.000000000 -0700 @@ -912,7 +912,9 @@ THX_ck_delay(pTHX_ OP *entersubop, GV *n if ( len < protolen ) { switch ( protopv[len] ) { case ':': - if ( aop->op_type == OP_REFGEN ) { + if ( aop->op_type == OP_REFGEN + && cUNOPx(cUNOPx(aop)->op_first)->op_first + ->op_sibling->op_type == OP_ANONCODE ) { protopv[len] = '&'; break; } diff -rup Params-Lazy-0.005-fW8fCO-orig/t/10-prototypes.t Params-Lazy-0.005-9c4xOW/t/10-prototypes.t --- Params-Lazy-0.005-fW8fCO-orig/t/10-prototypes.t 2013-08-27 15:55:46.000000000 -0700 +++ Params-Lazy-0.005-9c4xOW/t/10-prototypes.t 2014-10-25 23:30:23.000000000 -0700 @@ -34,6 +34,12 @@ is_deeply( 'fakemap \"_${_}_"' ); +is_deeply( + [fakemap \($_,$_), 1..10], + [ map \($_,$_), 1..10], + 'fakemap \($_,$_) (refgen, not srefgen)' +); + TODO: { local $TODO = "fakemap sub {}, 1; differs from map sub {}, 1"; is_deeply( From: Father Chrysostomos <sprout@cpan.org> perl 5.21.5 uses srefgen for anoncode diff -rup Params-Lazy-0.005-fW8fCO/Lazy.xs Params-Lazy-0.005-fW8fCO-copy/Lazy.xs --- Params-Lazy-0.005-fW8fCO/Lazy.xs 2014-10-25 23:36:26.000000000 -0700 +++ Params-Lazy-0.005-fW8fCO-copy/Lazy.xs 2014-10-25 23:41:54.000000000 -0700 @@ -918,11 +918,28 @@ THX_ck_delay(pTHX_ OP *entersubop, GV *n if ( len < protolen ) { switch ( protopv[len] ) { case ':': + /* Under perl 5.21.5: + * + * srefgen + * ex-list + * anoncode + * + * Under earlier perls: + * + * refgen + * ex-list + * pushmark + * anoncode + */ if ( aop->op_type == OP_REFGEN - && cUNOPx(cUNOPx(aop)->op_first)->op_first - ->op_sibling->op_type == OP_ANONCODE ) { + || aop->op_type == OP_SREFGEN ) { + OP *kid = cUNOPx(cUNOPx(aop)->op_first)->op_first; + if ( aop->op_type == OP_PUSHMARK ) + kid = aop->op_sibling; + if (kid->op_type == OP_ANONCODE ) { protopv[len] = '&'; break; + } } /* Fallthrough */ case '^': From: Father Chrysostomos <sprout@cpan.org> : sub{} support This allows mymap sub {}, LIST to work just like map. diff -rup Params-Lazy-0.005-fW8fCO-copy/Lazy.xs Params-Lazy-0.005-fW8fCO-copy2/Lazy.xs --- Params-Lazy-0.005-fW8fCO-copy/Lazy.xs 2014-10-25 23:41:54.000000000 -0700 +++ Params-Lazy-0.005-fW8fCO-copy2/Lazy.xs 2014-10-25 23:54:25.000000000 -0700 @@ -893,24 +893,18 @@ THX_ck_delay(pTHX_ OP *entersubop, GV *n STRLEN protolen, len = 0; char * protopv = SvPV(proto, protolen); OP *aop, *prev; -#ifdef op_sibling_splice OP *parent; -#endif PERL_UNUSED_ARG(namegv); aop = cUNOPx(entersubop)->op_first; if (!aop->op_sibling) { -#ifdef op_sibling_splice parent = aop; -#endif aop = cUNOPx(aop)->op_first; } -#ifdef op_sibling_splice else parent = entersubop; -#endif prev = aop; @@ -936,7 +930,15 @@ THX_ck_delay(pTHX_ OP *entersubop, GV *n OP *kid = cUNOPx(cUNOPx(aop)->op_first)->op_first; if ( aop->op_type == OP_PUSHMARK ) kid = aop->op_sibling; - if (kid->op_type == OP_ANONCODE ) { + if ( kid->op_type == OP_ANONCODE + /* Evil hack. + mymap sub {} LIST puts ex-rv2cv is scalar cx + mymap {} LIST puts ex-rv2cv in no cx + That's true for 5.8.8 to 5.21.5. Let's hope + it stays that way. + */ + && !(cLISTOPx(parent)->op_last->op_flags + & OPf_WANT) ) { protopv[len] = '&'; break; } diff -rup Params-Lazy-0.005-fW8fCO-copy/lib/Params/Lazy.pm Params-Lazy-0.005-fW8fCO-copy2/lib/Params/Lazy.pm --- Params-Lazy-0.005-fW8fCO-copy/lib/Params/Lazy.pm 2013-09-19 09:15:37.000000000 -0700 +++ Params-Lazy-0.005-fW8fCO-copy2/lib/Params/Lazy.pm 2014-10-25 23:45:14.000000000 -0700 @@ -185,16 +185,6 @@ Runs the delayed code. =item * -When using the C<:> prototype, these two cases are indistinguishable: - - myfunction { ... } - myfunction sub { ... } - -Which means that C<mymap sub { ... }, 1..10> will work -differently than the default map. - -=item * - It's important to note that delayed arguments are C<*not*> closures, so storing them for later use will likely lead to crashes, segfaults, and a general feeling of malignancy to descend upon you, your family, diff -rup Params-Lazy-0.005-fW8fCO-copy/t/10-prototypes.t Params-Lazy-0.005-fW8fCO-copy2/t/10-prototypes.t --- Params-Lazy-0.005-fW8fCO-copy/t/10-prototypes.t 2014-10-25 23:36:26.000000000 -0700 +++ Params-Lazy-0.005-fW8fCO-copy2/t/10-prototypes.t 2014-10-25 23:44:54.000000000 -0700 @@ -40,14 +40,11 @@ is_deeply( 'fakemap \($_,$_) (refgen, not srefgen)' ); -TODO: { - local $TODO = "fakemap sub {}, 1; differs from map sub {}, 1"; - is_deeply( +is_deeply( [map ref, fakemap sub { "_${_}_"}, 1..10], [map ref, map sub { "_${_}_"}, 1..10], 'fakemap sub {}' - ); -} +); is_deeply( [fakemap [ "_${_}_" ], 1..10],
On Sun Oct 26 03:03:51 2014, SPROUT wrote: Show quoted text
> The attached file contains four patches, which are self-explanatory. > You should be able to feed the attachment straight to ‘git am’ to > apply them all at once. > > I have not tested these patches fully except in bleadperl.
Sigh. This line from the comment is filled with typoes: mymap sub {} LIST puts ex-rv2cv is scalar cx There should be a comma after {} and ‘is’ should be ‘in’.