Exceptions and GObject-based libraries
- From: Andy Wingo <wingo pobox com>
- To: language-bindings gnome org
- Cc: guile-gtk-devel gnu org
- Subject: Exceptions and GObject-based libraries
- Date: Fri, 27 Aug 2004 13:10:11 +0100
Hey all,
I've been tracking down bizarre bugs in some code I'm writing. In doing
so, I realized that my naive practice of throwing exceptions and
invoking continuations in a signal handler is incorrect.
The concrete reason is that signal_emit_unlocked_R in gsignal.c
allocates a data structure on the stack, references it from the heap,
assuming that it can dereference it when the function exits. If the
function performs a nonlocal exit, then gsignal.c still points to a
location on the stack, which will probably be clobbered later as the
stack grows. (Speaking of emission and g_recursive_emissions.)
This is unfortunate, and really reduces the expressivity of using
higher-level languages with gobject-based libraries. I seem to recall
that python uses different return values to implement exceptions, but I
know C++ has true non-local exits. I wanted to know how the rest of you
deal with this situation.
Also, I wanted to know if there's interest in at least making GObject
exception-safe. Gtk+ would take a lot more work, of course. This would
likely require explicit unwind blocks in a function, e.g.:
int state = 0;
int
myfun (void)
{
G_BEGIN_UNWIND_PROTECT (myfun);
state = 1;
emit_my_signal ();
G_UNWIND (myfun) {
state = 0;
}
G_END_UNWIND_PROTECT (myfun);
return 10;
}
The expansion could be something like the following:
int
myfun (void)
{
int _myfun_jumped;
jmp_buf _myfun_jmp_buf;
g_push_jmp_buf (&_myfun_jmp_buf);
if ((_myfun_jumped = setjmp (_myfun_jmp_buf)))
goto _myfun_unwind;
state = 1;
emit_my_signal ();
_myfun_unwind:
g_pop_jmp_buf ();
{
state = 0;
}
if (_myfun_jumped)
longjmp (*g_peek_jmp_buf (), -1);
return 10;
}
The push/pop routines would have to keep a thread-local stack of jump
buffers for all of this to work. Then a language binding would have
to catch any uncaught exceptions coming from closures, call
`longjmp (g_peek_jmp_buf (), -1)' (which should probably be wrapped as
g_throw or something), and have a jmp buffer set up to catch uncaught
exceptions somewhere.
I'm afraid this is all too complicated, though. Portability would also
bite us pretty hard. But I see in the future a world in which few people
write their graphical applications in C. It would be a shame if all of
these higher-level languages would have to restrict themselves in order
to use Gtk+.
Any thoughts? Am I crazy?
--
Andy Wingo <wingo pobox com>
http://ambient.2y.net/wingo/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]