B-C

 view release on metacpan or  search on metacpan

ramblings/blogs-debugging-article4.pod  view on Meta::CPAN

The compiler just walks the ops but does not store away the optree, so
we have no access to the previous op.

So we need to add
<pre>
  if ($op->name eq 'method_named') {
    my $cv = method_named($sv);
    $cv->save;
  }
</pre>

to the SVOP and PADOP save methods and add the helper function to get us the cv.

<pre>
sub method_named {
  my $sv = shift;
  my $name = $sv->PVX;
  # Note: the pkg PV is at PL_stack_base+TOPMARK+1,
  # the previous op->sv->PVX. We store it away in op->_save_common.
  my $stash = $package_pv ? $package_pv."::" : "main::";
  $name = $stash . $name;
  warn "save method_name \"$name\"\n" if $debug{cv};
  return svref_2object( \&{$name} );
}
</pre>

Fortunately we have a common method for all ops, where we can store
away the $package_pv for any upcoming method_named op.

<pre>
sub B::OP::_save_common {
  my $op = shift;
  if ($op->next 
      and $op->next->can('name')
      and $op->next->name eq 'method_named')
  {
    # need to store away the pkg pv
    $package_pv = $op->sv->PVX;
  }
 ...
</pre>

Test it:
<pre>
$ <strong>t/testc.sh 35</strong>
=> 
./ccode35
PASS => 'ok'
</pre>

We just fixed one of the oldest compiler bugs, the methodcall syntax: pkg->method.
It's not fixed for CC, because CC unrolls the runops loop and does not use B::OP::_save_common. In CC the most common ops have their own optimized method.

The testsuite
<b>make test</b> <em>(~2 min with the current perl)</em> and 
<b>perlall-maketest</b> <em>(~20 min for all installed perls)</em> and 
<b>perltestvm</b> <em>(~60min for all installed perls in all accessible platforms - freebsd, debian, centos, solaris, ...)</em>
confirms that.

Let's look what the biggest testsuite, cpantesters, says. 
make dist, upload to pause and wait for the smoke.



( run in 1.241 second using v1.01-cache-2.11-cpan-b16cb0d3907 )