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;
57 c.protolen = sizeof("$")-1;
58 c.pp = scalar_util_reftype;
61 sub_op_register(aTHX_ &c, 0);
64 In your Perl module file :
66 package Scalar::Util::Ops;
73 use Sub::Op; # Before loading our own shared library
78 push @ISA, 'DynaLoader';
79 __PACKAGE__->bootstrap($VERSION);
82 sub import { Sub::Op::enable(reftype => scalar caller) }
84 sub unimport { Sub::Op::disable(reftype => scalar caller) }
88 In your F<Makefile.PL> :
90 use ExtUtils::Depends;
92 my $ed = ExtUtils::Depends->new('Scalar::Util::Ops' => 'Sub::Op');
95 $ed->get_makefile_vars,
101 This module provides a C and Perl API for replacing subroutine calls by custom opcodes.
102 This has two main advantages :
108 it gets rid of the overhead of a normal subroutine call ;
112 there's no symbol table entry defined for the subroutine.
116 Subroutine calls with and without parenthesis are handled.
117 Ampersand calls are B<not> replaced, and as such will still allow to call a subroutine with same name defined earlier.
118 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.
120 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.
126 use B::Hooks::EndOfScope;
127 use Variable::Magic 0.08;
131 $placeholder = sub { require Carp; Carp::croak('PLACEHOLDER') };
132 _placeholder($placeholder);
135 my $sw = Variable::Magic::wizard(
136 data => sub { +{ guard => 0, pkg => $_[1], map => $_[2] } },
138 my ($var, $data, $name) = @_;
140 return if $data->{guard};
141 local $data->{guard} = 1;
143 return unless $data->{map}->{$name};
145 my $pkg = $data->{pkg};
146 my $fqn = join '::', $pkg, $name;
149 local $SIG{__WARN__} = sub {
150 CORE::warn(@_) unless $_[0] =~ /^Constant subroutine.*redefined/;
151 } if _constant_sub(do { no strict 'refs'; \&$fqn });
153 no warnings qw/prototype redefine/;
154 *$fqn = $placeholder;
158 my $proto = _get_prototype($name);
160 Scalar::Util::set_prototype(\&$fqn, $proto);
169 my @parts = split /::/, $fqn;
170 my $name = pop @parts;
174 return 0 unless do { no strict 'refs'; %$pkg };
176 return do { no strict 'refs'; defined &{"$pkg$name"} };
180 my ($pkg, $name) = @_;
182 my $fqn = join '::', $pkg, $name;
185 old => _defined_sub($fqn) ? \&$fqn : undef,
186 proto => prototype($fqn),
195 Variable::Magic::getdata(%{"${pkg}::"}, $sw);
198 defined $data ? $data->{map} : undef;
202 my ($pkg, $name) = @_;
204 my $map = { $name => _tag(@_) };
208 Variable::Magic::cast(%{"${pkg}::"}, $sw, $pkg, $map);
218 Variable::Magic::dispell(%{"${pkg}::"}, $sw);
223 =head2 C<sub_op_config_t>
225 A typedef'd struct that configures how L<Sub::Op> should handle a given subroutine name.
226 It has the following members :
234 The name of the subroutine you want to replace.
235 Allowed to be static.
241 C<name>'s length, in bytes.
247 The prototype you want to apply to the subroutine, or C<NULL> if none.
248 Allowed to be static.
254 C<proto>'s length, in bytes.
260 The pp function that will be called instead of the subroutine.
261 C<Perl_ppaddr_t> is a typedef'd function pointer defined by perl as :
263 typedef OP *(*Perl_ppaddr_t)(pTHX);
267 C<sub_op_check_t check>
269 An optional callback that will be called each time a call to C<name> is replaced.
270 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.
271 C<sub_op_check_t> is a typedef'd function pointer defined by :
273 typedef OP *(*sub_op_check_t)(pTHX_ OP *, void *);
279 An optional user data passed to the C<check> callback.
283 =head2 C<void sub_op_init(sub_op_config_t *c)>
285 Initializes the fields of the C<sub_op_config_t> object.
286 For future compatibility, it is required to call this function with your config object before storing your actual values.
287 It will store safe defaults for members you won't set.
289 =head2 C<void sub_op_register(pTHX_ const sub_op_config_t *c, U32 flags)>
291 Registers a name and its configuration into L<Sub::Op>.
292 The caller is responsible for allocating and freeing the C<sub_op_config_t> object.
293 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.
295 =head2 C<sub_op_config_t *sub_op_dup(pTHX_ const sub_op_config_t *orig)>
297 Deeply clones the specified C<sub_op_config_t> object.
299 =head2 C<void sub_op_free(pTHX_ sub_op_config_t *c)>
301 Free the memory associated with the specified C<sub_op_config_t> object.
305 =head2 C<enable $name, [ $pkg ]>
307 Enable the replacement with a custom opcode of calls to the C<$name> subroutine of the C<$pkg> package in the current lexical scope.
308 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.
310 When C<$pkg> is not set, it defaults to the caller package.
317 my $pkg = @_ > 0 ? $_[0] : caller;
318 my $map = _map($pkg);
321 $map->{$name} = _tag($pkg, $name);
323 $map = _cast($pkg, $name);
326 my $proto = $map->{$name}->{proto};
327 if (defined $proto) {
329 Scalar::Util::set_prototype(\&{"${pkg}::$name"}, undef);
333 $^H{+(__PACKAGE__)} = 1;
335 on_scope_end { disable($name, $pkg) };
340 =head2 C<disable $name, [ $pkg ]>
342 Disable the replacement for calls to C<$name> in the package C<$pkg>.
344 When C<$pkg> is not set, it defaults to the caller package.
351 my $pkg = @_ > 0 ? $_[0] : caller;
352 my $map = _map($pkg);
354 my $fqn = join '::', $pkg, $name;
357 my $tag = $map->{$name};
359 my $old = $tag->{old};
362 no warnings 'redefine';
366 my $proto = $tag->{proto};
367 if (defined $proto) {
369 Scalar::Util::set_prototype(\&$fqn, $proto);
372 delete $map->{$name};
373 unless (keys %$map) {
383 See the F<t/Sub-Op-LexicalSub> directory that implements a complete example.
387 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.
388 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.
390 Function calls without parenthesis inside an C<eval STRING> in the scope of the pragma won't be replaced.
391 I know a few ways of fixing this, but I've not yet decided on which.
397 L<Variable::Magic>, L<B::Hooks::EndOfScope>.
399 L<ExtUtils::Depends>.
405 L<B::Hooks::XSUB::CallAsOp> provides a C API to declare XSUBs that effectively call a specific PP function.
406 Thus, it allows you to write XSUBs with the PP stack conventions used for implementing perl core keywords.
407 There's no opcode replacement and no parsing hacks.
409 L<B::Hooks::OP::Check::EntersubForCV>.
413 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
415 You can contact me by mail or on C<irc.perl.org> (vincent).
419 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>.
420 I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
424 You can find documentation for this module with the perldoc command.
428 Tests code coverage report is available at L<http://www.profvince.com/perl/cover/Sub-Op>.
430 =head1 COPYRIGHT & LICENSE
432 Copyright 2010 Vincent Pit, all rights reserved.
434 This program is free software; you can redistribute it and/or modify it
435 under the same terms as Perl itself.