Acme-Perl-VM

 view release on metacpan or  search on metacpan

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

extends 'Acme::Perl::VM::Scope';

use Acme::Perl::VM qw(APVM_SCOPE deb @PL_cxstack ddx);

has value => (
    is  => 'ro',
);
has comppad => (
    is  => 'ro',
    isa => 'B::AV',
);
has off => (
    is  => 'ro',
    isa => 'Int',
);

sub leave{
    my($self) = @_;

    my $comppad_ref = $self->comppad->object_2svref;

    if(APVM_SCOPE){
        my $old = ddx([${ $self->comppad->ARRAYelt($self->off)->object_2svref }]);
        my $new = ddx([$self->value]);
        $old->Indent(0);
        $new->Indent(0);
        deb "%s" . "padsv (%s -> %s) saved at %s\n", (q{>} x (@PL_cxstack+1)),
            $old->Dump, $new->Dump, $self->saved_at;
    }

    #delete $comppad_ref->[$self->off];
    $comppad_ref->[$self->off] = $self->value;

    return;
}

no Mouse;
__PACKAGE__->meta->make_immutable();

package Acme::Perl::VM::Scope::Localizer; # ABSTRACT
use Mouse;
extends 'Acme::Perl::VM::Scope';

has gv => (
    is  => 'ro',
    isa => 'B::GV',
);

has old_ref => (
    is   => 'rw',
    isa => 'Ref',
);

sub save_type;
sub create_ref;
sub sv;

sub BUILD{
    my($self) = @_;

    my $glob_ref = $self->gv->object_2svref;

    $self->old_ref( *{$glob_ref}{ $self->save_type } );
    *{$glob_ref} = $self->create_ref();

    return;
}

sub leave{
    my($self) = @_;

    *{$self->gv->object_2svref} = $self->old_ref;
    return;
}

no Mouse;
__PACKAGE__->meta->make_immutable();

package Acme::Perl::VM::Scope::Scalar;
use Mouse;
extends 'Acme::Perl::VM::Scope::Localizer';

sub _save{
    my($self) = @_;
    return Acme::Perl::VM::gv_fullname($self->gv, '$');
}

sub save_type(){ 'SCALAR' }
sub create_ref{
    my($self) = @_;

    if($self->gv->SV->MAGICAL){
        bless $self, 'Acme::Perl::VM::Scope::Scalar::Magical';
        $self->old_value(${$self->old_ref});
        return \local(${*{ $self->gv->object_2svref }}); # to copy MAGIC
    }
    else{
        return \my $scalar;
    }
}
sub sv{
    my($self) = @_;
    return $self->gv->SV;
}

no Mouse;
__PACKAGE__->meta->make_immutable();

package Acme::Perl::VM::Scope::Scalar::Magical;
use Mouse;
extends 'Acme::Perl::VM::Scope::Scalar';

has old_value => (
    is => 'rw',
);

sub leave{
    my($self) = @_;
    $self->SUPER::leave();
    
    ${$self->old_ref} = $self->old_value;
    return;
}



( run in 0.440 second using v1.01-cache-2.11-cpan-ceb78f64989 )