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 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. 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.

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

Ian



On Fri, Aug 15, 2014 at 6:13 PM, Ian Grant <ian.a.n.gr...@googlemail.com>
wrote:

> Hello Guile types,
>
> I have been experimenting with using libguile from within another
> byte-code interpreter: Moscow ML. I have a version of Moscow ML with an GNU
> lightning interface in which I JIT compile primitives to give access to
> libguile functions from Standard ML.
>
> Moscow ML uses an old version of the CAML light runtime which is a
> byte-code interpreter implemented in C. The CAML runtime provides
> exceptions implemented using a longjmp buffer.
>
> The Moscow ML top-level REPL is implemented as a byte-code compiled ML
> function which is invoked by main(). What I would like to do would be to
> catch any unhandled Guile exceptions and re-throw them as ML exceptions so
> that the toplevel isn't exit'ed by an un-handled scheme exception. To this
> end I call the CAML main from the scm_boot_guile callback, under a
> scm_c_catch. This code is in the guilert.c file
> https://github.com/IanANGrant/red-october/blob/master/src/runtime/guilert.c
> The only CAML'ism here is the call to failwith("message"). This does a
> longjump 'into the CAML exception bucket'
>
> The problem is that after the first successful catch by the pre-unwind
> handler, the next Guile exception is handled by the main_handler. This is
> not what I expected. The manual seems to say that it is only after the
> main_handler is invoked, that the catch is cancelled. Is this not the right
> understanding? The output of the example shows this isn't what happens:
>
> debug: main_trampoline: calling
> scm_c_catch(main_call,main_handler,main_pre_unwind_handler)
> debug: main_call: calling caml_main
> Moscow ML [Red October] 2.10
> Type `quit();' to quit.
> - scm_repl();
> Moscow ML Guile REPL
> Type `(quit)' to exit.
> > (+ "ab")
> debug: main_pre_unwind_handler called
> ! Uncaught exception:
> ! Fail  "Uncaught scheme exception"
> - scm_repl();
> Moscow ML Guile REPL
> Type `(quit)' to exit.
> > (+ "ab")
> debug: main_handler called
> debug: main_trampoline: scm_c_catch returned!
>
> Process mosml finished
>
>

Reply via email to