diff options
-rw-r--r-- | generic/tclExecute.c | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 6705193..bc39f01 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclExecute.c,v 1.212 2005/10/14 14:38:11 kennykb Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.213 2005/10/14 15:57:48 dgp Exp $ */ #include "tclInt.h" @@ -1123,48 +1123,64 @@ TclIncrObj(interp, valuePtr, incrPtr) Tcl_Panic("shared object passed to TclIncrObj"); } - if (valuePtr->typePtr == &tclIntType - && incrPtr->typePtr == &tclIntType) { - long augend = valuePtr->internalRep.longValue; - long addend = incrPtr->internalRep.longValue; + if (GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) { + /* Produce error message (reparse?!) */ + return Tcl_GetIntFromObj(interp, valuePtr, &type1); + } + if (GetNumberFromObj(NULL, incrPtr, &ptr2, &type2) != TCL_OK) { + /* Produce error message (reparse?!) */ + Tcl_GetIntFromObj(interp, incrPtr, &type1); + Tcl_AddErrorInfo(interp, "\n (reading increment)"); + return TCL_ERROR; + } + + if ((type1 == TCL_NUMBER_LONG) && (type2 == TCL_NUMBER_LONG)) { + long augend = *((CONST long *)ptr1); + long addend = *((CONST long *)ptr2); long sum = augend + addend; /* Test for overflow */ if ((augend >= 0 || addend >= 0 || sum < 0) - && (augend < 0 || addend < 0 || sum >= 0)) { - TclSetIntObj(valuePtr, sum); + && (sum >= 0 || addend < 0 || augend < 0)) { + TclSetLongObj(valuePtr, sum); return TCL_OK; } +#ifndef TCL_WIDE_INT_IS_LONG + { + Tcl_WideInt w1 = (Tcl_WideInt)augend; + Tcl_WideInt w2 = (Tcl_WideInt)addend; + /* We know the sum value is outside the long range, + * so we use the macro form that doesn't range test again */ + TclSetWideIntObj(valuePtr, w1 + w2); + return TCL_OK; + } +#endif } - if ((GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) - || (type1 == TCL_NUMBER_DOUBLE) || (type1 == TCL_NUMBER_NAN)) { + if ((type1 == TCL_NUMBER_DOUBLE) || (type1 == TCL_NUMBER_NAN)) { /* Produce error message (reparse?!) */ return Tcl_GetIntFromObj(interp, valuePtr, &type1); } - if ((GetNumberFromObj(NULL, incrPtr, &ptr2, &type2) != TCL_OK) - || (type1 == TCL_NUMBER_DOUBLE) || (type1 == TCL_NUMBER_NAN)) { + if ((type1 == TCL_NUMBER_DOUBLE) || (type1 == TCL_NUMBER_NAN)) { /* Produce error message (reparse?!) */ Tcl_GetIntFromObj(interp, incrPtr, &type1); Tcl_AddErrorInfo(interp, "\n (reading increment)"); return TCL_ERROR; } + +#ifndef NO_WIDE_TYPE if ((type1 != TCL_NUMBER_BIG) && (type2 != TCL_NUMBER_BIG)) { Tcl_WideInt w1, w2, sum; TclGetWideIntFromObj(NULL, valuePtr, &w1); TclGetWideIntFromObj(NULL, incrPtr, &w2); sum = w1 + w2; -#ifndef NO_WIDE_TYPE - if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE)) -#endif - { - /* Check for overflow */ - if ((w1 >= 0 || w2 >= 0 || sum < 0) - && (w1 < 0 || w2 < 0 || sum >= 0)) { - Tcl_SetWideIntObj(valuePtr, sum); - return TCL_OK; - } - } + /* Check for overflow */ + if ((w1 >= 0 || w2 >= 0 || sum < 0) + && (w1 < 0 || w2 < 0 || sum >= 0)) { + Tcl_SetWideIntObj(valuePtr, sum); + return TCL_OK; + } } +#endif Tcl_GetBignumAndClearObj(interp, valuePtr, &value); Tcl_GetBignumFromObj(interp, incrPtr, &incr); @@ -2498,7 +2514,7 @@ TclExecuteByteCode(interp, codePtr) /* Test for overflow */ if ((augend >= 0 || addend >= 0 || sum < 0) && (augend < 0 || addend < 0 || sum >= 0)) { - TclSetIntObj(objResultPtr, sum); + TclSetLongObj(objResultPtr, sum); goto doneIncr; } } |