Q about TT #1091 (deprecate label-based exception handlers)

Bob Rogers rogers-perl6 at rgrjr.dyndns.org
Sun Dec 13 16:53:30 UTC 2009


   From: Bob Rogers <rogers-perl6 at rgrjr.dyndns.org>
   Date: Tue, 8 Dec 2009 21:52:18 -0500

      From: Andrew Whitworth <wknight8111 at gmail.com>
      Date: Tue, 8 Dec 2009 08:08:01 -0500

      On Mon, Dec 7, 2009 at 11:43 PM, Bob Rogers wrote:

      > . . . Since it seems that we are stuck with inferior runloops for
      > the foreseeable future, maybe half a glass would be better than
      > none.

      I would like to see more information from you about this idea. I can't
      imagine that it's going to resolve all our problems but it sounds
      quite interesting nonetheless and aligns with some ideas I've been
      kicking around.

   OK, I'll try to elaborate when I have more time.  With any luck, I may
   get a chance to hack up a PoC this weekend.

This turned out to be easier than I expected, due mostly to the new
"struct parrot_runloop_t" machinery.  The first attachment contains a
test case that illustrates the problem:  A sort function that is induced
to throw an error by a buggy sort.  Running this in an unpatched Parrot
gives the following output:

	rogers at rgr> ./parrot ./t/pmc/test_sort_eh.t 
	1..1
	throwing
	ok 1 - buggy sort on FixedPMCArray did throw
	ok 2 - test_sort_eh_inner normal return
	throwing
	No exception handler and no message
	current instr.: 'integer_cmp_fun' pc 79 (test_sort_eh.t:44)
	rogers at rgr> 

At first, it looks like it all worked, but the exception was thrown to
the inner runloop, so when that returns, the sort resumes execution as
if the comparison function had returned normally, and subsequently
encounters another error.  (Though I don't understand why the outer
handler doesn't catch the second error; is this a bug in handler
scoping?)

   Applying the patch in the second attachment and then disabling the
search loop in ExceptionHandler:invoke shows what is going on:

	rogers at rgr> ./parrot test_sort_eh.t
	1..1
	throwing
	[oops; continuation 0x80be08c of type 18 is trying to jump from runloop 12 to runloop 1]
	ok 1 - buggy sort on FixedPMCArray did throw
	ok 2 - test_sort_eh_inner normal return
	throwing
	No exception handler and no message
	current instr.: 'integer_cmp_fun' pc 79 (test_sort_eh.t:44)
	rogers at rgr> 

Enabling the search loop gives the intended result (complete with
debugging output):

	rogers at rgr> ./parrot test_sort_eh.t
	1..1
	throwing
	[continuation 0x80be08c of type 18 is jumping from runloop 12 to runloop 1]
	ok 1 - buggy sort on FixedPMCArray did throw
	ok 2 - test_sort_eh_inner normal return
	rogers at rgr> 

How it works, of course, is simple:  Every continuation (not just those
of type ExceptionHandler) remembers the runloop that initialized it.  If
we define an "active runloop" as one for which "runops" hasn't exited
yet, then all active runloops are reachable from the
interp->current_runloop linked list.  Therefore, if we can't find the
right runloop for a given continuation, then it must no longer be
active.  If we *can* find it, then we have it's jump point, and can just
go there.

   There are a number of limitations that make this a proof-of-concept
rather than a viable patch:

   1.  This only works for the ExceptionHandler class; it should be
refactored so it works for all continuation classes.

   2.  The "oops" warning should instead throw an error.  In order to
avoid looping, the unreachable continuation must have been removed as a
handler by that point; I think that has happened by then, but wouldn't
swear to it.

   3.  The unwinding of interp->current_runloop leaks parrot_runloop_t
structures (but see below).

   4.  As alluded to earlier in the thread, it would be useful to have
some mechanism for breaking the runloop chain, so that user C code that
calls into Parrot ops can insist on not being thrown through.

   In addition, there is a potential optimization:  The parrot_runloop_t
structures need not be malloc'ed.  Since they exist only to maintain a
stack of setjmp locations, and since those locations are only valid
while the runloop is active, it would be a bug to encounter a
parrot_runloop_t after its corresponding runops invocation has exited.
Therefore, it ought to be possible to allocate these structures in the
body of runops, so that they are maintained on the C stack.  However,
there are a number of new_runloop_jump_point calls that would have to be
changed, so this may not be as straightforward as it looks.

					-- Bob

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: test_sort_eh.t
URL: <http://lists.parrot.org/pipermail/parrot-dev/attachments/20091213/fc65fc1a/attachment.diff>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: handler-outer-runloop-poc-1.patch
URL: <http://lists.parrot.org/pipermail/parrot-dev/attachments/20091213/fc65fc1a/attachment-0001.diff>


More information about the parrot-dev mailing list