set up catchable runloops early enough
authorZefram <zefram@fysh.org>
Sun, 26 Mar 2017 20:53:29 +0000 (21:53 +0100)
committerZefram <zefram@fysh.org>
Thu, 1 Jun 2017 17:24:52 +0000 (18:24 +0100)
commitd7e3f70f30811328d2f6ae57e5892deccf64d0b2
tree453f564f00ad60819ea1544bee772ead081456ef
parent4e1ed312da261450ba45a56e7b6756a873678f52
set up catchable runloops early enough

The jmpenv frame to catch Perl exceptions is set up lazily, and this used
to be a bit too lazy.  The flow of control through pp_entereval had a gap
where the eval frame was on the context stack but the catcher hadn't been
set up, and it was possible for an exception to occur in that gap and be
signalled through unwinding, which would thus break.  Specifically this
occurred if the code being evaluated died in a UNITCHECK block, because
doeval_compile() invokes those blocks with no special arrangements for
exceptions, whereas it handles compilation/BEGIN exceptions by means
that don't unwind.

This patch sets up the catcher earlier, before putting the eval frame
on the context stack.  This change is made to entereval, entertry,
and require, the three ops that set up real eval frames.  In each case,
whereas previously the catcher was interposed last thing before handing
off to the following op, the catcher is now set up first thing in the
pp function, with docatch() now recursively invoking the pp function.

Fixes [perl #105930].
MANIFEST
embed.fnc
pp_ctl.c
proto.h
t/op/catch.t [new file with mode: 0644]