summaryrefslogtreecommitdiffstats
path: root/signal.h
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-02-23 16:35:44 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-02-23 16:54:47 -0800
commit3e90887df08f70beb2752e5e3a1e9bebfa93ea2c (patch)
tree68dd5cbfba1d1b5e35f83431642354cc8e751fc2 /signal.h
parent41cca60e490bd252ce4382fb3edc93281e20b906 (diff)
downloadtxr-3e90887df08f70beb2752e5e3a1e9bebfa93ea2c.tar.gz
txr-3e90887df08f70beb2752e5e3a1e9bebfa93ea2c.tar.bz2
txr-3e90887df08f70beb2752e5e3a1e9bebfa93ea2c.zip
Introducing some changes for improved handling of special variables.
Saving and restoring of individual variables is very silly and it's making it difficult to implement function parameters that are rebindings of special variables. Let's have a global pointer to a dynamic environment called dyn_env. Let's make it part of the extended_jmp_buf structure, so that it's implicitly saved and restored across exception handling. Special variable lookups go through the dyn_env chain, and fall back on the global bindings. To override some specials, we just push a new dynamic environment and stick them there. (As a bonus, the bindings can even be repeated in the lexical environment (i.e. the same objects), so they can be found faster. We have to make sure we remove that environment when we leave the scope in the normal way. If we unwind out, it is done automatically by extended_longjmp mechanism. * eval.c (dyn_env): New global variable. (lookup_var, lookup_var_l): If env is nil, look in the dyn_env first, and only if that fails, look in the global bindings top_vb. * signal.h (extended_jmp_buf): New member, de, for saving/restoring dyn_env. This structure is now used whether or not we have signals. (extended_setjmp, extended_longjmp): Updated to save and restore dyn_env, and to do it regardless of whether there is POSIX signal support. (dyn_env): Declared here.
Diffstat (limited to 'signal.h')
-rw-r--r--signal.h23
1 files changed, 20 insertions, 3 deletions
diff --git a/signal.h b/signal.h
index 32281e9a..5aa49c82 100644
--- a/signal.h
+++ b/signal.h
@@ -61,15 +61,18 @@ typedef struct {
jmp_buf jb;
sig_atomic_t se;
sigset_t blocked;
+ val de;
int rv;
} extended_jmp_buf;
#define extended_setjmp(EJB) \
(setjmp((EJB).jb) \
? (async_sig_enabled = (EJB).se, \
+ dyn_env = (EJB).de, \
sig_mask(SIG_SETMASK, &(EJB).blocked, 0), \
(EJB).rv) \
: ((EJB).se = async_sig_enabled, \
+ (EJB).de = dyn_env, \
(EJB).blocked = sig_blocked_cache, 0))
#define extended_longjmp(EJB, ARG) \
@@ -86,13 +89,27 @@ extern volatile sig_atomic_t async_sig_enabled;
#define sig_restore_enable do { } while (0); } while (0)
#define sig_restore_disable do { } while (0); } while (0)
-typedef jmp_buf extended_jmp_buf;
-#define extended_setjmp(EJB) setjmp(EJB)
-#define extended_longjmp(EJB, ARG) longjmp(EJB, ARG)
+typedef struct {
+ jmp_buf jb;
+ val de;
+ int rv;
+} extended_jmp_buf;
+
+#define extended_setjmp(EJB) \
+ (setjmp((EJB).jb) \
+ ? (dyn_env = (EJB).de, \
+ (EJB).rv) \
+ : ((EJB).de = dyn_env, 0))
+
+#define extended_longjmp(EJB, ARG) \
+ ((EJB).rv = (ARG), longjmp((EJB).jb, 1))
+
extern int async_sig_enabled;
#endif
+extern val dyn_env; /* eval.c */
+
extern val sig_hup, sig_int, sig_quit, sig_ill, sig_trap, sig_abrt, sig_bus;
extern val sig_fpe, sig_kill, sig_usr1, sig_segv, sig_usr2, sig_pipe, sig_alrm;
extern val sig_term, sig_chld, sig_cont, sig_stop, sig_tstp, sig_ttin;