NAME

Devel::Chitin::OpTree - OpTree deparsing for Devel::Chitin

SYNOPSIS

  my $optree = Devel::Chitin::OpTree->build_from_location($subref);
  # or
  $optree = Devel::Chitin::OpTree->build_from_location($location_obj);

  $optree->walk_inorder(sub {
      my $op = shift;
      my $b_op = $op->op;
      printf("OP named %s has %d children\n",
              $b_op->name, scalar(@{ $op->children }));
      printf("  parent %s, sibling %s, next %s\n",
              $op->parent->op->name,
              $op->sibling->op->name,
              $op->next->op->name);
  });

  print $optree->deparse;

DESCRIPTION

This class is a wrapper around the B::OP-related classes to make navigating around the optree and deparsing easier. It differs from B::Deparse in that Devel::Chitin::OpTree is meant to be used at run-time and it supports deparsing from any point in the tree, not just at function entry points.

This module contains a mixture of methods responsible for construction, helpers used by the other OpTree-related classes, and deparsing methods for nullary OPs.

Constructor

Constructing an OpTree for a subroutine is done via build_from_location()

  my $optree = Devel::Chitin::OpTree->build_from_location($subref);
  $optree    = Devel::Chitin::OpTree->build_from_location($location_obj);

You can pass in either a subref or a Devel::Chitin::Location object. In the latter case, it uses the object's package and subroutine values to find the sub. Note that locations within anonymous subs aren't supported yet.

The returned OpTree object is the root of the optree. Each element of the tree is itself a Devel::Chitin::OpTree instance. You can explore the tree with the methods below.

OpTrees are cached, so that if build_from_location() is called twice for the same subroutine, the same OpTree object will be returned.

Methods

op

Returns the B::OP-related object wrapped by the invocant

op_name

Returns the original OP name, even if the OP has been optimized away, and without any preceding 'pp_'. For example, the OP named 'pp_exists' will return 'exists', and an optimized away pp_padsv will still return 'padsv' even though it's OP is a pp_null. To get the real OP name without this munging, use $op-op->name>.

parent

Returns a Devel::Chitin::OpTree instance for the parent node of the invocant

next

Returns a Devel::Chitin::OpTree instance for the invocant's OP's next pointer

sibling

Returns a Devel::Chitin::OpTree instance for the invocant's OP's sibling pointer

children

Returns a listref of Devel::Chitin::OpTree objects representing the children of the invocant

cv

Returns a B::CV|B/B::CV-Methods object for the subroutine the invocant is a part of

root_op

Returns a Devel::Chitin::OpTree instance representing the entrypoint for the subroutine the invocant is a part of

walk_inorder
  $op->walk_inorder($cb);

Perform an in-order walk of the optree and call the given callback function (a coderef) for each node in the tree. The callback is passed a Devel::Chitin::OpTree object as its only argument.

walk_preorder
  $op->walk_preorder($cb);

Perform a pre-order (children before parent) walk of the optree and call the given callback function (a coderef) for each node in the tree. The callback is passed a Devel::Chitin::OpTree object as its only argument.

deparse

Returns a string containing Perl code by essentially doing an in-order walk of the tree, turning each op into the Perl code it represents.

pp_*

These functions a responsible for the deparsing process. They contain whatever logic is necessary to turn the node and its children into Perl.

SEE ALSO

Devel::Chitin, Devel::Chitin::Location, B, B::Deparse, B::DeparseTree

AUTHOR

Anthony Brummett <brummett@cpan.org>

COPYRIGHT

Copyright 2017, Anthony Brummett. This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.