From fcec23a85e2e9936caab8a6251aade019dce5bbd Mon Sep 17 00:00:00 2001 From: Aleksey Demakov Date: Mon, 14 Aug 2006 19:21:19 +0000 Subject: [PATCH] add --enable-signals option and some support for signals --- ChangeLog | 8 ++++ configure.in | 12 ++++++ jit/Makefile.am | 1 + jit/jit-init.c | 5 +++ jit/jit-internal.h | 9 +++++ jit/jit-signal.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 129 insertions(+) create mode 100644 jit/jit-signal.c diff --git a/ChangeLog b/ChangeLog index 68c68bf..4cee899 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-08-15 Kirill Kononenko + + * configure.in: add --enable-signals option; + * jit/Makefile.am: add jit/jit-signal.c; + * jit/jit-signal.c, jit/jit-internal.h: add _jit_signal_init(); + * jit/jit-init.c: call _jit_signal_init() if JIT_USE_SIGNALS is + defined. + 2006-08-11 Thomas Cort * jit/jit-rules-alpha.c jit/jit-rules-alpha.ins Properly handle diff --git a/configure.in b/configure.in index 2f6040c..a9cc86f 100644 --- a/configure.in +++ b/configure.in @@ -75,6 +75,18 @@ if test x$new_reg_alloc = xtrue; then AC_DEFINE(USE_NEW_REG_ALLOC, 1, [Define if you want to use new register allocator]) fi +dnl The "--enable-signals" option forces the use of the OS signals for exception handling. +AC_ARG_ENABLE(signals, +[ --enable-signals Enable OS signal handling], +[case "${enableval}" in + yes) use_signals=true ;; + no) use_signals=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-signals) ;; +esac],[use_signals=false]) +if test x$use_signals = xtrue; then + AC_DEFINE(JIT_USE_SIGNALS, 1, [Define if you want to use the OS signals for exception handling]) +fi + dnl The "--enable-long-double" option forces the use of long double for dnl jit_nfloat. AC_ARG_ENABLE(long-double, diff --git a/jit/Makefile.am b/jit/Makefile.am index 8f84704..5bb4fc6 100644 --- a/jit/Makefile.am +++ b/jit/Makefile.am @@ -52,6 +52,7 @@ libjit_la_SOURCES = \ jit-rules-arm.c \ jit-rules-x86.h \ jit-rules-x86.c \ + jit-signal.c \ jit-string.c \ jit-symbol.c \ jit-thread.c \ diff --git a/jit/jit-init.c b/jit/jit-init.c index 5146d05..c1f8282 100644 --- a/jit/jit-init.c +++ b/jit/jit-init.c @@ -40,6 +40,11 @@ void jit_init(void) /* Make sure that the thread subsystem is initialized */ _jit_thread_init(); +#ifdef JIT_USE_SIGNALS + /* Initialize the signal handlers */ + _jit_signal_init(); +#endif + /* Initialize the backend */ _jit_init_backend(); } diff --git a/jit/jit-internal.h b/jit/jit-internal.h index cece21f..4a30e7d 100644 --- a/jit/jit-internal.h +++ b/jit/jit-internal.h @@ -651,6 +651,15 @@ extern struct _jit_type const _jit_type_void_ptr_def; */ #define JIT_CALL_NATIVE (1 << 14) +#ifdef JIT_USE_SIGNALS + +/* + * Initialize the signal handlers. + */ +void _jit_signal_init(void); + +#endif + #ifdef __cplusplus }; #endif diff --git a/jit/jit-signal.c b/jit/jit-signal.c new file mode 100644 index 0000000..b2a72b6 --- /dev/null +++ b/jit/jit-signal.c @@ -0,0 +1,94 @@ +/* + * jit-signal.c - Internal management routines to use Operating System + * signals for libjit exceptions handling. + * + * Copyright (C) 2006 Southern Storm Software, Pty Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#ifdef JIT_USE_SIGNALS + +#include "jit-internal.h" +#include +#include +#include + +/* + * Use SIGSEGV for builtin libjit exception. + */ +static void sigsegv_handler(int signum, siginfo_t *info, void *uap) +{ + jit_exception_builtin(JIT_RESULT_NULL_REFERENCE); +} + +/* + * Use SIGFPE for builtin libjit exception. + */ +static void sigfpe_handler(int signum, siginfo_t *info, void *uap) +{ + switch(info->si_code) + { + case FPE_INTDIV: + jit_exception_builtin(JIT_RESULT_DIVISION_BY_ZERO); + break; + case FPE_INTOVF: + jit_exception_builtin(JIT_RESULT_OVERFLOW); + break; + case FPE_FLTDIV: + jit_exception_builtin(JIT_RESULT_DIVISION_BY_ZERO); + break; + case FPE_FLTOVF: + jit_exception_builtin(JIT_RESULT_OVERFLOW); + break; + case FPE_FLTUND: + jit_exception_builtin(JIT_RESULT_ARITHMETIC); + break; + case FPE_FLTSUB: + jit_exception_builtin(JIT_RESULT_ARITHMETIC); + break; + default: + jit_exception_builtin(JIT_RESULT_ARITHMETIC); + break; + } +} + +/* + * Initialize signal handlers. + */ +void _jit_signal_init(void) +{ + struct sigaction sa_fpe, sa_segv; + + sa_fpe.sa_sigaction = sigfpe_handler; + sigemptyset(&sa_fpe.sa_mask); + sa_fpe.sa_flags = SA_SIGINFO; + if (sigaction(SIGFPE, &sa_fpe, 0)) { + perror("Sigaction SIGFPE"); + exit(1); + } + + sa_segv.sa_sigaction = sigsegv_handler; + sigemptyset(&sa_segv.sa_mask); + sa_segv.sa_flags = SA_SIGINFO; + if (sigaction(SIGSEGV, &sa_segv, 0)) { + perror("Sigaction SIGSEGV"); + exit(1); + } +} + +#endif /* JIT_USE_SIGNALS */