rurban/perl-compiler

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