diff options
author | Ben Morrow <ben@morrow.me.uk> | 2009-12-07 11:52:23 +0000 |
---|---|---|
committer | Rafael Garcia-Suarez <rgs@consttype.org> | 2010-07-12 10:40:47 +0200 |
commit | 52db365a88f7ab3b9b091f983a05054164499982 (patch) | |
tree | b4c8cfb606ca59bff9d00fd9263e797771fb5e3e | |
parent | 03569ecfc8c82939dcc47b586a8e22c613c158b2 (diff) | |
download | perl-52db365a88f7ab3b9b091f983a05054164499982.tar.gz |
Macroify the block_hooks structure.
Add a flags member, so it can be extended later if necessary. Add a
bhk_eval member, called from doeval to catch requires and string evals.
-rw-r--r-- | ext/XS-APItest/APItest.xs | 16 | ||||
-rw-r--r-- | op.h | 28 | ||||
-rw-r--r-- | perl.h | 2 | ||||
-rw-r--r-- | pp_ctl.c | 2 |
4 files changed, 35 insertions, 13 deletions
diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs index 012102dd3f..54880b73b3 100644 --- a/ext/XS-APItest/APItest.xs +++ b/ext/XS-APItest/APItest.xs @@ -271,17 +271,12 @@ blockhook_pre_end(pTHX_ OP **o) /* if we hit the end of a scope we missed the start of, we need to * unconditionally clear @CSC */ - if (GvAV(MY_CXT.cscgv) == MY_CXT.cscav && MY_CXT.cscav) + if (GvAV(MY_CXT.cscgv) == MY_CXT.cscav && MY_CXT.cscav) { av_clear(MY_CXT.cscav); + } } -STATIC struct block_hooks my_block_hooks = { - blockhook_start, - blockhook_pre_end, - NULL -}; - #include "const-c.inc" MODULE = XS::APItest:Hash PACKAGE = XS::APItest::Hash @@ -634,6 +629,7 @@ PROTOTYPES: DISABLE BOOT: { + BHK *bhk; MY_CXT_INIT; MY_CXT.i = 99; @@ -642,9 +638,13 @@ BOOT: GV_ADD, SVt_PVAV); MY_CXT.cscav = GvAV(MY_CXT.cscgv); + Newxz(bhk, 1, BHK); + BhkENTRY_set(bhk, start, blockhook_start); + BhkENTRY_set(bhk, pre_end, blockhook_pre_end); + if (!PL_blockhooks) PL_blockhooks = newAV(); - av_push(PL_blockhooks, newSViv(PTR2IV(&my_block_hooks))); + av_push(PL_blockhooks, newSViv(PTR2IV(bhk))); } void @@ -646,27 +646,45 @@ struct loop { #endif struct block_hooks { + U32 bhk_flags; void (*bhk_start) (pTHX_ int full); void (*bhk_pre_end) (pTHX_ OP **seq); void (*bhk_post_end) (pTHX_ OP **seq); + void (*bhk_eval) (pTHX_ OP *const saveop); }; +#define BhkFLAGS(hk) ((hk)->bhk_flags) + +#define BHKf_start 0x01 +#define BHKf_pre_end 0x02 +#define BHKf_post_end 0x04 +#define BHKf_eval 0x08 + +#define BhkENTRY(hk, which) \ + ((BhkFLAGS(hk) & BHKf_ ## which) ? ((hk)->bhk_ ## which) : NULL) + +#define BhkENTRY_set(hk, which, ptr) \ + STMT_START { \ + (hk)->bhk_ ## which = ptr; \ + (hk)->bhk_flags |= BHKf_ ## which; \ + } STMT_END + #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; \ + BHK *hk; \ \ assert(SvIOK(sv)); \ if (SvUOK(sv)) \ - hk = INT2PTR(struct block_hooks *, SvUVX(sv)); \ + hk = INT2PTR(BHK *, SvUVX(sv)); \ else \ - hk = INT2PTR(struct block_hooks *, SvIVX(sv)); \ + hk = INT2PTR(BHK *, SvIVX(sv)); \ \ - if (hk->bhk_ ## which) \ - CALL_FPTR(hk->bhk_ ## which)(aTHX_ arg); \ + if (BhkENTRY(hk, which)) \ + CALL_FPTR(BhkENTRY(hk, which))(aTHX_ arg); \ } \ } \ } STMT_END @@ -2385,6 +2385,8 @@ typedef struct padop PADOP; typedef struct pvop PVOP; typedef struct loop LOOP; +typedef struct block_hooks BHK; + typedef struct interpreter PerlInterpreter; /* Amdahl's <ksync.h> has struct sv */ @@ -3131,6 +3131,8 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq) else CLEAR_ERRSV(); + CALL_BLOCK_HOOKS(eval, saveop); + /* note that yyparse() may raise an exception, e.g. C<BEGIN{die}>, * so honour CATCH_GET and trap it here if necessary */ |