# HG changeset patch # User Paul Boddie # Date 1548535092 -3600 # Node ID c77216b79bebf428513d0a51b3754ad88e6d29ab # Parent c33b256b12705721d425d1b6e153afd65969c4b7 Generate floating point exceptions directly from the signal handler. diff -r c33b256b1270 -r c77216b79beb templates/native/float.c --- a/templates/native/float.c Sat Jan 26 01:04:34 2019 +0100 +++ b/templates/native/float.c Sat Jan 26 21:38:12 2019 +0100 @@ -16,8 +16,6 @@ this program. If not, see . */ -#include -#include #include /* pow */ #include /* snprintf */ #include /* errno */ @@ -65,29 +63,14 @@ return __NULL; } -/* Floating point exception handling. */ - -extern jmp_buf __fpe_env; - -/* Floating point operations. */ +/* Floating point operations. Exceptions are raised in the signal handler. */ __attr __fn_native_float_float_add(__attr __self, __attr self, __attr other) { /* self and other interpreted as float */ double i = __TOFLOAT(self); double j = __TOFLOAT(other); - int signum; - - /* Perform the operation while handling exceptions. */ - signum = setjmp(__fpe_env); - if (!signum) - return __new_float(i + j); - - /* Exception occurred. */ - if (signum == FPE_FLTOVF) - __raise_overflow_error(); - - return __NULL; + return __new_float(i + j); } __attr __fn_native_float_float_sub(__attr __self, __attr self, __attr other) @@ -95,18 +78,7 @@ /* self and other interpreted as float */ double i = __TOFLOAT(self); double j = __TOFLOAT(other); - int signum; - - /* Perform the operation while handling exceptions. */ - signum = setjmp(__fpe_env); - if (!signum) - return __new_float(i - j); - - /* Exception occurred. */ - if (signum == FPE_FLTOVF) - __raise_overflow_error(); - - return __NULL; + return __new_float(i - j); } __attr __fn_native_float_float_mul(__attr __self, __attr self, __attr other) @@ -114,20 +86,7 @@ /* self and other interpreted as float */ double i = __TOFLOAT(self); double j = __TOFLOAT(other); - int signum; - - /* Perform the operation while handling exceptions. */ - signum = setjmp(__fpe_env); - if (!signum) - return __new_float(i * j); - - /* Exception occurred. */ - if (signum == FPE_FLTOVF) - __raise_overflow_error(); - else if (signum == FPE_FLTUND) - __raise_underflow_error(); - - return __NULL; + return __new_float(i * j); } __attr __fn_native_float_float_div(__attr __self, __attr self, __attr other) @@ -135,22 +94,7 @@ /* self and other interpreted as float */ double i = __TOFLOAT(self); double j = __TOFLOAT(other); - int signum; - - /* Perform the operation while handling exceptions. */ - signum = setjmp(__fpe_env); - if (!signum) - return __new_float(i / j); - - /* Exception occurred. */ - if (signum == FPE_FLTOVF) - __raise_overflow_error(); - else if (signum == FPE_FLTUND) - __raise_underflow_error(); - else if (signum == FPE_FLTDIV) - __raise_zero_division_error(); - - return __NULL; + return __new_float(i / j); } __attr __fn_native_float_float_mod(__attr __self, __attr self, __attr other) @@ -158,38 +102,14 @@ /* self and other interpreted as float */ double i = __TOFLOAT(self); double j = __TOFLOAT(other); - int signum; - - /* Perform the operation while handling exceptions. */ - signum = setjmp(__fpe_env); - if (!signum) - return __new_float(fmod(i, j)); - - /* Exception occurred. */ - if (signum == FPE_FLTOVF) - __raise_overflow_error(); - else if (signum == FPE_FLTDIV) - __raise_zero_division_error(); - - return __NULL; + return __new_float(fmod(i, j)); } __attr __fn_native_float_float_neg(__attr __self, __attr self) { /* self interpreted as float */ double i = __TOFLOAT(self); - int signum; - - /* Perform the operation while handling exceptions. */ - signum = setjmp(__fpe_env); - if (!signum) - return __new_float(-i); - - /* Exception occurred. */ - if (signum == FPE_FLTOVF) - __raise_overflow_error(); - - return __NULL; + return __new_float(-i); } __attr __fn_native_float_float_pow(__attr __self, __attr self, __attr other) diff -r c33b256b1270 -r c77216b79beb templates/progops.c --- a/templates/progops.c Sat Jan 26 01:04:34 2019 +0100 +++ b/templates/progops.c Sat Jan 26 21:38:12 2019 +0100 @@ -1,6 +1,6 @@ /* Operations depending on program specifics. -Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie +Copyright (C) 2015, 2016, 2017, 2018, 2019 Paul Boddie 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 @@ -127,6 +127,11 @@ #endif /* __HAVE___builtins___exception_io_EOFError */ } +void __raise_floating_point_error() +{ + __Raise(__new___builtins___core_FloatingPointError(__NULL)); +} + void __raise_io_error(__attr value) { #ifdef __HAVE___builtins___exception_io_IOError diff -r c33b256b1270 -r c77216b79beb templates/progops.h --- a/templates/progops.h Sat Jan 26 01:04:34 2019 +0100 +++ b/templates/progops.h Sat Jan 26 21:38:12 2019 +0100 @@ -1,6 +1,6 @@ /* Operations depending on program specifics. -Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie +Copyright (C) 2015, 2016, 2017, 2018, 2019 Paul Boddie 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 @@ -48,6 +48,7 @@ /* Helpers for raising errors within common operations. */ void __raise_eof_error(); +void __raise_floating_point_error(); void __raise_io_error(__attr value); void __raise_memory_error(); void __raise_os_error(__attr value, __attr arg); diff -r c33b256b1270 -r c77216b79beb templates/signals.c --- a/templates/signals.c Sat Jan 26 01:04:34 2019 +0100 +++ b/templates/signals.c Sat Jan 26 21:38:12 2019 +0100 @@ -16,11 +16,11 @@ this program. If not, see . */ -#include #include #include #include "signals.h" +#include "progops.h" void __signals_install_handlers() { @@ -35,11 +35,26 @@ sigaction(SIGFPE, &context, NULL); } -jmp_buf __fpe_env; - void __signals_fpe_handler(int signum, siginfo_t *siginfo, void *context) { - /* Return from setjmp with the signal number. */ + /* Return from setjmp using the signal number. */ + + switch (siginfo->si_code) + { + case FPE_FLTOVF: + __raise_overflow_error(); + break; - longjmp(__fpe_env, siginfo->si_code); + case FPE_FLTUND: + __raise_underflow_error(); + break; + + case FPE_FLTDIV: + __raise_zero_division_error(); + break; + + default: + __raise_floating_point_error(); + break; + } }