summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile14
-rw-r--r--args.c1
-rw-r--r--arith.c1
-rw-r--r--cadr.c1
-rw-r--r--combi.c1
-rw-r--r--debug.c1
-rw-r--r--eval.c1
-rw-r--r--filter.c1
-rw-r--r--gc.c5
-rw-r--r--glob.c1
-rw-r--r--hash.c1
-rw-r--r--jmp.S180
-rw-r--r--lib.c1
-rw-r--r--match.c1
-rw-r--r--parser.c1
-rw-r--r--rand.c1
-rw-r--r--regex.c1
-rw-r--r--signal.c1
-rw-r--r--signal.h81
-rw-r--r--stream.c1
-rw-r--r--struct.c1
-rw-r--r--sysif.c1
-rw-r--r--syslog.c1
-rw-r--r--txr.c1
-rw-r--r--unwind.c1
-rw-r--r--utf8.c1
26 files changed, 270 insertions, 32 deletions
diff --git a/Makefile b/Makefile
index bc0b488e..f718e40d 100644
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,7 @@ EXTRA_OBJS-y :=
OBJS := txr.o lex.yy.o y.tab.o match.o lib.o regex.o gc.o unwind.o stream.o
OBJS += arith.o hash.o utf8.o filter.o eval.o parser.o rand.o combi.o sysif.o
-OBJS += args.o lisplib.o cadr.o struct.o
+OBJS += args.o lisplib.o cadr.o struct.o jmp.o
OBJS-$(debug_support) += debug.o
OBJS-$(have_syslog) += syslog.o
OBJS-$(have_glob) += glob.o
@@ -122,6 +122,12 @@ dbg/%.o: $(top_srcdir)%.c
opt/%.o: $(top_srcdir)%.c
$(call COMPILE_C_WITH_DEPS,$(OPT_FLAGS))
+
+dbg/%.o: $(top_srcdir)%.S
+ $(call COMPILE_C_WITH_DEPS,)
+
+opt/%.o: $(top_srcdir)%.S
+ $(call COMPILE_C_WITH_DEPS,)
endif
dbg/%.o: %.c
@@ -130,6 +136,12 @@ dbg/%.o: %.c
opt/%.o: %.c
$(call COMPILE_C_WITH_DEPS,$(OPT_FLAGS))
+dbg/%.o: %.S
+ $(call COMPILE_C_WITH_DEPS,)
+
+opt/%.o: %.S
+ $(call COMPILE_C_WITH_DEPS,)
+
dbg/%-win.o: $(top_srcdir)%.c
$(call COMPILE_C_WITH_DEPS,-DCONFIG_WIN_MAIN=1)
diff --git a/args.c b/args.c
index 9e0a6b24..7f65fc9e 100644
--- a/args.c
+++ b/args.c
@@ -25,7 +25,6 @@
*/
#include <stddef.h>
-#include <setjmp.h>
#include <signal.h>
#include <string.h>
#include "config.h"
diff --git a/arith.c b/arith.c
index 3d526b5b..21036cf4 100644
--- a/arith.c
+++ b/arith.c
@@ -29,7 +29,6 @@
#include <string.h>
#include <wctype.h>
#include <stdarg.h>
-#include <setjmp.h>
#include <wchar.h>
#include <math.h>
#include <signal.h>
diff --git a/cadr.c b/cadr.c
index 057e4f57..2172dd9b 100644
--- a/cadr.c
+++ b/cadr.c
@@ -29,7 +29,6 @@
#include <dirent.h>
#include <stdarg.h>
#include <stdlib.h>
-#include <setjmp.h>
#include <limits.h>
#include <signal.h>
#include "config.h"
diff --git a/combi.c b/combi.c
index 8a7697a5..5acd65b6 100644
--- a/combi.c
+++ b/combi.c
@@ -25,7 +25,6 @@
*/
#include <wctype.h>
-#include <setjmp.h>
#include <wchar.h>
#include <signal.h>
#include "config.h"
diff --git a/debug.c b/debug.c
index 370d13bd..487ef2a9 100644
--- a/debug.c
+++ b/debug.c
@@ -29,7 +29,6 @@
#include <string.h>
#include <errno.h>
#include <dirent.h>
-#include <setjmp.h>
#include <stdarg.h>
#include <wchar.h>
#include <signal.h>
diff --git a/eval.c b/eval.c
index ea08c7b3..bff81a48 100644
--- a/eval.c
+++ b/eval.c
@@ -29,7 +29,6 @@
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
-#include <setjmp.h>
#include <stdarg.h>
#include <wchar.h>
#include <signal.h>
diff --git a/filter.c b/filter.c
index 0388ea9f..9a66bb34 100644
--- a/filter.c
+++ b/filter.c
@@ -25,7 +25,6 @@
*/
#include <stddef.h>
-#include <setjmp.h>
#include <string.h>
#include <wctype.h>
#include <wchar.h>
diff --git a/gc.c b/gc.c
index ed8cd04c..7762a3a2 100644
--- a/gc.c
+++ b/gc.c
@@ -28,7 +28,6 @@
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
-#include <setjmp.h>
#include <dirent.h>
#include <wchar.h>
#include <signal.h>
@@ -58,10 +57,10 @@ typedef struct heap {
} heap_t;
typedef struct mach_context {
- jmp_buf buf;
+ struct jmp buf;
} mach_context_t;
-#define save_context(X) setjmp((X).buf)
+#define save_context(X) jmp_save(&(X).buf)
int opt_gc_debug;
#if HAVE_VALGRIND
diff --git a/glob.c b/glob.c
index 58b0d0e9..b3a39d92 100644
--- a/glob.c
+++ b/glob.c
@@ -27,7 +27,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
-#include <setjmp.h>
#include <wchar.h>
#include <signal.h>
#include <glob.h>
diff --git a/hash.c b/hash.c
index 33455f36..d6092efa 100644
--- a/hash.c
+++ b/hash.c
@@ -30,7 +30,6 @@
#include <dirent.h>
#include <stdarg.h>
#include <stdlib.h>
-#include <setjmp.h>
#include <limits.h>
#include <signal.h>
#include "config.h"
diff --git a/jmp.S b/jmp.S
new file mode 100644
index 00000000..9784d5d7
--- /dev/null
+++ b/jmp.S
@@ -0,0 +1,180 @@
+/* Copyright 2009-2015
+ * Kaz Kylheku <kaz@kylheku.com>
+ * Vancouver, Canada
+ * All rights reserved.
+ *
+ * Redistribution of this software in source and binary forms, with or without
+ * modification, is permitted provided that the following two conditions are met.
+ *
+ * Use of this software in any manner constitutes agreement with the disclaimer
+ * which follows the two conditions.
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DAMAGES, HOWEVER CAUSED,
+ * AND UNDER ANY THEORY OF LIABILITY, ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if __MINGW32__ || __CYGWIN32__
+#define DEFUN(NAME) \
+.global _ ## NAME ; \
+_ ## NAME: ;
+#elif __APPLE__
+#define DEFUN(NAME) \
+.globl _ ## NAME ; \
+_ ## NAME: ;
+#elif __arm__ && !__thumb__
+#define DEFUN(NAME) \
+.text ; \
+.align 4 ; \
+.global NAME ; \
+.type NAME, %function ; \
+NAME: ;
+#elif __arm__ && __thumb__
+#define DEFUN(NAME) \
+.text ; \
+.align 4 ; \
+.global NAME ; \
+.thumb ; \
+.thumb_func ; \
+.type NAME, %function ; \
+NAME: ;
+#else
+#define DEFUN(NAME) \
+.global NAME ; \
+.type NAME, @function ; \
+NAME: ;
+#endif
+
+#if __i386__
+
+#define JEIP 0
+#define JESP 4
+#define JEBP 8
+#define JEBX 12
+#define JESI 16
+#define JEDI 20
+
+#define RETA 0
+#define ARG1 4
+#define ARG2 8
+
+DEFUN(jmp_save)
+ movl RETA(%esp), %ecx
+ movl ARG1(%esp), %eax
+ movl %ecx, JEIP(%eax)
+ leal ARG1(%esp), %ecx
+ movl %ecx, JESP(%eax)
+ movl %ebp, JEBP(%eax)
+ movl %ebx, JEBX(%eax)
+ movl %esi, JESI(%eax)
+ movl %edi, JEDI(%eax)
+ xorl %eax, %eax
+ ret
+
+DEFUN(jmp_restore)
+ movl ARG1(%esp), %edx
+ movl ARG2(%esp), %eax
+ mov JEDI(%edx),%edi
+ mov JESI(%edx),%esi
+ mov JEBX(%edx),%ebx
+ mov JEBP(%edx),%ebp
+ mov JESP(%edx),%ecx
+ mov %ecx,%esp
+ mov JEIP(%edx),%ecx
+ jmp *%ecx
+
+#elif __x86_64__
+
+#define JRIP 0
+#define JRSP 8
+#define JRBP 16
+#define JRBX 24
+#define JR12 32
+#define JR13 40
+#define JR14 48
+#define JR15 56
+
+#define RETA 0
+#define ARG2 8
+
+DEFUN(jmp_save)
+ mov RETA(%rsp), %rdx
+ mov %rdx, JRIP(%rdi)
+ lea ARG2(%rsp), %rdx
+ mov %rdx, JRSP(%rdi)
+ mov %rbp, JRBP(%rdi)
+ mov %rbx, JRBX(%rdi)
+ mov %r12, JR12(%rdi)
+ mov %r13, JR13(%rdi)
+ mov %r14, JR14(%rdi)
+ mov %r15, JR15(%rdi)
+ xor %rax, %rax
+ ret
+
+DEFUN(jmp_restore)
+ mov JR15(%rdi), %r15
+ mov JR14(%rdi), %r14
+ mov JR13(%rdi), %r13
+ mov JR12(%rdi), %r12
+ mov JRBX(%rdi), %rbx
+ mov JRBP(%rdi), %rbp
+ mov JRSP(%rdi), %rdx
+ mov %rdx, %rsp
+ mov JRIP(%rdi), %rdx
+ mov %rsi, %rax
+ jmp *%rdx
+
+#elif __arm__ && !__thumb__
+
+DEFUN(jmp_save)
+ stmia r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr}
+ mov r0, #0
+ bx lr
+
+DEFUN(jmp_restore)
+ ldmia r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr}
+ mov r0, r1
+ bx lr
+
+#elif __arm__ && __thumb__
+
+DEFUN(jmp_save)
+ mov r2, r0
+ mov r3, lr
+ stmia r0!, {r3, r4, r5, r6, r7}
+ mov r3, r8
+ mov r4, r9
+ mov r5, r10
+ mov r6, fp
+ mov r7, sp
+ stmia r0!, {r3, r4, r5, r6, r7}
+ ldmia r2!, {r3, r4, r5, r6, r7}
+ mov r0, #0
+ bx lr
+
+DEFUN(jmp_restore)
+ mov r2, r0
+ add r0, #5*4
+ ldmia r0!, {r3, r4, r5, r6, r7}
+ mov r8, r3
+ mov r9, r4
+ mov r10, r5
+ mov fp, r6
+ mov sp, r7
+ ldmia r2!, {r3, r4, r5, r6, r7}
+ mov r0, r1
+ bx r3
+
+#else
+#error port me!
+#endif
diff --git a/lib.c b/lib.c
index 15986952..21f27816 100644
--- a/lib.c
+++ b/lib.c
@@ -32,7 +32,6 @@
#include <limits.h>
#include <stdarg.h>
#include <dirent.h>
-#include <setjmp.h>
#include <errno.h>
#include <wchar.h>
#include <math.h>
diff --git a/match.c b/match.c
index 7a521416..98b35cbc 100644
--- a/match.c
+++ b/match.c
@@ -30,7 +30,6 @@
#include <string.h>
#include <errno.h>
#include <dirent.h>
-#include <setjmp.h>
#include <stdarg.h>
#include <wchar.h>
#include <signal.h>
diff --git a/parser.c b/parser.c
index 9acfa0da..6caa3a41 100644
--- a/parser.c
+++ b/parser.c
@@ -31,7 +31,6 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
-#include <setjmp.h>
#include <wchar.h>
#include <signal.h>
#include <ctype.h>
diff --git a/rand.c b/rand.c
index b127dae0..04c161be 100644
--- a/rand.c
+++ b/rand.c
@@ -31,7 +31,6 @@
#include <limits.h>
#include <stdarg.h>
#include <dirent.h>
-#include <setjmp.h>
#include <wchar.h>
#include <limits.h>
#include <time.h>
diff --git a/regex.c b/regex.c
index 823f0c4e..79692803 100644
--- a/regex.c
+++ b/regex.c
@@ -30,7 +30,6 @@
#include <wchar.h>
#include <assert.h>
#include <dirent.h>
-#include <setjmp.h>
#include <dirent.h>
#include <limits.h>
#include <signal.h>
diff --git a/signal.c b/signal.c
index 05554a64..c3b9a351 100644
--- a/signal.c
+++ b/signal.c
@@ -28,7 +28,6 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
-#include <setjmp.h>
#include <errno.h>
#include <wchar.h>
#include <dirent.h>
diff --git a/signal.h b/signal.h
index 9dc076cd..dc5b44ba 100644
--- a/signal.h
+++ b/signal.h
@@ -40,6 +40,75 @@ extern int debug_depth;
#define EJ_OPT_SAVE(EJB) EJ_DBG_SAVE(EJB)
#define EJ_OPT_REST(EJB) EJ_DBG_REST(EJB)
+#if __i386__
+
+struct jmp {
+ unsigned eip;
+ unsigned esp;
+ unsigned ebp;
+ unsigned ebx;
+ unsigned esi;
+ unsigned edi;
+};
+
+#elif __x86_64__
+
+struct jmp {
+ unsigned long rip;
+ unsigned long rsp;
+ unsigned long rbp;
+ unsigned long rbx;
+ unsigned long r12;
+ unsigned long r13;
+ unsigned long r14;
+ unsigned long r15;
+};
+
+#elif __arm__ && !__thumb__
+
+struct jmp {
+ unsigned long r4;
+ unsigned long r5;
+ unsigned long r6;
+ unsigned long r7;
+ unsigned long r8;
+ unsigned long r9;
+ unsigned long r10;
+ unsigned long fp;
+ unsigned long sp;
+ unsigned long lr;
+};
+
+#elif __arm__ && __thumb__
+
+struct jmp {
+ unsigned long lr;
+ unsigned long r4;
+ unsigned long r5;
+ unsigned long r6;
+ unsigned long r7;
+ unsigned long r8;
+ unsigned long r9;
+ unsigned long r10;
+ unsigned long fp;
+ unsigned long sp;
+};
+
+#else
+#error port me!
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int jmp_save(struct jmp *);
+void jmp_restore(struct jmp *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
#if HAVE_POSIX_SIGS
INLINE void copy_sigset(volatile sigset_t *dest, const sigset_t *src)
@@ -88,7 +157,7 @@ INLINE val sig_check_fast(void)
}
typedef struct {
- jmp_buf jb;
+ struct jmp jb;
volatile sig_atomic_t se;
volatile sigset_t blocked;
volatile val de;
@@ -99,7 +168,7 @@ typedef struct {
} extended_jmp_buf;
#define extended_setjmp(EJB) \
- (setjmp((EJB).jb) \
+ (jmp_save(&(EJB).jb) \
? (async_sig_enabled = (EJB).se, \
dyn_env = (EJB).de, \
gc_enabled = (EJB).gc, \
@@ -119,7 +188,7 @@ typedef struct {
0))
#define extended_longjmp(EJB, ARG) \
- ((EJB).rv = (ARG), longjmp((EJB).jb, 1))
+ ((EJB).rv = (ARG), jmp_restore(&(EJB).jb, 1))
extern sigset_t sig_blocked_cache;
extern volatile sig_atomic_t async_sig_enabled;
@@ -135,7 +204,7 @@ extern volatile sig_atomic_t async_sig_enabled;
#define sig_check_fast() ((void) 0)
typedef struct {
- jmp_buf jb;
+ struct jmp jb;
volatile val de;
volatile int gc;
val **volatile gc_pt;
@@ -144,7 +213,7 @@ typedef struct {
} extended_jmp_buf;
#define extended_setjmp(EJB) \
- (setjmp((EJB).jb) \
+ (jmp_save(&(EJB).jb) \
? (dyn_env = (EJB).de, \
gc_enabled = ((EJB).gc), \
gc_prot_top = (EJB).gc_pt, \
@@ -157,7 +226,7 @@ typedef struct {
0))
#define extended_longjmp(EJB, ARG) \
- ((EJB).rv = (ARG), longjmp((EJB).jb, 1))
+ ((EJB).rv = (ARG), jmp_restore(&(EJB).jb, 1))
extern int async_sig_enabled;
diff --git a/stream.c b/stream.c
index 024591e4..275de1bb 100644
--- a/stream.c
+++ b/stream.c
@@ -30,7 +30,6 @@
#include <dirent.h>
#include <stdarg.h>
#include <stdlib.h>
-#include <setjmp.h>
#include <errno.h>
#include <ctype.h>
#include <wchar.h>
diff --git a/struct.c b/struct.c
index 87f1ebb7..24d65363 100644
--- a/struct.c
+++ b/struct.c
@@ -30,7 +30,6 @@
#include <dirent.h>
#include <stdarg.h>
#include <stdlib.h>
-#include <setjmp.h>
#include <limits.h>
#include <signal.h>
#include "config.h"
diff --git a/sysif.c b/sysif.c
index 1fe92471..b4f2df52 100644
--- a/sysif.c
+++ b/sysif.c
@@ -28,7 +28,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <setjmp.h>
#include <wchar.h>
#include <signal.h>
#include <dirent.h>
diff --git a/syslog.c b/syslog.c
index aa3539c3..275b188e 100644
--- a/syslog.c
+++ b/syslog.c
@@ -28,7 +28,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
-#include <setjmp.h>
#include <wchar.h>
#include <signal.h>
#include <dirent.h>
diff --git a/txr.c b/txr.c
index 36937ffe..f9d20fdb 100644
--- a/txr.c
+++ b/txr.c
@@ -29,7 +29,6 @@
#include <string.h>
#include <limits.h>
#include <dirent.h>
-#include <setjmp.h>
#include <stdarg.h>
#include <wchar.h>
#include <signal.h>
diff --git a/unwind.c b/unwind.c
index 79b9a7fd..0e075306 100644
--- a/unwind.c
+++ b/unwind.c
@@ -29,7 +29,6 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
-#include <setjmp.h>
#include <dirent.h>
#include <stdarg.h>
#include <signal.h>
diff --git a/utf8.c b/utf8.c
index a09e082b..af81e99d 100644
--- a/utf8.c
+++ b/utf8.c
@@ -28,7 +28,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
-#include <setjmp.h>
#include <signal.h>
#include "config.h"
#include "lib.h"