diff options
author | Paul "LeoNerd" Evans <leonerd@leonerd.org.uk> | 2021-12-16 21:43:08 +0000 |
---|---|---|
committer | ℕicolas ℝ <nicolas@atoomic.org> | 2022-01-20 11:41:09 -0700 |
commit | 1a7eed135c20f2515b61b6960de09800d80ca9cd (patch) | |
tree | 6976098c97a79712202ceec45f4a2a8a74b1f91f /op.c | |
parent | 0a3ddc721abc261a58c47a6d376ed8224d00582a (diff) | |
download | perl-1a7eed135c20f2515b61b6960de09800d80ca9cd.tar.gz |
Add op_wrap_finally() convenience function
Diffstat (limited to 'op.c')
-rw-r--r-- | op.c | 26 |
1 files changed, 26 insertions, 0 deletions
@@ -10723,6 +10723,32 @@ Perl_newDEFEROP(pTHX_ I32 flags, OP *block) return o; } +/* +=for apidoc op_wrap_finally + +Wraps the given C<block> optree fragment in its own scoped block, arranging +for the C<finally> optree fragment to be invoked when leaving that block for +any reason. Both optree fragments are consumed and the combined result is +returned. + +*/ + +OP * +Perl_op_wrap_finally(pTHX_ OP *block, OP *finally) +{ + PERL_ARGS_ASSERT_OP_WRAP_FINALLY; + + /* TODO: If block is already an ENTER/LEAVE-wrapped line sequence we can + * just splice the DEFEROP in at the top, for efficiency. + */ + + OP *o = newLISTOP(OP_LINESEQ, 0, newDEFEROP(0, finally), block); + o = op_prepend_elem(OP_LINESEQ, newOP(OP_ENTER, 0), o); + OpTYPE_set(o, OP_LEAVE); + + return o; +} + /* must not conflict with SVf_UTF8 */ #define CV_CKPROTO_CURSTASH 0x1 |