From: Vincent Pit Date: Fri, 23 Apr 2010 14:30:30 +0000 (+0200) Subject: Revamp documentation X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FSub-Op.git;a=commitdiff_plain;h=45db99eaea3d62c21f1f9ca9503b671a4040af6f Revamp documentation --- diff --git a/lib/Sub/Op.pm b/lib/Sub/Op.pm index d8a6b73..c7b705d 100644 --- a/lib/Sub/Op.pm +++ b/lib/Sub/Op.pm @@ -7,7 +7,7 @@ use warnings; =head1 NAME -Sub::Op - Install subroutines as opcodes. +Sub::Op - Hook compilation of keyword calls and reference constructors. =head1 VERSION @@ -28,35 +28,49 @@ BEGIN { =head1 SYNOPSIS +In the end user Perl code : + + { + use Sub::Recall; + # There's no "call" symbol defined in this scope + + # Compiles to "sub { $_[0] + $_[1] }->(1, 2)" + my $three = call { $_[0] + $_[1] } 1, 2; + } + 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; + STATIC OP *sub_recall_call(pTHX_ OP *, void *ud_) { + OP *ex_list, *pushmark, *refgen, *gvop, *last_arg, *rv2cv; + + ex_list = cUNOPo->op_first; + pushmark = cUNOPx(ex_list)->op_first; + refgen = pushmark->op_sibling; + gvop = sub_op_study(o, &last_arg, &rv2cv); + + /* Replace the function name by the refgen that contains the anon sub */ + op_free(rv2cv); + last_arg->op_sibling = refgen; + pushmark->op_sibling = refgen->op_sibling; + refgen->op_sibling = NULL; + + return o; } - MODULE = Scalar::Util::Ops PACKAGE = Scalar::Util::Ops + MODULE = Sub::Recall PACKAGE = Sub::Recall BOOT: { sub_op_config_t c; sub_op_init(&c); - c.name = "reftype"; - c.namelen = sizeof("reftype")-1; - c.proto = "$"; - c.protolen = sizeof("$")-1; - c.pp = scalar_util_reftype; - c.check = 0; + c.name = "call"; + c.namelen = sizeof("call")-1; + c.proto = "&@"; + c.protolen = sizeof("&@")-1; + c.call = sub_recall_call; + c.ref = 0; c.ud = NULL; sub_op_register(aTHX_ &c, 0); } @@ -79,9 +93,9 @@ In your Perl module file : __PACKAGE__->bootstrap($VERSION); } - sub import { Sub::Op::enable(reftype => scalar caller) } + sub import { Sub::Op::enable(call => scalar caller) } - sub unimport { Sub::Op::disable(reftype => scalar caller) } + sub unimport { Sub::Op::disable(call => scalar caller) } 1; @@ -98,26 +112,10 @@ In your F : =head1 DESCRIPTION -This module provides a C and Perl API for replacing subroutine calls by custom opcodes. -This has two main advantages : - -=over 4 - -=item * - -it gets rid of the overhead of a normal subroutine call ; - -=item * +This module provides a C and Perl API for hooking compilation of subroutine calls and reference constructors for a given name and prototype, and this without polluting the caller namespace with a dummy symbol. +This allows you to define customized keywords that compile to whatever construct you want. -there's no symbol table entry defined for the subroutine. - -=back - -Subroutine calls with and without parenthesis are handled. -Ampersand calls are B 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 L and L are loaded, they get automatically monkeypatched so that introspecting modules like L and L still produce a valid output. +Subroutine calls with and without parenthesis are handled, but ampersand calls are B caught. =cut @@ -255,28 +253,25 @@ C's length, in bytes. =item * -C +C -The pp function that will be called instead of the subroutine. -C is a typedef'd function pointer defined by perl as : +An optional callback that will be fired each time C compiles a function call to C. +You can use it to attach extra info to those ops (e.g. with a pointer table), perform some optimizations to the optree, or completely replace the call. +C is a typedef'd function pointer defined by : - typedef OP *(*Perl_ppaddr_t)(pTHX); + typedef OP *(*sub_op_check_t)(pTHX_ OP *, void *); =item * -C +C -An optional callback that will be called each time a call to C 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. -C is a typedef'd function pointer defined by : - - typedef OP *(*sub_op_check_t)(pTHX_ OP *, void *); +An optional callback that will be fired each time a reference to C is taken. =item * C -An optional user data passed to the C callback. +An optional user data passed to the C and C callbacks. =back @@ -300,12 +295,18 @@ Deeply clones the specified C object. Free the memory associated with the specified C object. +=head2 C + +Studies the subset of the optree based on C, expecting it to be an C or C op (the ones you get in the C and C callbacks). +If the tree is well-formed, C<*last_arg_p> will be set to the last argument of the call, C<*rv2cv_p> to the C op that resolves the function name, and the C op will be returned. +Otherwise, this function returns C. + =head1 PERL API =head2 C -Enable the replacement with a custom opcode of calls to the C<$name> subroutine of the C<$pkg> package in the current lexical scope. -A pp callback must have been registered for C<$name> by calling the C function C in the XS section of your module. +Enable the capture of function calls and references constructors to C<$name> in the C<$pkg> package in the current lexical scope. +You must have registered an appropriate C configuration by calling the C function C in the XS section of your module. When C<$pkg> is not set, it defaults to the caller package. @@ -339,7 +340,7 @@ sub enable { =head2 C -Disable the replacement for calls to C<$name> in the package C<$pkg>. +Disable the capture of function calls and reference constructors to C<$name> in the package C<$pkg>. When C<$pkg> is not set, it defaults to the caller package. @@ -402,10 +403,6 @@ L. L. -L provides a C API to declare XSUBs that effectively call a specific PP function. -Thus, it allows you to write XSUBs with the PP stack conventions used for implementing perl core keywords. -There's no opcode replacement and no parsing hacks. - L. =head1 AUTHOR