[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: scm_c_catch question
From: |
Neil Jerram |
Subject: |
Re: scm_c_catch question |
Date: |
Sat, 16 Aug 2014 15:24:54 +0200 |
User-agent: |
Roundcube Webmail/0.9.5 |
On 2014-08-16 00:13, Ian Grant wrote:
Hello Guile types,
Hi Ian,
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
[1] 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?
It was a while ago, but it was me who first implemented that pre-unwind
handler. So maybe I can help here.
No, I don't think that is the right understanding. The manual (at least
for 2.0.11) says:
A PRE-UNWIND-HANDLER can exit either normally or non-locally. If
it exits normally, Guile unwinds the stack and dynamic context and
then calls the normal (third argument) handler. If it exits
non-locally, that exit determines the continuation.
In either case, I believe the intention is for any exception to
terminate the catch. In the case where the pre-unwind handler exits
normally, the catch is terminated after the main handler has been
called. In the case where the pre-unwind handler exits non-locally, I
think it's assumed that the new context is somewhere outside of the
catch, and hence that the catch is no longer in effect.
In either case, therefore, handling any subsequent exception should
require establishing a new catch.
In your code, the pre-unwind handler calls failwith() and doesn't expect
it to return - so where does it jump to?
Regards,
Neil