guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: scm_c_catch question


From: Ian Grant
Subject: Re: scm_c_catch question
Date: Sat, 23 Aug 2014 21:09:51 -0400

Thanks Neil, that works. This is what I did: but I made no attempt to make the C-level interface backwardly compatible. It seems the same option could apply to scm_with_throw_handler, but I left that alone. Can anyone tell me what where the semantics to the latter when the LAZY_THROW_P paramerter was set? It sounds like it used to evaluate the handler in the dynamic context of the destination, like a continuation.

Ian




On Wed, Aug 20, 2014 at 2:02 PM, Neil Jerram <address@hidden> wrote:
On 2014-08-18 03:14, Ian Grant wrote:
Hi Neil,

Sorry, I am replying to my message because I'm not on guile-devel, it
seems. I'll join later.

Thanks for clarifying that. The misleading statement in the manual is
just above the paragraph you quote: on
https://www.gnu.org/software/guile/manual/html_node/Catch.html#Catch
[2] it says


    Handler is invoked outside the scope of its own catch. If
handler
    again throws to the same key, a new handler from further up the
    call chain is invoked.

It doesn't mention pre_unwind_handler, which implies that the
statement does _not_ apply to pre_unwind_handler.

Yes, I believe it is correct that those statements do not apply to the pre-unwind handler.


So this should be
amended.

But it would be more useful if there were a way to allow a throw to be
aborted as I was expecting. How hard would that be to implement? If
you think the semantics are in fact different, it could be given a new
name, scm_c_catch_and_rethrow or something. What I want is something
like BSD signals semantics, where the handler is not reset when the
signal occurs.

You ask "In your code, the pre-unwind handler calls failwith() and
doesn't expect it to return - so where does it jump to?"

I thought I had explained that, sorry. The call to failwith() does a C
longjmp back into the CAML bytecode interpreter (i.e. back down below
the call stack into caml_main). This is not a non-local exit, as far
as Guile is concerned, because it is just a 'naked' C longjmp. So in
that sense, the second time Guile throws an exception it is being
thrown from within pre_unwind_handler.

OK, I think I see now.  From Guile's point of view, the dynamic context of the 'catch' remains in effect - as you want - but with a flag to say that the pre-unwind handler is already running (actually implemented by the %running-exception-handlers fluid in boot-9.scm).  That explains why the _next_ exception causes the catch's main handler to be called, instead of the pre-unwind handler again.


Is there a way to implement what I want with fluids?

I don't think so, no.  Basically what you need is to make some call, from the pre-unwind handler code, just before calling failwith(), that says "this pre-unwind handler should now be reactivated" and is implemented by removing itself from %running-exception-handlers.  But %running-exception-handlers is hidden inside a lexical environment, so that isn't possible without hacking the boot-9 code.

You could try hacking the boot-9 code, though, to see if that idea works, and then propose a patch.

Regards,
     Neil


Attachment: reset-catch.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]