Hi Taahir,
On Mon 23 Feb 2015 22:59, Taahir Ahmed ahmed.taa...@gmail.com writes:
Over the past few days, I've been working on reducing the amount of
defensive coding that is required when writing Guile extensions using
C++.
My primary goal is to ensure that destructors of automatic variables
are called if any Guile non-local control flow passes through a C++
stack frame.
I was thinking about this recently too, in the context of GDB's upcoming
switch to C++, though I didn't get very far in the thinking.
1) To check that I'm not duplicating any other ongoing work,
Not that I know of. Doesn't matter anyway, a good solution is always
acceptable :)
2) To float two different implementation strategies and see which
one is the best choice going forward, and
3) To get clarification on some issues that I've encountered with a
prototype implementation.
Cool.
The two major strategies I considered are:
1) Replace all uses of set/longjmp in the Guile source with C++
exceptions. This approach is simple in some ways, and
complicated in others. I would hesitate to pursue this unless
Guile has some sort of longer-term plan to move towards C++.
I am not C++-averse but a hypothetical move towards C++ in a Guile
context doesn't necessarily mean moving towards use of exceptions.
Scheme has fairly complicated control flow and embracing C++ exceptions
doesn't necessarily solve things. For example an exception propagating
over natively-compiled Scheme code would have to run dynwinds. Calling
out to C++ would have to set up some sort of try/catch. Is that the
right design? I don't know.
(I do think that the C-stack-saving aspect of Guile's continuations is a
silly thing, given that delimited continuations are more expressive, we
can have escape-only continuations either way, and our VM and future
native compilation pipeline means that we don't have so much rewinding
of C stack frames, and in any case rewinding is unexpected and untested
by most Guile core code, not to mention user code.)
2) Replace all uses of set/longjmp with replacements (call them
eh_setjmp and eh_longjmp) that are based on libunwind [1].
No opinion other than a vague aversion to dependencies.
However, I've run into an issue --- many of Guile's uses of setjmp
don't conform to the C standard. In particular, after experiencing a
non-local return from setjmp, you're not allowed to access any
non-volatile local variables, but Guile does (see the local variable
mx in eval()).
You are allowed to access variables that could never be assigned after
the setjmp, AFAIK? Anyway how is mx accessed before being re-set after
a prompt longjmp?
Cheers, and thanks for looking at this,
Andy
--
http://wingolog.org/