Acme-Perl-VM

 view release on metacpan or  search on metacpan

lib/Acme/Perl/VM/B.pm  view on Meta::CPAN

package Acme::Perl::VM::B;

use strict;
use warnings;

use Exporter qw(import);

use B();
our @EXPORT = grep{ /^[A-Z]/ } @B::EXPORT_OK; # constants
push @EXPORT, qw(sv_undef svref_2object);
B->import(@EXPORT);

unless(defined &OPpPAD_STATE){
    constant->import(OPpPAD_STATE => 0x00);
    push @EXPORT, qw(OPpPAD_STATE);
}
unless(defined &G_WANT){
    constant->import(G_WANT => G_SCALAR() | G_ARRAY() | G_VOID());
    push @EXPORT, qw(G_WANT);
}
unless(defined &OPpITER_REVERSED){
    constant->import(OPpITER_REVERSED => 0x00);
    push @EXPORT, qw(OPpITER_REVERSED);
}

push @EXPORT, qw(NULL TRUE FALSE USE_ITHREADS sv_yes sv_no);
use constant {
    NULL         => bless(\do{ my $addr = 0 }, 'B::SPECIAL'),
    TRUE         => 1,
    FALSE        => 0,
    USE_ITHREADS => defined(&B::regex_padav),

    sv_yes       => B::sv_yes,
    sv_no        => B::sv_no,
};


package
    B::OBJECT;

use B qw(class);

sub dump{
    my($obj) = @_;
    require Devel::Peek;
    Devel::Peek::Dump($obj->object_2svref);
    return;
}

package
    B::OP;

sub dump{
    my($obj) = @_;
    require B::Debug;

    $obj->debug;
    return;
}

package
    B::SPECIAL;

my %special_sv = (
    ${ B::sv_undef() } => \(undef),
    ${ B::sv_yes() }   => \(1 == 1),
    ${ B::sv_no() }    => \(1 != 1),
);

unless(@B::specialsv_name){
    @B::specialsv_name = qw(
        Nullsv
        &PL_sv_undef
        &PL_sv_yes
        &PL_sv_no
        pWARN_ALL
        pWARN_NONE
        pWARN_STD
    );
}

sub object_2svref{
    my($obj) = @_;

    return $special_sv{ $$obj } || do{
        Carp::confess($obj->special_name, ' is not a normal SV object');
    };
}

sub setval{
    my($obj) = @_;

    Acme::Perl::VM::apvm_die('Modification of read-only value (%s) attempted', $obj->special_name);
}

sub STASH(){ undef }

sub POK(){ 0 }
sub ROK(){ 0 }

sub special_name{
    my($obj) = @_;
    return $B::specialsv_name[$$obj] || sprintf 'SPECIAL(0x%x)', $$obj;
}

package
    B::SV;

# for sv_setsv()
sub setsv{
    my($dst, $src) = @_;

    my $dst_ref = $dst->object_2svref;
    ${$dst_ref} = ${$src->object_2svref};
    bless $dst, ref(B::svref_2object( $dst_ref ));

    return $dst;
}

# for sv_setpv()/sv_setiv()/sv_setnv() etc.
sub setval{
    my($dst, $val) = @_;

    my $dst_ref = $dst->object_2svref;
    ${$dst_ref} = $val;
    bless $dst, ref(B::svref_2object( $dst_ref ));

    return $dst;
}

sub clear{
    my($sv) = @_;

    ${$sv->object_2svref} = undef;
    return;
}

sub toCV{
    my($sv) = @_;
    Carp::croak(sprintf 'Cannot convert %s to a CV', B::class($sv));
}

sub STASH(){ undef }

package
    B::PVMG;

sub ROK{
    my($obj) = @_;
    my $dummy = ${ $obj->object_2svref }; # invoke mg_get()
    return $obj->SUPER::ROK;
}

package
    B::CV;

sub toCV{ $_[0] }

sub clear{
    Carp::croak('Cannot clear a CV');
}

sub ROK(){ 0 }

package
    B::GV;


sub toCV{ $_[0]->CV }

sub clear{
    Carp::croak('Cannot clear a CV');
}

sub ROK(){ 0 }

package
    B::AV;

sub setsv{
    my($sv) = @_;
    Carp::croak('Cannot call setsv() for ' . B::class($sv));
}

sub clear{
    my($sv) = @_;



( run in 0.932 second using v1.01-cache-2.11-cpan-5b529ec07f3 )