From fd85fad2cd9375073457ad3f1e13e90d7d79f23f Mon Sep 17 00:00:00 2001 From: Ben Morrow Date: Wed, 9 Dec 2009 10:32:23 +0000 Subject: [PATCH] Document the blockhook functions and macros. --- embed.fnc | 2 +- op.c | 11 +++++++++ op.h | 24 ++++++++++++++++++++ pod/perlguts.pod | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 1 deletion(-) diff --git a/embed.fnc b/embed.fnc index 054616a..15bd938 100644 --- a/embed.fnc +++ b/embed.fnc @@ -214,7 +214,7 @@ pR |OP* |block_end |I32 floor|NULLOK OP* seq ApR |I32 |block_gimme : Used in perly.y pR |int |block_start |int full -Aop |void |blockhook_register |NN BHK *hk +Aodp |void |blockhook_register |NN BHK *hk : Used in perl.c p |void |boot_core_UNIVERSAL : Used in perl.c diff --git a/op.c b/op.c index 9caf8cd..d832c99 100644 --- a/op.c +++ b/op.c @@ -2343,6 +2343,17 @@ Perl_block_end(pTHX_ I32 floor, OP *seq) return retval; } +/* +=head1 Compile-time scope hooks + +=for apidoc Ao||blockhook_register + +Register a set of hooks to be called when the Perl lexical scope changes +at compile time. See L. + +=cut +*/ + void Perl_blockhook_register(pTHX_ BHK *hk) { diff --git a/op.h b/op.h index ac34f1d..30a41c8 100644 --- a/op.h +++ b/op.h @@ -653,6 +653,30 @@ struct block_hooks { void (*bhk_eval) (pTHX_ OP *const saveop); }; +/* +=head1 Compile-time scope hooks + +=for apidoc m|U32|BhkFLAGS|BHK *hk +Return the BHK's flags. + +=for apidoc m|void *|BhkENTRY|BHK *hk|which +Return an entry from the BHK structure. I is a preprocessor token +indicating which entry to return. If the appropriate flag is not set +this will return NULL. The type of the return value depends on which +entry you ask for. + +=for apidoc Am|void|BhkENTRY_set|BHK *hk|which|void *ptr +Set an entry in the BHK structure, and set the flags to indicate it is +valid. I is a preprocessing token indicating which entry to set. +The type of I depends on the entry. + +=for apidoc m|void|CALL_BLOCK_HOOKS|which|arg +Call all the registered block hooks for type I. I is a +preprocessing token; the type of I depends on I. + +=cut +*/ + #define BhkFLAGS(hk) ((hk)->bhk_flags) #define BHKf_start 0x01 diff --git a/pod/perlguts.pod b/pod/perlguts.pod index b6cec65..d0178e7 100644 --- a/pod/perlguts.pod +++ b/pod/perlguts.pod @@ -1842,6 +1842,74 @@ file, add the line: This function should be as efficient as possible to keep your programs running as fast as possible. +=head2 Compile-time scope hooks + +As of perl 5.14 it is possible to hook into the compile-time lexical +scope mechanism using C. This is used like +this: + + STATIC void my_start_hook(pTHX_ int full); + STATIC BHK my_hooks; + + BOOT: + BhkENTRY_set(&my_hooks, start, my_start_hook); + Perl_blockhook_register(aTHX_ &my_hooks); + +This will arrange to have C called at the start of +compiling every lexical scope. The available hooks are: + +=over 4 + +=item C + +This is called just after starting a new lexical scope. Note that Perl +code like + + if ($x) { ... } + +creates two scopes: the first starts at the C<(> and has C, +the second starts at the C<{> and has C. Both end at the +C<}>, so calls to C and C
 will match. Anything
+pushed onto the save stack by this hook will be popped just before the
+scope ends (between the C and C hooks, in fact).
+
+=item C
+
+This is called at the end of a lexical scope, just before unwinding the
+stack. I is the root of the optree representing the scope; it is a
+double pointer so you can replace the OP if you need to.
+
+=item C
+
+This is called at the end of a lexical scope, just after unwinding the
+stack. I is as above. Note that it is possible for calls to C
+and C to nest, if there is something on the save stack that
+calls string eval.
+
+=item C
+
+This is called just before starting to compile an C, C, C or C, after the eval has been set up. I is the
+OP that requested the eval, and will normally be an C,
+C or C.
+
+=back
+
+Once you have your hook functions, you need a C structure to put
+them in. It's best to allocate it statically, since there is no way to
+free it once it's registered. The function pointers should be inserted
+into this structure using the C macro, which will also set
+flags indicating which entries are valid. If you do need to allocate
+your C dynamically for some reason, be sure to zero it before you
+start.
+
+Once registered, there is no mechanism to switch these hooks off, so if
+that is necessary you will need to do this yourself. An entry in C<%^H>
+is probably the best way, so the effect is lexically scoped. You should
+also be aware that generally speaking at least one scope will have
+opened before your extension is loaded, so you will see some
+C
 pairs that didn't have a matching C.
+
 =head1 Examining internal data structures with the C functions
 
 To aid debugging, the source file F contains a number of
-- 
2.7.4