Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: Consistency, syntax, and runtime optree mangling

by diotalevi (Canon)
on Oct 03, 2002 at 12:59 UTC ( [id://202497]=note: print w/replies, xml ) Need Help??


in reply to Consistency, syntax, and little minds

This is my first crack at hacking the opcode tree at compile time but the general idea is to dereference any array references given to push() as the first argument. This doesn't address forms like push(.., ..), push(\@a, ..) or really anything beyond retrieving the array reference from a global or lexical value. I was following the lead from the perl.com article http://www.perl.com/pub/a/2002/05/07/optree.html. Right now the code just exits and I'm sure that I'm doing things incorrectly (I just picked '0' as an arbitrary value for the new rv2av opcode) but don't have the expertise to get further. I'm sharing the code so you can at least see that in perl 5.8 you can have whatever you want as long as you're willing to get your hands dirty.

#!/usr/local/bin/perl CHECK { require B::Generate; use B::Utils qw(opgrep walkallops_filtered); walkallops_filtered ( sub { opgrep( { name => 'push', first => { sibling => { name => [ 'padsv', 'g +vsv' ] } } }, $_[0] ) }, sub { my $kid0 = $_[0]->first; my $ref = $kid0->sibling; my $val = $ref->sibling; my $rv2av = B::UNOP->new( 'rv2av', 0, $ref ); $kid0->sibling( $rv2av ); $rv2av->sibling( $val ); $ref->sibling( undef ); $rv2av->first( $ref ); $kid0->next( $ref ); $ref->next( $rv2av ); $rv2av->next( $val ); } ); } my @a = 1; my $a = \@a; push @{$a}, 2; push $a, 4; # alter this to do @$a print join(', ',@a) . "\n";

No modifications: This is the original opcode tree that is generated with no modifications

$ /usr/local/bin/perl -MO=Concise over.pl
Type of arg 1 to push must be array (not private variable) at over.pl line 31, near "4;"
over.pl had compilation errors.
1aq <@> leave@a:128,131 KP/REFC ->(end)
19s    <0> enter ->19t
19t    <;> nextstate(main 128 over.pl:28) ->19u
19y    <2> aassignt2 KS ->19z
-        <1> ex-list lK ->19w
19u          <0> pushmark s ->19v
19v          <$> const(IV 1)t10 s ->19w
-        <1> ex-list lK ->19y
19w          <0> pushmark s ->19x
19x          <0> padav@a:128,131 lRM*/LVINTRO ->19y
19z    <;> nextstate(main 129 over.pl:29) ->1a0
1a4    <2> sassign sKS/2 ->1a5
1a2       <1> refgen sK/1 ->1a3
-           <1> ex-list lKRM ->1a2
1a0             <0> pushmark sRM ->1a1
1a1             <0> padav@a:128,131 lRM ->1a2
1a3       <0> padsv$a:129,131 sRM*/LVINTRO ->1a4
1a5    <;> nextstate(main 131 over.pl:30) ->1a6

----> this is the push @$a, 2 line
1aa    <@> pusht5 sK/2 ->1ab
1a6       <0> pushmark s ->1a7
1a8       <1> rv2avt4 lKRM/1 ->1a9
-           <@> scope sK ->1a8
-              <0> ex-nextstate v ->1a7
1a7             <0> padsv$a:129,131 sM/32 ->1a8
1a9       <$> const(IV 2)t11 s ->1aa


1ab    <;> nextstate(main 131 over.pl:31) ->1ac


----> this is the push $a, 2 line. Here you see
the raw lexical being passed to push().
1af    <@> pusht6 K/2 ->1ag
1ac       <0> pushmark s ->1ad
1ad       <0> padsv$a:129,131 ->1ae
1ae       <$> const(IV 4)t12 s ->1af


1ag    <;> nextstate(main 131 over.pl:32) ->1ah
1ap    <@> print K ->1aq
1ah       <0> pushmark ->1ai
1ao       <2> concatt9 K/2 ->1ap
1al          <@> joint7 K/2 ->1am
1ai             <0> pushmark ->1aj
1aj             <$> const(PV ", ")t13 ->1ak
1ak             <0> padav@a:128,131 ->1al
1an          <@> stringifyt8 K/1 ->1ao
-              <0> ex-pushmark ->1am
1am             <$> const(PV "\n")t14 ->1an

Modified opcode tree: Here I've attempted to instert a rv2av and thread execution through it. I'm not sure why that rv2av is now the end point but that's my own ignorance peeking.

$ /usr/local/bin/perl -MO=Concise over.pl
Type of arg 1 to push must be array (not private variable) at over.pl line 30, near "4;"
over.pl had compilation errors.
1an <@> leave@a:128,131 KP/REFC ->(end)
19p    <0> enter ->19q
19q    <;> nextstate(main 128 over.pl:27) ->19r
19v    <2> aassignt2 KS ->19w
-        <1> ex-list lK ->19t
19r          <0> pushmark s ->19s
19s          <$> const(IV 1)t10 s ->19t
-        <1> ex-list lK ->19v
19t          <0> pushmark s ->19u
19u          <0> padav@a:128,131 lRM*/LVINTRO ->19v
19w    <;> nextstate(main 129 over.pl:28) ->19x
1a1    <2> sassign sKS/2 ->1a2
19z       <1> refgen sK/1 ->1a0
-           <1> ex-list lKRM ->19z
19x             <0> pushmark sRM ->19y
19y             <0> padav@a:128,131 lRM ->19z
1a0       <0> padsv$a:129,131 sRM*/LVINTRO ->1a1
1a2    <;> nextstate(main 131 over.pl:29) ->1a3


----> Again, this is the push @$a, 2 line.
1a7    <@> pusht5 sK/2 ->1a8
1a3       <0> pushmark s ->1a4
1a5       <1> rv2avt4 lKRM/1 ->1a6
-           <@> scope sK ->1a5
-              <0> ex-nextstate v ->1a4
1a4             <0> padsv$a:129,131 sM/32 ->1a5
1a6       <$> const(IV 2)t11 s ->1a7


1a8    <;> nextstate(main 131 over.pl:30) ->1a9

-----> and this is what that CHECK{} block was tying up in knots.
1ac    <@> pusht6 K/2 ->1ad
1a9       <0> pushmark s ->1aa
-        <1> rv2avt15 K/1 ->1ab
1aa          <0> padsv$a:129,131 ->-
1ab       <$> const(IV 4)t12 s ->1ac


1ad    <;> nextstate(main 131 over.pl:31) ->1ae
1am    <@> print K ->1an
1ae       <0> pushmark ->1af
1al       <2> concatt9 K/2 ->1am
1ai          <@> joint7 K/2 ->1aj
1af             <0> pushmark ->1ag
1ag             <$> const(PV ", ")t13 ->1ah
1ah             <0> padav@a:128,131 ->1ai
1ak          <@> stringifyt8 K/1 ->1al
-              <0> ex-pushmark ->1aj
1aj             <$> const(PV "\n")t14 ->1ak
$

__SIG__
printf "You are here %08x\n", unpack "L!", unpack "P4", pack "L!", B::svref_2object(sub{})->OUTSIDE

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://202497]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (3)
As of 2024-04-26 07:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found