Viewing File: /usr/local/cpanel/3rdparty/perl/536/cpanel-lib/x86_64-linux/B/C/OverLoad/B/PV.pm

package B::PV;

use B::C::Std;

use B               qw/SVf_IsCOW SVf_ROK SVf_POK SVp_POK SVs_GMG SVt_PVGV SVf_READONLY SVf_FAKE/;
use B::C::Debug     qw/debug/;
use B::C::Save      qw/savecowpv/;
use B::C::Save::Hek qw/save_shared_he get_sHe_HEK/;
use B::C::File      qw/xpvsect svsect free/;
use B::C::Helpers   qw/is_shared_hek/;

sub SVpbm_VALID { 0x40000000 }
sub SVp_SCREAM  { 0x00008000 }    # method name is DOES

sub do_save ( $sv, $fullname = undef, $custom = undef ) {

    #if ( !length $fullname ) {
    #    print STDERR B::C::Save::stack_flat();
    #    die("B::PV requires a \$fullname be passed to save please!");
    #}

    my ( $ix, $sym ) = svsect()->reserve($sv);
    svsect()->debug( $fullname, $sv );

    my $shared_hek = is_shared_hek($sv);

    my ( $savesym, $cur, $len, $pv, $flags ) = $sv->save_svu( $sym, $fullname );

    # sv_free2 problem with !SvIMMORTAL and del_SV
    my $refcnt = $sv->REFCNT;
    if ( $fullname && $fullname eq 'svop const' ) {
        $refcnt = 0x7fffffff;
    }

    if ( ref $custom ) {    # used when downgrading a PVIV / PVNV to IV
        $flags  = $custom->{flags}  if defined $custom->{flags};
        $refcnt = $custom->{refcnt} if defined $custom->{refcnt};
        $flags &= $custom->{update_flags} if defined $custom->{update_flags};
    }

    # static pv, do not destruct. test 13 with pv0 "3".
    if ( !$shared_hek and $flags & SVf_READONLY and !$len ) {
        $flags ^= SVf_FAKE;    # turn off SVf_FAKE
        debug( pv => "turn off SVf_FAKE %s %s\n", $pv, $fullname );
    }

    my $xpv_sym = 'NULL';
    if ( $sv->HAS_ANY ) {
        xpvsect()->comment("stash, magic, cur, len");
        my $xpv_ix = xpvsect()->sadd( "Nullhv, {0}, %u, {%u}", $cur, $len );

        $xpv_sym = sprintf( '&xpv_list[%d]', $xpv_ix );
    }

    svsect()->comment("any, refcnt, flags, sv_u");
    my $sv_ix = svsect()->supdatel(
        $ix,
        '%s'   => $xpv_sym,
        '%Lu'  => $refcnt,
        '0x%x' => $flags,
        '{%s}' => $savesym
    );

    return $sym;
}

sub save_svu ( $sv, $sym, $fullname, @ ) {

    my $flags = $sv->FLAGS;

    # This is an RV so the svu points to another SV.
    if ( $flags & SVf_ROK ) {
        my $savesym = B::RV::save_rv( $sv, $sym, $fullname );

        my $flags = $sv->FLAGS;

        # GV should never have an ROK flag. that's just wierd.
        die( sprintf( "Unexpected Flags (0x%x) for %s in save_svu for ROK\n", $flags, ref $sv ) ) if ( $flags & SVt_PVGV ) == SVt_PVGV;

        my $pv = "RV DEBUG ONLY STRING";
        $savesym = ".svu_rv=$savesym";
        return ( $savesym, $sv->CUR, $sv->LEN, $pv, $flags );
    }

    if ( $sv->IsBool ) {

        # bool values are only sharing the PVX at this point
        my $pv = $sv->IsBoolYes ? 'PL_Yes' : 'PL_No';
        return ( ".svu_pv=(char*) $pv", $sv->CUR, $sv->LEN, $pv, $sv->FLAGS );
    }

    my $pok = $flags & ( SVf_POK | SVp_POK );
    my $gmg = $flags & SVs_GMG;

    my $shared_hek = is_shared_hek($sv);

    # Our svu points to a shared_hek.
    if ($shared_hek) {
        my $pv = $sv->PV;
        my ( $shared_he, $cur ) = save_shared_he($pv);    # we know that a shared_hek as POK
        my $len = 0;

        return ( ".svu_pv=(char*)(" . get_sHe_HEK($shared_he) . q{)->hek_key}, $cur, $len, $pv, $flags );
    }

    my $pv = "";
    my ( $savesym, $cur, $len ) = savecowpv($pv);

    # overloaded VERSION symbols fail to xs boot: ExtUtils::CBuilder with Fcntl::VERSION (i91)
    # 5.6: Can't locate object method "RV" via package "B::PV" Carp::Clan
    if ($pok) {
        $pv  = pack "a*", $sv->PV;    # XXX!
        $cur = ( $sv and $sv->can('CUR') and ref($sv) ne 'B::GV' ) ? $sv->CUR : length($pv);
    }
    else {
        if ( $gmg && $fullname ) {
            no strict 'refs';
            $pv  = ( $fullname and ref($fullname) ) ? "${$fullname}" : '';
            $cur = length( pack "a*", $pv );
            $pok = 1;
        }
    }

    if ($pok) {
        ( $savesym, $cur, $len ) = savecowpv($pv);    # only flags as COW if it's not a reference and not an empty string
        $flags |= SVf_IsCOW;
    }
    else {
        $flags ^= SVf_IsCOW;
    }

    $fullname = '' if !defined $fullname;

    if ( $fullname =~ m{^(.+)::AUTOLOAD$} ) {
        my $pkg = $1;
        if ( $pkg->can('AUTOLOAD') ) {

            # clear AUTOLOAD PV when used at compile time
            #print STDERR "## $fullname has AUTOLOAD sub\n";
            $savesym = 'NULL';
            $cur     = 0;
            $len     = 0;
            $pv      = '';
            $flags   = 0;
        }
    }

    debug( pv => "Saving pv %s %s cur=%d, len=%d, %s", $savesym, $pv, $cur, $len, $shared_hek ? "shared, $fullname" : $fullname );

    $savesym = ".svu_pv=(char*) $savesym";
    return ( $savesym, $cur, $len, $pv, $flags );
}

1;
Back to Directory File Manager