10 Sub::Op - Install subroutines as opcodes.
20 sub dl_load_flags { 0x01 }
25 push @ISA, 'DynaLoader';
26 __PACKAGE__->bootstrap($VERSION);
35 STATIC OP *scalar_util_reftype(pTHX) {
42 PUSHs(sv_reftype(SvRV(sv), 0));
48 MODULE = Scalar::Util::Ops PACKAGE = Scalar::Util::Ops
55 c.namelen = sizeof("reftype")-1;
56 c.pp = scalar_util_reftype;
59 sub_op_register(aTHX_ &c, 0);
62 In your Perl module file :
64 package Scalar::Util::Ops;
71 use Sub::Op; # Before loading our own shared library
76 push @ISA, 'DynaLoader';
77 __PACKAGE__->bootstrap($VERSION);
80 sub import { Sub::Op::enable(reftype => scalar caller) }
82 sub unimport { Sub::Op::disable(reftype => scalar caller) }
86 In your F<Makefile.PL> :
88 use ExtUtils::Depends;
90 my $ed = ExtUtils::Depends->new('Scalar::Util::Ops' => 'Sub::Op');
93 $ed->get_makefile_vars,
99 This module provides a C and Perl API for replacing subroutine calls by custom opcodes.
100 This has two main advantages :
106 it gets rid of the overhead of a normal subroutine call ;
110 there's no symbol table entry defined for the subroutine.
114 Subroutine calls with and without parenthesis are handled.
115 Ampersand calls are B<not> replaced, and as such will still allow to call a subroutine with same name defined earlier.
116 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.
118 When L<B> and L<B::Deparse> are loaded, they get automatically monkeypatched so that introspecting modules like L<B::Concise> and L<B::Deparse> still produce a valid output.
124 use B::Hooks::EndOfScope;
125 use Variable::Magic 0.08;
129 $placeholder = sub { require Carp; Carp::croak('PLACEHOLDER') };
130 _placeholder($placeholder);
133 my $sw = Variable::Magic::wizard(
134 data => sub { +{ guard => 0, pkg => $_[1], map => $_[2] } },
136 my ($var, $data, $name) = @_;
138 return if $data->{guard};
139 local $data->{guard} = 1;
141 return unless $data->{map}->{$name};
143 my $pkg = $data->{pkg};
144 my $fqn = join '::', $pkg, $name;
147 local $SIG{__WARN__} = sub {
148 CORE::warn(@_) unless $_[0] =~ /^Constant subroutine.*redefined/;
149 } if _constant_sub(do { no strict 'refs'; \&$fqn });
151 no warnings 'redefine';
152 *$fqn = $placeholder;
160 my ($pkg, $name) = @_;
162 my $fqn = join '::', $pkg, $name;
165 old => _defined_sub($fqn) ? \&$fqn : undef,
166 proto => prototype($fqn),
175 Variable::Magic::getdata(%{"${pkg}::"}, $sw);
178 defined $data ? $data->{map} : undef;
182 my ($pkg, $name) = @_;
184 my $map = { $name => _tag(@_) };
188 Variable::Magic::cast(%{"${pkg}::"}, $sw, $pkg, $map);
198 Variable::Magic::dispell(%{"${pkg}::"}, $sw);
203 =head2 C<sub_op_config_t>
205 A typedef'd struct that configures how L<Sub::Op> should handle a given subroutine name.
206 It has the following members :
214 The name of the subroutine you want to replace.
215 Allowed to be static.
221 C<name>'s length, in bytes.
227 The pp function that will be called instead of the subroutine.
228 C<Perl_ppaddr_t> is a typedef'd function pointer defined by perl as :
230 typedef OP *(*Perl_ppaddr_t)(pTHX);
234 C<sub_op_check_t check>
236 An optional callback that will be called each time a call to C<name> is replaced.
237 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.
238 C<sub_op_check_t> is a typedef'd function pointer defined by :
240 typedef OP *(*sub_op_check_t)(pTHX_ OP *, void *);
246 An optional user data passed to the C<check> callback.
250 =head2 C<void sub_op_init(sub_op_config_t *c)>
252 Initializes the fields of the C<sub_op_config_t> object.
253 For future compatibility, it is required to call this function with your config object before storing your actual values.
254 It will store safe defaults for members you won't set.
256 =head2 C<void sub_op_register(pTHX_ const sub_op_config_t *c, U32 flags)>
258 Registers a name and its configuration into L<Sub::Op>.
259 The caller is responsible for allocating and freeing the C<sub_op_config_t> object.
260 No pointer to it or to its members is kept, except if you pass the flag C<SUB_OP_REGISTER_STEAL> in which case the configuration object will be stolen to be stored into L<Sub::Op>'s internal datastructure.
262 =head2 C<sub_op_config_t *sub_op_dup(pTHX_ const sub_op_config_t *orig)>
264 Deeply clones the specified C<sub_op_config_t> object.
266 =head2 C<void sub_op_free(pTHX_ sub_op_config_t *c)>
268 Free the memory associated with the specified C<sub_op_config_t> object.
272 =head2 C<enable $name, [ $pkg ]>
274 Enable the replacement with a custom opcode of calls to the C<$name> subroutine of the C<$pkg> package in the current lexical scope.
275 A pp callback must have been registered for C<$name> by calling the C function C<sub_op_register> in the XS section of your module.
277 When C<$pkg> is not set, it defaults to the caller package.
284 my $pkg = @_ > 0 ? $_[0] : caller;
285 my $map = _map($pkg);
288 $map->{$name} = _tag($pkg, $name);
290 $map = _cast($pkg, $name);
293 my $proto = $map->{$name}->{proto};
294 if (defined $proto) {
296 Scalar::Util::set_prototype(\&{"${pkg}::$name"}, undef);
300 $^H{+(__PACKAGE__)} = 1;
302 on_scope_end { disable($name, $pkg) };
307 =head2 C<disable $name, [ $pkg ]>
309 Disable the replacement for calls to C<$name> in the package C<$pkg>.
311 When C<$pkg> is not set, it defaults to the caller package.
318 my $pkg = @_ > 0 ? $_[0] : caller;
319 my $map = _map($pkg);
321 my $fqn = join '::', $pkg, $name;
324 my $tag = $map->{$name};
326 my $old = $tag->{old};
329 no warnings 'redefine';
333 my $proto = $tag->{proto};
334 if (defined $proto) {
336 Scalar::Util::set_prototype(\&$fqn, $proto);
339 delete $map->{$name};
340 unless (keys %$map) {
349 my ($pkg, $inject) = @_;
351 my $stash = do { no strict 'refs'; \%{"${pkg}::"} };
353 while (my ($meth, $code) = each %$inject) {
354 next if exists $stash->{$meth} and (*{$stash->{$meth}}{CODE} // 0) == $code;
356 *{"${pkg}::$meth"} = $code;
362 my @parts = split /::/, $fqn;
363 my $name = pop @parts;
367 return 0 unless do { no strict 'refs'; %$pkg };
369 return do { no strict 'refs'; defined &{"$pkg$name"} };
375 $injector = Variable::Magic::wizard(
376 data => sub { +{ guard => 0, pkg => $_[1], subs => $_[2] } },
378 my ($stash, $data, $key) = @_;
380 return if $data->{guard};
381 local $data->{guard} = 1;
383 _inject($data->{pkg}, $data->{subs});
393 $B_OP_inject{first} = sub {
394 if (defined _custom_name($_[0])) {
395 $_[0] = bless $_[0], 'B::UNOP' unless $_[0]->isa('B::UNOP');
396 goto $_[0]->can('first') || die 'oops';
399 Carp::confess('Calling B::OP->first for something that isn\'t a custom op');
402 $B_OP_inject{can} = sub {
403 my ($obj, $meth) = @_;
404 if ($meth eq 'first') {
405 return undef unless $obj->isa('B::UNOP') or defined _custom_name($obj);
407 $obj->SUPER::can($meth);
410 if (_defined_sub('B::OP::type')) {
411 _inject('B::OP', \%B_OP_inject);
414 Variable::Magic::cast %{'B::OP::'}, $injector, 'B::OP', \%B_OP_inject;
417 my $B_Deparse_inject = {
419 my ($self, $op, $cx) = @_;
420 my $name = _custom_name($op);
421 die 'unhandled custom op' unless defined $name;
422 if ($op->flags & do { no strict 'refs'; &{'B::OPf_STACKED'}() }) {
423 my $kid = $op->first;
424 $kid = $kid->first->sibling; # skip ex-list, pushmark
426 while (not do { no strict 'refs'; &{'B::Deparse::null'}($kid) }) {
427 push @exprs, $self->deparse($kid, 6);
428 $kid = $kid->sibling;
430 my $args = join(", ", @exprs);
431 return "$name($args)";
438 if (_defined_sub('B::Deparse::pp_entersub')) {
439 _inject('B::Deparse', $B_Deparse_inject);
442 Variable::Magic::cast %{'B::Deparse::'}, $injector, 'B::Deparse', $B_Deparse_inject;
447 BEGIN { _monkeypatch() }
451 See the F<t/Sub-Op-LexicalSub> directory that implements a complete example.
455 Preexistent definitions of a sub whose name is handled by L<Sub::Op> are restored at the end of the lexical scope in which the module is used.
456 But if you define a sub in the scope of action of L<Sub::Op> with a name that is currently being replaced, the new declaration will be obliterated at the scope end.
458 Function calls without parenthesis inside an C<eval STRING> in the scope of the pragma won't be replaced.
459 I know a few ways of fixing this, but I've not yet decided on which.
465 L<Variable::Magic>, L<B::Hooks::EndOfScope>.
467 L<ExtUtils::Depends>.
473 L<B::Hooks::XSUB::CallAsOp> provides a C API to declare XSUBs that effectively call a specific PP function.
474 Thus, it allows you to write XSUBs with the PP stack conventions used for implementing perl core keywords.
475 There's no opcode replacement and no parsing hacks.
477 L<B::Hooks::OP::Check::EntersubForCV>.
481 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
483 You can contact me by mail or on C<irc.perl.org> (vincent).
487 Please report any bugs or feature requests to C<bug-sub-op at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Sub-Op>.
488 I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
492 You can find documentation for this module with the perldoc command.
496 Tests code coverage report is available at L<http://www.profvince.com/perl/cover/Sub-Op>.
498 =head1 COPYRIGHT & LICENSE
500 Copyright 2010 Vincent Pit, all rights reserved.
502 This program is free software; you can redistribute it and/or modify it
503 under the same terms as Perl itself.