Acme-Perl-VM
view release on metacpan or search on metacpan
lib/Acme/Perl/VM.pm view on Meta::CPAN
);
return;
}
sub SAVECLEARSV{
my($sv) = @_;
push @PL_savestack, Acme::Perl::VM::Scope::Clearsv->new(
sv => $sv,
);
return;
}
sub SAVEPADSV{
my($off) = @_;
push @PL_savestack, Acme::Perl::VM::Scope::Padsv->new(
off => $off,
value => ${$PL_curpad[$off]->object_2svref},
comppad => $PL_comppad,
);
return;
}
sub save_scalar{
my($gv) = @_;
push @PL_savestack, Acme::Perl::VM::Scope::Scalar->new(gv => $gv);
return $PL_savestack[-1]->sv;
}
sub save_ary{
my($gv) = @_;
push @PL_savestack, Acme::Perl::VM::Scope::Array->new(gv => $gv);
return $PL_savestack[-1]->sv;
}
sub save_hash{
my($gv) = @_;
push @PL_savestack, Acme::Perl::VM::Scope::Hash->new(gv => $gv);
return $PL_savestack[-1]->sv;
}
sub PAD_SET_CUR_NOSAVE{
my($padlist, $nth) = @_;
$PL_comppad_name = $padlist->ARRAYelt(0);
$PL_comppad = $padlist->ARRAYelt($nth);
@PL_curpad = ($PL_comppad->ARRAY);
return;
}
sub PAD_SET_CUR{
my($padlist, $nth) = @_;
SAVECOMPPAD();
PAD_SET_CUR_NOSAVE($padlist, $nth);
return;
}
sub PAD_SV{
#my($targ) = @_;
return $PL_curpad[ $_[0] ];
}
sub dopoptosub{
my($startingblock) = @_;
for(my $i = $startingblock; $i >= 0; $i--){
my $type = $PL_cxstack[$i]->type;
if($type eq 'EVAL' or $type eq 'SUB'){
return $i;
}
}
return -1;
}
my %loop;
@loop{qw(SUBST SUB EVAL NULL)} = ();
$loop{LOOP} = TRUE;
sub dopoptoloop{
my($startingblock) = @_;
for(my $i = $startingblock; $i >= 0; --$i){
my $cx = $PL_cxstack[$i];
my $type = $cx->type;
if(exists $loop{$type}){
if(!$loop{$type}){
apvm_warn 'Exsiting %s via %s', $type, $PL_op->name;
$i = -1 if $type eq 'NULL';
}
return $i;
}
}
return -1;
}
sub dopoptolabel{
my($label) = @_;
for(my $i = $#PL_cxstack; $i >= 0; --$i){
my $cx = $PL_cxstack[$i];
my $type = $cx->type;
if(exists $loop{$type}){
if(!$loop{$type}){
apvm_warn 'Exsiting %s via %s', $type, $PL_op->name;
return $type eq 'NULL' ? -1 : $i;
}
elsif($cx->label && $cx->label eq $label){
return $i;
}
}
}
return -1;
}
sub OP_GIMME{ # op.h
my($op, $default) = @_;
my $op_gimme = $op->flags & OPf_WANT;
return $op_gimme == OPf_WANT_VOID ? G_VOID
: $op_gimme == OPf_WANT_SCALAR ? G_SCALAR
: $op_gimme == OPf_WANT_LIST ? G_ARRAY
: $default;
}
sub OP_GIMME_REVERSE{ # op.h
my($flags) = @_;
$flags &= G_WANT;
return $flags == G_VOID ? OPf_WANT_VOID
: $flags == G_SCALAR ? OPf_WANT_SCALAR
: OPf_WANT_LIST;
}
sub gimme2want{
my($gimme) = @_;
$gimme &= G_WANT;
return $gimme == G_VOID ? undef
: $gimme == G_SCALAR ? 0
: 1;
}
sub want2gimme{
my($wantarray) = @_;
lib/Acme/Perl/VM.pm view on Meta::CPAN
1;
__END__
=head1 NAME
Acme::Perl::VM - A Perl5 Virtual Machine in Pure Perl (APVM)
=head1 VERSION
This document describes Acme::Perl::VM version 0.006.
=head1 SYNOPSIS
use Acme::Perl::VM;
run_block{
print "Hello, APVM world!\n",
};
=head1 DESCRIPTION
C<Acme::Perl::VM> is an implementation of Perl5 virtual machine in pure Perl.
Perl provides a feature to access compiled syntax trees (B<opcodes>) by
C<B> module. C<B::*> modules walk into opcodes and do various things;
C<B::Deparse> retrieves Perl source code from subroutine references,
C<B::Concise> reports formatted syntax trees, and so on.
This module also walks into the opcodes, and executes them with its
own B<ppcodes>.
You can run any Perl code:
use Acme::Perl::VM;
run_block {
print "Hello, APVM world!\n";
};
This code says B<Hello, APVM world> to C<stdout> as you expect.
Here is a more interesting example:
BEGIN{ $ENV{APVM} = 'trace' }
use Acme::Perl::VM;
run_block {
print "Hello, APVM world!\n";
};
And you'll get a list of opcodes as the code runs:
.entersub(&__ANON__) VOID
.nextstate(main -:4) VOID
.pushmark SCALAR
.const("Hello, APVM world!\n") SCALAR
.print SCALAR KIDS
Hello, APVM world!
.leavesub KIDS
The first C<entersub> is the start of the block. The next C<nextstate>
indicates the statement that says hello. C<pushmark>, C<const>, and
C<print> are opcodes which runs on the statement. The last C<leavesub> is
the end of the block. This is a future of the module.
In short, the module has no purpose :)
=head1 DEPENDENCIES
Perl 5.8.1 or later.
=head1 BUGS
No bugs have been reported.
Please report any bugs or feature requests to the author.
=head1 AUTHOR
Goro Fuji (gfx) E<lt>gfuji(at)cpan.orgE<gt>.
=head1 SEE ALSO
L<perlapi>.
L<perlhack>.
F<pp.h> for PUSH/POP macros.
F<pp.c>, F<pp_ctl.c>, and F<pp_hot.c> for ppcodes.
F<op.h> for opcodes.
F<cop.h> for COP and context blocks.
F<scope.h> and F<scope.c> for scope stacks.
F<pad.h> and F<pad.c> for pad variables.
F<run.c> for runops.
L<B>.
L<B::Concise>.
L<Devel::Optrace>.
=head1 LICENSE AND COPYRIGHT
Copyright (c) 2009, Goro Fuji (gfx). Some rights reserved.
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
( run in 1.963 second using v1.01-cache-2.11-cpan-140bd7fdf52 )