develooper Front page | perl.perl5.porters | Postings from August 2009

Accuracy of B::Deparse (was Re: maint-5.10 snapshot (aka "RC0"))

Thread Previous | Thread Next
Paul Johnson
August 8, 2009 12:44
Accuracy of B::Deparse (was Re: maint-5.10 snapshot (aka "RC0"))
Message ID:
On Wed, Jul 08, 2009 at 10:03:38AM +0200, Vincent Pit wrote:
> > Maybe this optimisation :
> >
> > [rafael@scipion ~]$ perl5.10.0 -MO=Deparse -e 'if(not $a or not $b){}'
> > if (not $a or not $b) {
> >     ();
> > }
> > -e syntax OK
> > [rafael@scipion ~]$ bleadperl -MO=Deparse -e 'if(not $a or not $b){}'
> > unless ($a and $b) {
> >     ();
> > }
> > -e syntax OK
> >
> > Which seems to come from :
> >
> > commit edbe35ea95baf286c38bf4d7db7d18b82ecce254
> > Author: Vincent Pit <>
> > Date:   Sat Aug 30 00:47:28 2008 +0200
> >
> >     Re: unless(...) terser than if(!...)
> >     Message-ID: <>
> >
> >     p4raw-id: //depot/perl@34310
> >
> > Not sure Deparse will be able to cope with this.
> This is highly possible.
> If by cope you mean "being able to recreeate the precise original
> code", then I don't think so either.

Here's a start at the impossible:

--- lib/B/        2009-08-07 20:30:49.000000000 +0200
+++ lib/B/    2009-08-08 20:16:08.000000000 +0200
@@ -2231,6 +2231,8 @@
        return "$blockname ($left) {\n\t$right\n\b}\cK";
     } elsif ($cx < 1 and $blockname and not $self->{'parens'}
             and $self->{'expand'} < 7) { # $b if $a
+       $blockname = ($blockname eq "if" ? "unless" : "if") . " not"
+           if $left->name eq "null" and B::ppname($left->targ) eq "pp_not";
        $right = $self->deparse($right, 1);
        $left = $self->deparse($left, 1);
        return "$right $blockname $left";

Before the patch:

$ ./perl -MO=Deparse -e 'die if not $a'
die unless $a;
-e syntax OK

After the patch:

$ ./perl -Ilib -MO=Deparse -e 'die if not $a'
die if not $a;
-e syntax OK

This is by no means a complete solution.  In fact I'm not even convinced
that a full solution is possible.  But it is heading in the direction of
an improvement and, as such, it may merit further investigation.  There
are at least the following problems:

 1. You can't just stick a "not" in there and expect it to work.  You
    probably have to de De Morgan (to Morgan?) the condition.

 2. "not" and ! are different.

 3. Something similar needs to be done for "if (not $a) { die }"

This is probably a reasonably simple task for someone familiar with the
optree, but it might also be a nice introduction for someone who would
like to become more familiar with it.  No C is required.  Any

>                                      But it also can't tell the
> difference between "1 if $x" and "$x and 1", or recover optimized out
> sections, so that shouldn't be a blocker.

My opinion is that it is nice if Deparse can get as close as possible to
to the original code but if it can't tell that certain optimisations
have been made then it's not the end of the world.  I expect (and hope
for) this to happen more and more as we are able to optimise the optree,
possibly with the optimisations being controlled by a switch, if they
are expensive.

Having said that, it would be nice if there were a way to be able to
faithfully recreate the original source code.  This could be of great
benefit to source code analysis tools.  What options do we have?

 1. B::Deparse
    - not always accurate

 2. Go through the debugger
    - line based
    - slow

 3. MAD
    - no one has this compiled in

 4. Use the cop line and file data to go back to the original file
    - line based
    - file may not be there
    - if it is, it might be hard to find (file is relative to the cwd
      when it was opened)
    - only available for cops

 5. Anything else?

What have I missed?  Is this important?  Is effort better directed
somewhere else?  Do we have a champion?

I'm CCing Gerard Goossen since I wonder whether his proposal "Changing
the Perl 5 optree build process into a Abstract Syntax Tree generation
and a code generation step" might be able to provide any benefits in
this area.  Or perhaps it might make things more difficult?

Paul Johnson -

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About