aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-05-04 23:31:14 -0700
committerPaul Eggert2011-05-04 23:31:14 -0700
commitc717b32678affe3864f0d5024a9de514c950214d (patch)
tree5e682fb44780734c00be9a203499b7a8651e560c /src
parent852a74a59b12d505eba86a0aed46bfe8af7b9acf (diff)
downloademacs-c717b32678affe3864f0d5024a9de514c950214d.tar.gz
emacs-c717b32678affe3864f0d5024a9de514c950214d.zip
Revert to wraparound integer arithmetic, instead of going to float.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog10
-rw-r--r--src/bytecode.c6
-rw-r--r--src/data.c126
-rw-r--r--src/floatfns.c46
4 files changed, 66 insertions, 122 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index ee2db310562..2b4f498a0b9 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -11,16 +11,6 @@
11 11
12 * term.c: Don't include <stdarg.h>, as <lisp.h> does that. 12 * term.c: Don't include <stdarg.h>, as <lisp.h> does that.
13 13
14 Arithmetic overflows now return float rather than wrapping around.
15 (Bug#8611).
16 * data.c: Include <intprops.h>.
17 (arith_driver): Use floating point if the accumulator would otherwise
18 go out of EMACS_INT range.
19 (arith_driver, Fadd1, Fsub1): Use floating point if the result is
20 out of Emacs fixnum range.
21 * bytecode.c (exec_byte_code): Likewise, for Bsub1, Badd1, Bnegate.
22 * floatfns.c (Fexpt): Likewise.
23
24 * callproc.c (Fcall_process): Use 'volatile' to avoid vfork clobbering. 14 * callproc.c (Fcall_process): Use 'volatile' to avoid vfork clobbering.
25 15
26 * process.c (Fformat_network_address): Fix typo: args2 -> *args2. 16 * process.c (Fformat_network_address): Fix typo: args2 -> *args2.
diff --git a/src/bytecode.c b/src/bytecode.c
index ce79b011bbb..c3cd3d43072 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -1186,7 +1186,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1186 { 1186 {
1187 Lisp_Object v1; 1187 Lisp_Object v1;
1188 v1 = TOP; 1188 v1 = TOP;
1189 if (INTEGERP (v1) && MOST_NEGATIVE_FIXNUM < XINT (v1)) 1189 if (INTEGERP (v1))
1190 { 1190 {
1191 XSETINT (v1, XINT (v1) - 1); 1191 XSETINT (v1, XINT (v1) - 1);
1192 TOP = v1; 1192 TOP = v1;
@@ -1204,7 +1204,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1204 { 1204 {
1205 Lisp_Object v1; 1205 Lisp_Object v1;
1206 v1 = TOP; 1206 v1 = TOP;
1207 if (INTEGERP (v1) && XINT (v1) < MOST_POSITIVE_FIXNUM) 1207 if (INTEGERP (v1))
1208 { 1208 {
1209 XSETINT (v1, XINT (v1) + 1); 1209 XSETINT (v1, XINT (v1) + 1);
1210 TOP = v1; 1210 TOP = v1;
@@ -1290,7 +1290,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1290 { 1290 {
1291 Lisp_Object v1; 1291 Lisp_Object v1;
1292 v1 = TOP; 1292 v1 = TOP;
1293 if (INTEGERP (v1) && - MOST_POSITIVE_FIXNUM <= XINT (v1)) 1293 if (INTEGERP (v1))
1294 { 1294 {
1295 XSETINT (v1, - XINT (v1)); 1295 XSETINT (v1, - XINT (v1));
1296 TOP = v1; 1296 TOP = v1;
diff --git a/src/data.c b/src/data.c
index beff570d552..577ae777d89 100644
--- a/src/data.c
+++ b/src/data.c
@@ -22,9 +22,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#include <signal.h> 22#include <signal.h>
23#include <stdio.h> 23#include <stdio.h>
24#include <setjmp.h> 24#include <setjmp.h>
25
26#include <intprops.h>
27
28#include "lisp.h" 25#include "lisp.h"
29#include "puresize.h" 26#include "puresize.h"
30#include "character.h" 27#include "character.h"
@@ -2429,8 +2426,10 @@ static Lisp_Object float_arith_driver (double, size_t, enum arithop,
2429static Lisp_Object 2426static Lisp_Object
2430arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args) 2427arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)
2431{ 2428{
2429 register Lisp_Object val;
2432 register size_t argnum; 2430 register size_t argnum;
2433 register EMACS_INT accum = 0; 2431 register EMACS_INT accum = 0;
2432 register EMACS_INT next;
2434 2433
2435 switch (SWITCH_ENUM_CAST (code)) 2434 switch (SWITCH_ENUM_CAST (code))
2436 { 2435 {
@@ -2452,89 +2451,58 @@ arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)
2452 2451
2453 for (argnum = 0; argnum < nargs; argnum++) 2452 for (argnum = 0; argnum < nargs; argnum++)
2454 { 2453 {
2455 EMACS_INT a = accum;
2456 int use_float = 0;
2457
2458 /* Using args[argnum] as argument to CHECK_NUMBER_... */ 2454 /* Using args[argnum] as argument to CHECK_NUMBER_... */
2459 Lisp_Object val = args[argnum]; 2455 val = args[argnum];
2460 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val); 2456 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val);
2461 args[argnum] = val;
2462 2457
2463 if (FLOATP (val)) 2458 if (FLOATP (val))
2464 use_float = 1; 2459 return float_arith_driver ((double) accum, argnum, code,
2465 else 2460 nargs, args);
2461 args[argnum] = val;
2462 next = XINT (args[argnum]);
2463 switch (SWITCH_ENUM_CAST (code))
2466 { 2464 {
2467 EMACS_INT next = XINT (val); 2465 case Aadd:
2468 switch (SWITCH_ENUM_CAST (code)) 2466 accum += next;
2467 break;
2468 case Asub:
2469 accum = argnum ? accum - next : nargs == 1 ? - next : next;
2470 break;
2471 case Amult:
2472 accum *= next;
2473 break;
2474 case Adiv:
2475 if (!argnum)
2476 accum = next;
2477 else
2469 { 2478 {
2470 case Aadd: 2479 if (next == 0)
2471 if (next < 0 2480 xsignal0 (Qarith_error);
2472 ? a < TYPE_MINIMUM (EMACS_INT) - next 2481 accum /= next;
2473 : TYPE_MAXIMUM (EMACS_INT) - next < a)
2474 use_float = 1;
2475 else
2476 a += next;
2477 break;
2478 case Asub:
2479 if (argnum == 0 && nargs != 1)
2480 a = next;
2481 else if (next < 0
2482 ? TYPE_MAXIMUM (EMACS_INT) + next < a
2483 : a < TYPE_MINIMUM (EMACS_INT) + next)
2484 use_float = 1;
2485 else
2486 a -= next;
2487 break;
2488 case Amult:
2489 if (next < 0
2490 ? (a < 0
2491 ? a < TYPE_MAXIMUM (EMACS_INT) / next
2492 : next != -1 && TYPE_MINIMUM (EMACS_INT) / next < a)
2493 : (next != 0
2494 && (a < 0
2495 ? a < TYPE_MINIMUM (EMACS_INT) / next
2496 : TYPE_MAXIMUM (EMACS_INT) / next < a)))
2497 use_float = 1;
2498 else
2499 a *= next;
2500 break;
2501 case Adiv:
2502 if (!argnum)
2503 a = next;
2504 else
2505 {
2506 if (next == 0)
2507 xsignal0 (Qarith_error);
2508 a /= next;
2509 }
2510 break;
2511 case Alogand:
2512 a &= next;
2513 break;
2514 case Alogior:
2515 a |= next;
2516 break;
2517 case Alogxor:
2518 a ^= next;
2519 break;
2520 case Amax:
2521 if (!argnum || a < next)
2522 a = next;
2523 break;
2524 case Amin:
2525 if (!argnum || next < a)
2526 a = next;
2527 break;
2528 } 2482 }
2483 break;
2484 case Alogand:
2485 accum &= next;
2486 break;
2487 case Alogior:
2488 accum |= next;
2489 break;
2490 case Alogxor:
2491 accum ^= next;
2492 break;
2493 case Amax:
2494 if (!argnum || next > accum)
2495 accum = next;
2496 break;
2497 case Amin:
2498 if (!argnum || next < accum)
2499 accum = next;
2500 break;
2529 } 2501 }
2530
2531 if (use_float)
2532 return float_arith_driver (accum, argnum, code, nargs, args);
2533
2534 accum = a;
2535 } 2502 }
2536 2503
2537 return make_fixnum_or_float (accum); 2504 XSETINT (val, accum);
2505 return val;
2538} 2506}
2539 2507
2540#undef isnan 2508#undef isnan
@@ -2809,8 +2777,7 @@ Markers are converted to integers. */)
2809 2777
2810 if (FLOATP (number)) 2778 if (FLOATP (number))
2811 return (make_float (1.0 + XFLOAT_DATA (number))); 2779 return (make_float (1.0 + XFLOAT_DATA (number)));
2812 if (XINT (number) + 1 == MOST_POSITIVE_FIXNUM + 1) 2780
2813 return make_float (XINT (number) + 1);
2814 XSETINT (number, XINT (number) + 1); 2781 XSETINT (number, XINT (number) + 1);
2815 return number; 2782 return number;
2816} 2783}
@@ -2824,8 +2791,7 @@ Markers are converted to integers. */)
2824 2791
2825 if (FLOATP (number)) 2792 if (FLOATP (number))
2826 return (make_float (-1.0 + XFLOAT_DATA (number))); 2793 return (make_float (-1.0 + XFLOAT_DATA (number)));
2827 if (XINT (number) - 1 == MOST_NEGATIVE_FIXNUM - 1) 2794
2828 return make_float (XINT (number) - 1);
2829 XSETINT (number, XINT (number) - 1); 2795 XSETINT (number, XINT (number) - 1);
2830 return number; 2796 return number;
2831} 2797}
diff --git a/src/floatfns.c b/src/floatfns.c
index 5c286772864..1232fc0afa1 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -491,39 +491,27 @@ DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0,
491 y = XINT (arg2); 491 y = XINT (arg2);
492 acc = 1; 492 acc = 1;
493 493
494 if ((x == 0 && y != 0) || x == 1 || (x == -1 && (y & 1))) 494 if (y < 0)
495 return arg1;
496 if (x == -1)
497 y = 0;
498
499 while (1)
500 { 495 {
501 if (y & 1) 496 if (x == 1)
502 { 497 acc = 1;
503 if (x < 0 498 else if (x == -1)
504 ? (acc < 0 499 acc = (y & 1) ? -1 : 1;
505 ? acc < MOST_POSITIVE_FIXNUM / x 500 else
506 : MOST_NEGATIVE_FIXNUM / x < acc) 501 acc = 0;
507 : (acc < 0 502 }
508 ? acc < MOST_NEGATIVE_FIXNUM / x 503 else
509 : MOST_POSITIVE_FIXNUM / x < acc)) 504 {
510 break; 505 while (y > 0)
511 acc *= x;
512 }
513
514 y >>= 1;
515 if (y == 0)
516 { 506 {
517 XSETINT (val, acc); 507 if (y & 1)
518 return val; 508 acc *= x;
509 x *= x;
510 y = (unsigned)y >> 1;
519 } 511 }
520
521 if (x < 0
522 ? x < MOST_POSITIVE_FIXNUM / x
523 : MOST_POSITIVE_FIXNUM / x < x)
524 break;
525 x *= x;
526 } 512 }
513 XSETINT (val, acc);
514 return val;
527 } 515 }
528 f1 = FLOATP (arg1) ? XFLOAT_DATA (arg1) : XINT (arg1); 516 f1 = FLOATP (arg1) ? XFLOAT_DATA (arg1) : XINT (arg1);
529 f2 = FLOATP (arg2) ? XFLOAT_DATA (arg2) : XINT (arg2); 517 f2 = FLOATP (arg2) ? XFLOAT_DATA (arg2) : XINT (arg2);