Subject: | Breakage on some imported subs. [ w/ possible solution ] |
perl -Ilib -MO=RecDeparse,level,3 -e 'package Bar; use version qw(qv); qv(q{1.0})';
Seems the problem is its thinking the Nullsv special is a sub trying to enter it, but doing it wrong.
Here is a modified pp_gv that does fallthrough on this case and produces working output:
sub pp_gv {
my $self = shift;
my $body;
if ($self->{brd_sub} <= 0 || !$self->_recurse) {
$body = $self->SUPER::pp_gv(@_);
} else {
my $gv = $self->gv_or_padgv($_[0]);
my $sv = $gv->CV;
if( $sv->isa('B::SPECIAL') && $B::specialsv_name[$$sv] eq "Nullsv" ) {
$body = $self->SUPER::pp_gv(@_);
} else {
$body = do {
local @{$self}{qw/brd_sub brd_cur/} = (0, $self->{brd_cur} + 1);
'sub ' . $self->indent($self->deparse_sub($gv->CV));
};
if (FOOL_SINGLE_DELIM) {
$body = $key . $body;
} else {
$body .= '->';
}
}
}
return $body;
}
perl -Ilib -MO=RecDeparse,level,3 -e 'package Bar; use version qw(qv); qv(q{1.0})'
package Bar;
sub BEGIN {
require version;
do {
'version'->import('qv')
};
}
sub {
package version;
return $class->qv(shift @_);
}->('1.0');
-e syntax OK
While deparsing /usr/lib64/perl5/vendor_perl/5.12.2/x86_64-linux-thread-multi/version.pm near line 184, SPECIAL in deparse_sub at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 854 B::Deparse::deparse_sub('B::RecDeparse=HASH(0x11e6eb8)', 'B::SPECIAL=SCALAR(0x16a4a20)') called at /usr/lib64/perl5/vendor_perl/5.12.2/B/RecDeparse.pm line 151 B::RecDeparse::pp_gv('B::RecDeparse=HASH(0x11e6eb8)', 'B::PADOP=SCALAR(0x16a4c60)', 0) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 818 B::Deparse::deparse('B::RecDeparse=HASH(0x11e6eb8)', 'B::PADOP=SCALAR(0x16a4c60)', 0) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 2903 B::Deparse::rv2x('B::RecDeparse=HASH(0x11e6eb8)', 'B::UNOP=SCALAR(0x16bb398)', 16, '@') called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 2980 B::Deparse::pp_rv2av('B::RecDeparse=HASH(0x11e6eb8)', 'B::UNOP=SCALAR(0x16bb398)', 16) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 818 B::Deparse::deparse('B::RecDeparse=HASH(0x11e6eb8)', 'B::UNOP=SCALAR(0x16bb398)', 16) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 1009 B::Deparse::maybe_parens_unop('B::RecDeparse=HASH(0x11e6eb8)', 'shift', 'B::UNOP=SCALAR(0x16bb398)', 6) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 1610 B::Deparse::unop('B::RecDeparse=HASH(0x11e6eb8)', 'B::UNOP=SCALAR(0x16ba848)', 6, 'shift') called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 1653 B::Deparse::pp_shift('B::RecDeparse=HASH(0x11e6eb8)', 'B::UNOP=SCALAR(0x16ba848)', 6) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 818 B::Deparse::deparse('B::RecDeparse=HASH(0x11e6eb8)', 'B::UNOP=SCALAR(0x16ba848)', 6) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 3215 B::Deparse::e_method('B::RecDeparse=HASH(0x11e6eb8)', 'HASH(0x16baae8)') called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 3306 B::Deparse::pp_entersub('B::RecDeparse=HASH(0x11e6eb8)', 'B::UNOP=SCALAR(0x168b360)', 6) called at /usr/lib64/perl5/vendor_perl/5.12.2/B/RecDeparse.pm line 128 B::RecDeparse::pp_entersub('B::RecDeparse=HASH(0x11e6eb8)', 'B::UNOP=SCALAR(0x168b360)', 6) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 818 B::Deparse::deparse('B::RecDeparse=HASH(0x11e6eb8)', 'B::UNOP=SCALAR(0x168b360)', 6) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 2279 B::Deparse::listop('B::RecDeparse=HASH(0x11e6eb8)', 'B::LISTOP=SCALAR(0x16a0628)', 0.5, 'return') called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 2324 B::Deparse::pp_return('B::RecDeparse=HASH(0x11e6eb8)', 'B::LISTOP=SCALAR(0x16a0628)', 0.5) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 818 B::Deparse::deparse('B::RecDeparse=HASH(0x11e6eb8)', 'B::LISTOP=SCALAR(0x16a0628)', 0.5) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 1219 B::Deparse::walk_lineseq('B::RecDeparse=HASH(0x11e6eb8)', undef, 'ARRAY(0x13bd150)', 'CODE(0x168b1b0)') called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 1131 B::Deparse::lineseq('B::RecDeparse=HASH(0x11e6eb8)', undef, 'B::COP=SCALAR(0x168afe8)', 'B::LISTOP=SCALAR(0x16a0628)') called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 878 B::Deparse::deparse_sub('B::RecDeparse=HASH(0x11e6eb8)', 'B::CV=SCALAR(0x1684bb8)') called at /usr/lib64/perl5/vendor_perl/5.12.2/B/RecDeparse.pm line 151 B::RecDeparse::pp_gv('B::RecDeparse=HASH(0x11e6eb8)', 'B::PADOP=SCALAR(0x16a04a8)', 24) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 818 B::Deparse::deparse('B::RecDeparse=HASH(0x11e6eb8)', 'B::PADOP=SCALAR(0x16a04a8)', 24) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 2810 B::Deparse::pp_null('B::RecDeparse=HASH(0x11e6eb8)', 'B::UNOP=SCALAR(0x165ba78)', 24) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 818 B::Deparse::deparse('B::RecDeparse=HASH(0x11e6eb8)', 'B::UNOP=SCALAR(0x165ba78)', 24) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 3332 B::Deparse::pp_entersub('B::RecDeparse=HASH(0x11e6eb8)', 'B::UNOP=SCALAR(0x16a0148)', 0.5) called at /usr/lib64/perl5/vendor_perl/5.12.2/B/RecDeparse.pm line 128 B::RecDeparse::pp_entersub('B::RecDeparse=HASH(0x11e6eb8)', 'B::UNOP=SCALAR(0x16a0148)', 0.5) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 818 B::Deparse::deparse('B::RecDeparse=HASH(0x11e6eb8)', 'B::UNOP=SCALAR(0x16a0148)', 0.5) called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 1219 B::Deparse::walk_lineseq('B::RecDeparse=HASH(0x11e6eb8)', 'B::LISTOP=SCALAR(0x16778b8)', 'ARRAY(0x13c7778)', 'CODE(0x16a0118)') called at /usr/lib64/perl5/5.12.2/B/Deparse.pm line 1200 B::Deparse::deparse_root('B::RecDeparse=HASH(0x11e6eb8)', 'B::LISTOP=SCALAR(0x16778b8)') called at (eval 10) line 37 B::RecDeparse::__ANON__() called at (eval 1) line 31 O::CHECK() called at -e line 0 eval {...} called at -e line 0 CHECK failed--call queue aborted.
Seems the problem is its thinking the Nullsv special is a sub trying to enter it, but doing it wrong.
Here is a modified pp_gv that does fallthrough on this case and produces working output:
sub pp_gv {
my $self = shift;
my $body;
if ($self->{brd_sub} <= 0 || !$self->_recurse) {
$body = $self->SUPER::pp_gv(@_);
} else {
my $gv = $self->gv_or_padgv($_[0]);
my $sv = $gv->CV;
if( $sv->isa('B::SPECIAL') && $B::specialsv_name[$$sv] eq "Nullsv" ) {
$body = $self->SUPER::pp_gv(@_);
} else {
$body = do {
local @{$self}{qw/brd_sub brd_cur/} = (0, $self->{brd_cur} + 1);
'sub ' . $self->indent($self->deparse_sub($gv->CV));
};
if (FOOL_SINGLE_DELIM) {
$body = $key . $body;
} else {
$body .= '->';
}
}
}
return $body;
}
perl -Ilib -MO=RecDeparse,level,3 -e 'package Bar; use version qw(qv); qv(q{1.0})'
package Bar;
sub BEGIN {
require version;
do {
'version'->import('qv')
};
}
sub {
package version;
return $class->qv(shift @_);
}->('1.0');
-e syntax OK