1.1 --- a/templates/native/float.c Sat Jan 26 01:04:34 2019 +0100
1.2 +++ b/templates/native/float.c Sat Jan 26 21:38:12 2019 +0100
1.3 @@ -16,8 +16,6 @@
1.4 this program. If not, see <http://www.gnu.org/licenses/>.
1.5 */
1.6
1.7 -#include <setjmp.h>
1.8 -#include <signal.h>
1.9 #include <math.h> /* pow */
1.10 #include <stdio.h> /* snprintf */
1.11 #include <errno.h> /* errno */
1.12 @@ -65,29 +63,14 @@
1.13 return __NULL;
1.14 }
1.15
1.16 -/* Floating point exception handling. */
1.17 -
1.18 -extern jmp_buf __fpe_env;
1.19 -
1.20 -/* Floating point operations. */
1.21 +/* Floating point operations. Exceptions are raised in the signal handler. */
1.22
1.23 __attr __fn_native_float_float_add(__attr __self, __attr self, __attr other)
1.24 {
1.25 /* self and other interpreted as float */
1.26 double i = __TOFLOAT(self);
1.27 double j = __TOFLOAT(other);
1.28 - int signum;
1.29 -
1.30 - /* Perform the operation while handling exceptions. */
1.31 - signum = setjmp(__fpe_env);
1.32 - if (!signum)
1.33 - return __new_float(i + j);
1.34 -
1.35 - /* Exception occurred. */
1.36 - if (signum == FPE_FLTOVF)
1.37 - __raise_overflow_error();
1.38 -
1.39 - return __NULL;
1.40 + return __new_float(i + j);
1.41 }
1.42
1.43 __attr __fn_native_float_float_sub(__attr __self, __attr self, __attr other)
1.44 @@ -95,18 +78,7 @@
1.45 /* self and other interpreted as float */
1.46 double i = __TOFLOAT(self);
1.47 double j = __TOFLOAT(other);
1.48 - int signum;
1.49 -
1.50 - /* Perform the operation while handling exceptions. */
1.51 - signum = setjmp(__fpe_env);
1.52 - if (!signum)
1.53 - return __new_float(i - j);
1.54 -
1.55 - /* Exception occurred. */
1.56 - if (signum == FPE_FLTOVF)
1.57 - __raise_overflow_error();
1.58 -
1.59 - return __NULL;
1.60 + return __new_float(i - j);
1.61 }
1.62
1.63 __attr __fn_native_float_float_mul(__attr __self, __attr self, __attr other)
1.64 @@ -114,20 +86,7 @@
1.65 /* self and other interpreted as float */
1.66 double i = __TOFLOAT(self);
1.67 double j = __TOFLOAT(other);
1.68 - int signum;
1.69 -
1.70 - /* Perform the operation while handling exceptions. */
1.71 - signum = setjmp(__fpe_env);
1.72 - if (!signum)
1.73 - return __new_float(i * j);
1.74 -
1.75 - /* Exception occurred. */
1.76 - if (signum == FPE_FLTOVF)
1.77 - __raise_overflow_error();
1.78 - else if (signum == FPE_FLTUND)
1.79 - __raise_underflow_error();
1.80 -
1.81 - return __NULL;
1.82 + return __new_float(i * j);
1.83 }
1.84
1.85 __attr __fn_native_float_float_div(__attr __self, __attr self, __attr other)
1.86 @@ -135,22 +94,7 @@
1.87 /* self and other interpreted as float */
1.88 double i = __TOFLOAT(self);
1.89 double j = __TOFLOAT(other);
1.90 - int signum;
1.91 -
1.92 - /* Perform the operation while handling exceptions. */
1.93 - signum = setjmp(__fpe_env);
1.94 - if (!signum)
1.95 - return __new_float(i / j);
1.96 -
1.97 - /* Exception occurred. */
1.98 - if (signum == FPE_FLTOVF)
1.99 - __raise_overflow_error();
1.100 - else if (signum == FPE_FLTUND)
1.101 - __raise_underflow_error();
1.102 - else if (signum == FPE_FLTDIV)
1.103 - __raise_zero_division_error();
1.104 -
1.105 - return __NULL;
1.106 + return __new_float(i / j);
1.107 }
1.108
1.109 __attr __fn_native_float_float_mod(__attr __self, __attr self, __attr other)
1.110 @@ -158,38 +102,14 @@
1.111 /* self and other interpreted as float */
1.112 double i = __TOFLOAT(self);
1.113 double j = __TOFLOAT(other);
1.114 - int signum;
1.115 -
1.116 - /* Perform the operation while handling exceptions. */
1.117 - signum = setjmp(__fpe_env);
1.118 - if (!signum)
1.119 - return __new_float(fmod(i, j));
1.120 -
1.121 - /* Exception occurred. */
1.122 - if (signum == FPE_FLTOVF)
1.123 - __raise_overflow_error();
1.124 - else if (signum == FPE_FLTDIV)
1.125 - __raise_zero_division_error();
1.126 -
1.127 - return __NULL;
1.128 + return __new_float(fmod(i, j));
1.129 }
1.130
1.131 __attr __fn_native_float_float_neg(__attr __self, __attr self)
1.132 {
1.133 /* self interpreted as float */
1.134 double i = __TOFLOAT(self);
1.135 - int signum;
1.136 -
1.137 - /* Perform the operation while handling exceptions. */
1.138 - signum = setjmp(__fpe_env);
1.139 - if (!signum)
1.140 - return __new_float(-i);
1.141 -
1.142 - /* Exception occurred. */
1.143 - if (signum == FPE_FLTOVF)
1.144 - __raise_overflow_error();
1.145 -
1.146 - return __NULL;
1.147 + return __new_float(-i);
1.148 }
1.149
1.150 __attr __fn_native_float_float_pow(__attr __self, __attr self, __attr other)
2.1 --- a/templates/progops.c Sat Jan 26 01:04:34 2019 +0100
2.2 +++ b/templates/progops.c Sat Jan 26 21:38:12 2019 +0100
2.3 @@ -1,6 +1,6 @@
2.4 /* Operations depending on program specifics.
2.5
2.6 -Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
2.7 +Copyright (C) 2015, 2016, 2017, 2018, 2019 Paul Boddie <paul@boddie.org.uk>
2.8
2.9 This program is free software; you can redistribute it and/or modify it under
2.10 the terms of the GNU General Public License as published by the Free Software
2.11 @@ -127,6 +127,11 @@
2.12 #endif /* __HAVE___builtins___exception_io_EOFError */
2.13 }
2.14
2.15 +void __raise_floating_point_error()
2.16 +{
2.17 + __Raise(__new___builtins___core_FloatingPointError(__NULL));
2.18 +}
2.19 +
2.20 void __raise_io_error(__attr value)
2.21 {
2.22 #ifdef __HAVE___builtins___exception_io_IOError
3.1 --- a/templates/progops.h Sat Jan 26 01:04:34 2019 +0100
3.2 +++ b/templates/progops.h Sat Jan 26 21:38:12 2019 +0100
3.3 @@ -1,6 +1,6 @@
3.4 /* Operations depending on program specifics.
3.5
3.6 -Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
3.7 +Copyright (C) 2015, 2016, 2017, 2018, 2019 Paul Boddie <paul@boddie.org.uk>
3.8
3.9 This program is free software; you can redistribute it and/or modify it under
3.10 the terms of the GNU General Public License as published by the Free Software
3.11 @@ -48,6 +48,7 @@
3.12 /* Helpers for raising errors within common operations. */
3.13
3.14 void __raise_eof_error();
3.15 +void __raise_floating_point_error();
3.16 void __raise_io_error(__attr value);
3.17 void __raise_memory_error();
3.18 void __raise_os_error(__attr value, __attr arg);
4.1 --- a/templates/signals.c Sat Jan 26 01:04:34 2019 +0100
4.2 +++ b/templates/signals.c Sat Jan 26 21:38:12 2019 +0100
4.3 @@ -16,11 +16,11 @@
4.4 this program. If not, see <http://www.gnu.org/licenses/>.
4.5 */
4.6
4.7 -#include <setjmp.h>
4.8 #include <signal.h>
4.9 #include <stdlib.h>
4.10
4.11 #include "signals.h"
4.12 +#include "progops.h"
4.13
4.14 void __signals_install_handlers()
4.15 {
4.16 @@ -35,11 +35,26 @@
4.17 sigaction(SIGFPE, &context, NULL);
4.18 }
4.19
4.20 -jmp_buf __fpe_env;
4.21 -
4.22 void __signals_fpe_handler(int signum, siginfo_t *siginfo, void *context)
4.23 {
4.24 - /* Return from setjmp with the signal number. */
4.25 + /* Return from setjmp using the signal number. */
4.26 +
4.27 + switch (siginfo->si_code)
4.28 + {
4.29 + case FPE_FLTOVF:
4.30 + __raise_overflow_error();
4.31 + break;
4.32
4.33 - longjmp(__fpe_env, siginfo->si_code);
4.34 + case FPE_FLTUND:
4.35 + __raise_underflow_error();
4.36 + break;
4.37 +
4.38 + case FPE_FLTDIV:
4.39 + __raise_zero_division_error();
4.40 + break;
4.41 +
4.42 + default:
4.43 + __raise_floating_point_error();
4.44 + break;
4.45 + }
4.46 }