NAME

Sub::Op - Install subroutines as opcodes.

VERSION

Version 0.01

SYNOPSIS

In your XS file :

#include "sub_op.h"

STATIC OP *scalar_util_reftype(pTHX) {
 dSP;
 dMARK;
 SV *sv = POPs;
 if (SvMAGICAL(sv))
  mg_get(sv);
 if (SvROK(sv))
  PUSHs(sv_reftype(SvRV(sv), 0));
 else
  PUSHs(&PL_sv_undef);
 RETURN;
}

MODULE = Scalar::Util::Ops       PACKAGE = Scalar::Util::Ops

BOOT:
{
 sub_op_config_t c;
 c.name  = "reftype";
 c.len   = sizeof("reftype")-1;
 c.pp    = scalar_util_reftype;
 c.check = 0;
 c.ud    = NULL;
 sub_op_register(aTHX_ &c);
}

In your Perl module file :

package Scalar::Util::Ops;

use strict;
use warnings;

our ($VERSION, @ISA);

use Sub::Op; # Before loading our own shared library

BEGIN {
 $VERSION = '0.01';
 require DynaLoader;
 push @ISA, 'DynaLoader';
 __PACKAGE__->bootstrap($VERSION);
}

sub import   { Sub::Op::enable(reftype => scalar caller) }

sub unimport { Sub::Op::disable(reftype => scalar caller) }

1;

In your Makefile.PL :

use ExtUtils::Depends;

my $ed = ExtUtils::Depends->new('Scalar::Util::Ops' => 'Sub::Op');

WriteMakefile(
 $ed->get_makefile_vars,
 ...
);

DESCRIPTION

This module provides a C and Perl API for replacing subroutine calls by custom opcodes. This has two main advantages :

  • it gets rid of the overhead of a normal subroutine call ;

  • there's no symbol table entry defined for the subroutine.

Subroutine calls with and without parenthesis are handled. Ampersand calls are not replaced, and as such will still allow to call a subroutine with same name defined earlier. This may or may not be considered as a bug, but it gives the same semantics as Perl keywords, so I believe it's reasonable.

When B and B::Deparse are loaded, they get automatically monkeypatched so that introspecting modules like B::Concise and B::Deparse still produce a valid output.

C API

sub_op_config_t

A typedef'd struct that configures how Sub::Op should handle a given subroutine name. It has the following members :

  • const char *name

    The name of the subroutine you want to replace. Allowed to be static.

  • STRLEN len

    name's length, in bytes.

  • Perl_ppaddr_t pp

    The pp function that will be called instead of the subroutine. Perl_ppaddr_t is a typedef'd function pointer defined by perl as :

    typedef OP *(*Perl_ppaddr_t)(pTHX);
  • sub_op_check_t check

    An optional callback that will be called each time a call to name is replaced. You can use it to attach extra info to those ops (e.g. with a pointer table) or to perform more optimizations to the optree. sub_op_check_t is a typedef'd function pointer defined by :

    typedef OP *(*sub_op_check_t)(pTHX_ OP *, void *);
  • void *ud

    An optional user data passed to the check callback.

void sub_op_register(pTHX_ const sub_op_config_t *c)

Registers a name and its configuration into Sub::Op. The caller is responsible for allocating and freeing the sub_op_config_t object. No pointer to it or to its members is kept.

PERL API

enable $name, [ $pkg ]

Enable the replacement with a custom opcode of calls to the $name subroutine of the $pkg package in the current lexical scope. A pp callback must have been registered for $name by calling the C function sub_op_register in the XS section of your module.

When $pkg is not set, it defaults to the caller package.

disable $name, [ $pkg ]

Disable the replacement for calls to $name in the package $pkg.

When $pkg is not set, it defaults to the caller package.

EXAMPLES

See the t/Sub-Op-LexicalSub directory that implements a complete example.

DEPENDENCIES

perl 5.10.

Variable::Magic, B::Hooks::EndOfScope.

ExtUtils::Depends.

SEE ALSO

subs::auto.

B::Hooks::OP::Check::EntersubForCV.

AUTHOR

Vincent Pit, <perl at profvince.com>, http://www.profvince.com.

You can contact me by mail or on irc.perl.org (vincent).

BUGS

Please report any bugs or feature requests to bug-sub-op at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Sub-Op. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Sub::Op

Tests code coverage report is available at http://www.profvince.com/perl/cover/Sub-Op.

COPYRIGHT & LICENSE

Copyright 2010 Vincent Pit, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.