catacomb-python.h, *.c: Fix how Python `pgen' handlers handle exceptions.
authorMark Wooding <mdw@distorted.org.uk>
Thu, 14 Nov 2019 19:08:53 +0000 (19:08 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 22 Nov 2019 22:18:11 +0000 (22:18 +0000)
commit87aa2e3c42d96790852436f8f108fc70bd87de9c
tree1c277bf8961142050ac0904e87ca243ff265203a
parent87b60410226b9b6e15fcac3bae1cb4f67cc34f2a
catacomb-python.h, *.c: Fix how Python `pgen' handlers handle exceptions.

Oh, this was a mess.  The old code would convert an exception from a
Python handler into `PGEN_ABORT', and hope that the exception state was
still available when the overall operation ended.

This doesn't work.  In particular, steppers and testers are finalized by
calling them with `PGEN_DONE', and the interpreter doesn't like
re-entering Python with an exception set.  (In debug builds, this is an
assertion failure.)

Overhaul all of this nonsense.

  * Add a collection of utilities for saving and restoring the exception
    state.

  * Add a hook, in the `catacomb' module, for reporting `lost'
    exceptions, for the case where further exceptions are raised while
    responding to a first exception.

  * Use a larger `pypgev' structure to track the state of a Python event
    handler through the framework.  This structure holds a reference to
    the Python object itself, and a slot for recording an exception.

  * When a Python handler fails, stash the exception state in the slot
    provided by the `pypgev' structure if there isn't one already, and
    clear the pending exception.  If there is already an exception in
    the slot, then report the new exception through the hook described
    above.

  * Once a `pgen' operation completes, if it raised any exceptions at
    all, then the first of these is left in the exception slot.  If it
    fails otherwise, then we supply a generic exception.
catacomb-python.h
util.c