Cannot use const instead of a sub once compiled
Closed this issue · 5 comments
Try the uncompiled version of the script provided there
> perl test.pl
myscript at test.pl line 9.
DONE.
but once compiled the _OPTIONS is not available
> perlcc -r test.pl
Undefined subroutine &myscript::_OPTIONS called at test.pl line 11.
if you use the
sub _OPTIONS { return ( 'all', 'helper' ) }
instead of
use constant _OPTIONS => ( 'all', 'helper' );
then it works compiled or uncompiled
package Master;
sub new {
my ( $class, @args ) = @_;
warn $class;
join ' ', $class->_OPTIONS();
return $class;
}
package myscript;
use base ('Master');
# works compiled & uncompiled if defined as a sub
#sub _OPTIONS { return ( 'all', 'helper' ) }
# failed in the compiled version
use constant _OPTIONS => ( 'all', 'helper' );
__PACKAGE__->new(@ARGV)->run() unless caller;
sub run {
my ($self) = @_;
print "DONE.\n";
}
1;
try to get some extra information using Devel::Peek which can be used once lazy compiled
warn join ' ', "ISA: ", @myscript::ISA, "\n";
eval q{use Devel::Peek; Devel::Peek::Dump(\*myscript::_OPTIONS) };
uncompiled version, note the NULL SV in the GP
> perl test.pl
ISA: Master
SV = IV(0xfada38) at 0xfada48
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0xfada00
SV = PVGV(0xffd690) at 0xfada00
REFCNT = 3
FLAGS = (RMG,MULTI)
MAGIC = 0xf7a5e0
MG_VIRTUAL = &PL_vtbl_backref
MG_TYPE = PERL_MAGIC_backref(<)
MG_OBJ = 0xf6be00
NAME = "_OPTIONS"
NAMELEN = 8
GvSTASH = 0xf76b10 "myscript"
FLAGS = 0x2
GP = 0xf79020
SV = 0x0
REFCNT = 1
IO = 0x0
FORM = 0x0
AV = 0x0
HV = 0x0
CV = 0xf6be00
CVGEN = 0x0
GPFLAGS = 0x0 ()
LINE = 1
FILE = "(eval 1)"
EGV = 0xfada00 "_OPTIONS"
myscript at test.pl line 7.
DONE.
# compiled version
ISA: Master
SV = IV(0x1152438) at 0x1152448
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x10fe330
SV = PVGV(0x10f6c60) at 0x10fe330
REFCNT = 5
FLAGS = (RMG,MULTI)
MAGIC = 0x1101f80
MG_VIRTUAL = &PL_vtbl_backref
MG_TYPE = PERL_MAGIC_backref(<)
MG_OBJ = 0x6d1748
NAME = "_OPTIONS"
NAMELEN = 8
GvSTASH = 0x10f3d88 "myscript"
FLAGS = 0x2
GP = 0x1101f00
SV = 0x10fe348
REFCNT = 1
IO = 0x0
FORM = 0x0
AV = 0x0
HV = 0x0
CV = 0x6d1748
CVGEN = 0x0
GPFLAGS = 0x0 ()
LINE = 7914
FILE = "/usr/local/cpanel/3rdparty/perl/524/lib64/perl5/cpanel_lib/x86_64-linux-64int/B/C.pm"
EGV = 0x10fe330 "_OPTIONS"
myscript at test.pl line 7.
Undefined subroutine &myscript::_OPTIONS called at test.pl line 8.
using an arrayref for the constant _OPTIONS, also fix the issue...
when using use constant _OPTIONS => ( 'all', 'helper' );
this would generate one PVAV with FLAGS = (READONLY,PROTECT)
SV = PVAV(0x20e30c0) at 0x2108520
REFCNT = 2
FLAGS = (READONLY,PROTECT)
ARRAY = 0x2099830
FILL = 1
MAX = 3
ARYLEN = 0x0
FLAGS = (REAL)
Elt No. 0
SV = PV(0x20b7710) at 0x20be798
REFCNT = 1
FLAGS = (PADTMP,POK,IsCOW,READONLY,PROTECT,pPOK)
PV = 0x20b4fb0 "all"\0
CUR = 3
LEN = 10
COW_REFCNT = 0
Elt No. 1
SV = PV(0x20b7700) at 0x20be780
REFCNT = 1
FLAGS = (PADTMP,POK,IsCOW,READONLY,PROTECT,pPOK)
PV = 0x20bad90 "helper"\0
CUR = 6
LEN = 10
COW_REFCNT = 0
and when using use constant _OPTIONS => [ 'all', 'helper' ];
the PVAV do not have the READONLY flag it's at the RV level
SV = IV(0x1bd2450) at 0x1bd2460
REFCNT = 2
FLAGS = (ROK,READONLY)
RV = 0x1b4fc10
SV = PVAV(0x1b321e0) at 0x1b4fc10
REFCNT = 1
FLAGS = ()
ARRAY = 0x1b56810
FILL = 1
MAX = 1
ARYLEN = 0x0
FLAGS = (REAL)
Elt No. 0
SV = PV(0x1b31000) at 0x1b50390
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK)
PV = 0x1b7efb0 "all"\0
CUR = 3
LEN = 10
COW_REFCNT = 0
Elt No. 1
SV = PV(0x1b31390) at 0x1b50198
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK)
PV = 0x1b84d90 "helper"\0
CUR = 6
LEN = 10
B::C fails to detect the CONSTSUB at Warning: Undefined const sub $cvstashname::$cvname
CV 0x7fce2230e130 as PVGV 0x7fce222d3298 myscript::_OPTIONS CvFLAGS=0x100c
CV CONST 0x7fce222d3298 myscript::_OPTIONS -> 0x7fce22a2c920 as B::AV
Warning: Undefined const sub myscript::_OPTIONS -> B::AV=SCALAR(0x7fce22a2c920)
saving myscript::_OPTIONS CV 0x7fce2230e130 as &sv_list[15]
Warning: Empty &myscript::_OPTIONS
Fixed by allowing AV being the SV.
an easier one liner to trigger the problem
> perlcc -r -e 'use constant _OPTIONS => ( qw{a b c} ); eval q{ print "======\n"; use Devel::Peek; Dump _OPTIONS(); } or die $@;'
======
Undefined subroutine &main::_OPTIONS called at (eval 1) line 1.
vs
> perlcc -r -e 'use constant _OPTIONS => [ qw{a b c} ]; eval q{ print "======\n"; use Devel::Peek; Dump _OPTIONS(); };'
======
SV = IV(0x609948) at 0x609950
REFCNT = 3
FLAGS = (ROK)
RV = 0x6098f0
SV = PVAV(0x6095e0) at 0x6098f0
REFCNT = 1
FLAGS = ()
ARRAY = 0x8e4af0
FILL = 2
MAX = 2
ARYLEN = 0x0
FLAGS = (REAL)
Elt No. 0
SV = PV(0x6093e0) at 0x609908
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK)
PV = 0x407198 "a"\0
CUR = 1
LEN = 3
COW_REFCNT = 255
Elt No. 1
SV = PV(0x609400) at 0x609920
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK)
PV = 0x40719c "b"\0
CUR = 1
LEN = 3
COW_REFCNT = 255
Elt No. 2
SV = PV(0x609420) at 0x609938
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK)
PV = 0x4071a0 "c"\0
CUR = 1
LEN = 3
COW_REFCNT = 255