diff options
author | Ben Morrow <ben@morrow.me.uk> | 2009-11-26 17:18:29 +0000 |
---|---|---|
committer | Rafael Garcia-Suarez <rgs@consttype.org> | 2010-07-12 10:40:47 +0200 |
commit | 1930840b26541ab67ff111a47ceab4753d798617 (patch) | |
tree | f27bbe5e370d51ad4f243eea906dc3b546f05efc /op.h | |
parent | 3e2d3818e517e0037c1ab6a482f31d50271f9e27 (diff) | |
download | perl-1930840b26541ab67ff111a47ceab4753d798617.tar.gz |
Generic hooks into Perl_block_{start,end}.
These take the form of a vtable pushed onto the new PL_blockhooks array.
This could probably do with a API around it later. Separate pre_end and
post_end hooks are needed to capture globals before the stack is unwound
(like needblockscope in the existing code). The intention is that once
a vtable is installed it never gets removed, so where necessary
extensions using this will need to use a hinthv element to determine
whether to do anything or not.
Diffstat (limited to 'op.h')
-rw-r--r-- | op.h | 26 |
1 files changed, 26 insertions, 0 deletions
@@ -645,6 +645,32 @@ struct loop { #define FreeOp(p) PerlMemShared_free(p) #endif +struct block_hooks { + void (*bhk_start) (pTHX_ int full); + void (*bhk_pre_end) (pTHX_ OP **seq); + void (*bhk_post_end) (pTHX_ OP **seq); +}; + +#define CALL_BLOCK_HOOKS(which, arg) \ + STMT_START { \ + if (PL_blockhooks) { \ + I32 i; \ + for (i = av_len(PL_blockhooks); i >= 0; i--) { \ + SV *sv = AvARRAY(PL_blockhooks)[i]; \ + struct block_hooks *hk; \ + \ + assert(SvIOK(sv)); \ + if (SvUOK(sv)) \ + hk = INT2PTR(struct block_hooks *, SvUVX(sv)); \ + else \ + hk = INT2PTR(struct block_hooks *, SvIVX(sv)); \ + \ + if (hk->bhk_ ## which) \ + CALL_FPTR(hk->bhk_ ## which)(aTHX_ arg); \ + } \ + } \ + } STMT_END + #ifdef PERL_MAD # define MAD_NULL 1 # define MAD_PV 2 |