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