diff options
author | dgp <dgp@users.sourceforge.net> | 2007-07-01 17:31:20 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2007-07-01 17:31:20 (GMT) |
commit | b7b7a76f55e9cf3a0233401d12077c2a4c02fb58 (patch) | |
tree | d4026023af8a692acd7041d3afcf6c32c771d3ce /generic/tclExecute.c | |
parent | d4a8765b8fddb5229749b15cac181af631f9e3a6 (diff) | |
download | tcl-b7b7a76f55e9cf3a0233401d12077c2a4c02fb58.zip tcl-b7b7a76f55e9cf3a0233401d12077c2a4c02fb58.tar.gz tcl-b7b7a76f55e9cf3a0233401d12077c2a4c02fb58.tar.bz2 |
merge updates from HEAD
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r-- | generic/tclExecute.c | 238 |
1 files changed, 1 insertions, 237 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index eb6096f..8a05056 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.285.2.10 2007/06/27 01:37:43 dgp Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.285.2.11 2007/07/01 17:31:23 dgp Exp $ */ #include "tclInt.h" @@ -4949,242 +4949,6 @@ TclExecuteByteCode( } } -#if 0 -/* - * Macro to read a string containing either a wide or an int and decide which - * it is while decoding it at the same time. This enforces the policy that - * integer constants between LONG_MIN and LONG_MAX (inclusive) are represented - * by normal longs, and integer constants outside that range are represented - * by wide ints. - */ - -#define REQUIRE_WIDE_OR_INT(resultVar, objPtr, longVar, wideVar) \ - (resultVar) = Tcl_GetWideIntFromObj(interp, (objPtr), &(wideVar)); \ - if ((resultVar) == TCL_OK && (wideVar) >= Tcl_LongAsWide(LONG_MIN) \ - && (wideVar) <= Tcl_LongAsWide(LONG_MAX)) { \ - (objPtr)->typePtr = &tclIntType; \ - (objPtr)->internalRep.longValue = (longVar) \ - = Tcl_WideAsLong(wideVar); \ - } - -#define W0 Tcl_LongAsWide(0) -/* - * For tracing that uses wide values. - */ -#define LLD "%" TCL_LL_MODIFIER "d" - case INST_MOD: { - /* - * Only integers are allowed. We compute value op value2. - */ - - long i = 0, i2 = 0, rem, neg_divisor = 0; - long iResult = 0; /* Init. avoids compiler warning. */ - Tcl_WideInt w, w2, wResult = W0; - int doWide = 0; - Tcl_Obj *valuePtr, *value2Ptr; - - value2Ptr = OBJ_AT_TOS; - valuePtr = OBJ_UNDER_TOS; - if (valuePtr->typePtr == &tclIntType) { - i = valuePtr->internalRep.longValue; - } else if (valuePtr->typePtr == &tclWideIntType) { - TclGetWide(w,valuePtr); - } else { /* try to convert to int */ - REQUIRE_WIDE_OR_INT(result, valuePtr, i, w); - if (result != TCL_OK) { - TRACE(("%.20s %.20s => ILLEGAL 1st TYPE %s\n", - O2S(valuePtr), O2S(value2Ptr), - (valuePtr->typePtr? - valuePtr->typePtr->name : "null"))); - IllegalExprOperandType(interp, pc, valuePtr); - goto checkForCatch; - } - } - if (value2Ptr->typePtr == &tclIntType) { - i2 = value2Ptr->internalRep.longValue; - } else if (value2Ptr->typePtr == &tclWideIntType) { - TclGetWide(w2,value2Ptr); - } else { - REQUIRE_WIDE_OR_INT(result, value2Ptr, i2, w2); - if (result != TCL_OK) { - TRACE(("%.20s %.20s => ILLEGAL 2nd TYPE %s\n", - O2S(valuePtr), O2S(value2Ptr), - (value2Ptr->typePtr? - value2Ptr->typePtr->name : "null"))); - IllegalExprOperandType(interp, pc, value2Ptr); - goto checkForCatch; - } - } - - do { - /* - * This code is tricky: C doesn't guarantee much about the - * quotient or remainder, and results with a negative divisor are - * not specified. Tcl guarantees that the remainder will have the - * same sign as the divisor and a smaller absolute value. - */ - - if (value2Ptr->typePtr == &tclWideIntType && w2 == W0) { - if (valuePtr->typePtr == &tclIntType) { - TRACE(("%ld "LLD" => DIVIDE BY ZERO\n", i, w2)); - } else { - TRACE((LLD" "LLD" => DIVIDE BY ZERO\n", w, w2)); - } - goto divideByZero; - } - if (value2Ptr->typePtr == &tclIntType && i2 == 0) { - if (valuePtr->typePtr == &tclIntType) { - TRACE(("%ld %ld => DIVIDE BY ZERO\n", i, i2)); - } else { - TRACE((LLD" %ld => DIVIDE BY ZERO\n", w, i2)); - } - goto divideByZero; - } - if (valuePtr->typePtr == &tclWideIntType - || value2Ptr->typePtr == &tclWideIntType) { - Tcl_WideInt wRemainder; - - /* - * Promote to wide - */ - - if (valuePtr->typePtr == &tclIntType) { - w = Tcl_LongAsWide(i); - } else if (value2Ptr->typePtr == &tclIntType) { - w2 = Tcl_LongAsWide(i2); - } - if (w == LLONG_MIN && w2 == -1) { - /* - * Integer overflow could happen with (LLONG_MIN % -1) - * even though it is not possible in the code below. - */ - - wRemainder = 0; - } else if (w == LLONG_MIN && w2 == LLONG_MAX) { - wRemainder = LLONG_MAX - 1; - } else if (w2 == LLONG_MIN) { - /* - * In C, a modulus operation is not well defined when the - * divisor is a negative number. So w % LLONG_MIN is not - * well defined in the code below because -LLONG_MIN is - * still a negative number. - */ - - if (w == 0 || w == LLONG_MIN) { - wRemainder = 0; - } else if (w < 0) { - wRemainder = w; - } else { - wRemainder = LLONG_MIN + w; - } - neg_divisor = 1; - } else { - if (w2 < 0) { - w2 = -w2; - w = -w; /* Note: -LLONG_MIN == LLONG_MIN */ - neg_divisor = 1; - } - wRemainder = w % w2; - - /* - * remainder is (remainder + divisor) when the remainder - * is negative. Watch out for the special case of a - * LLONG_MIN dividend and a negative divisor. Don't add - * the divisor in that case because the remainder should - * not be negative. - */ - - if (wRemainder < 0 && !(neg_divisor && w==LLONG_MIN)) { - wRemainder += w2; - } - } - if ((neg_divisor && (wRemainder > 0)) || - (!neg_divisor && (wRemainder < 0))) { - wRemainder = -wRemainder; - } - wResult = wRemainder; - doWide = 1; - break; - } - - if (i == LONG_MIN && i2 == -1) { - /* - * Integer overflow could happen with (LONG_MIN % -1) even - * though it is not possible in the code below. - */ - - rem = 0; - } else if (i == LONG_MIN && i2 == LONG_MAX) { - rem = LONG_MAX - 1; - } else if (i2 == LONG_MIN) { - /* - * In C, a modulus operation is not well defined when the - * divisor is a negative number. So i % LONG_MIN is not well - * defined in the code below because -LONG_MIN is still a - * negative number. - */ - - if (i == 0 || i == LONG_MIN) { - rem = 0; - } else if (i < 0) { - rem = i; - } else { - rem = LONG_MIN + i; - } - neg_divisor = 1; - } else { - if (i2 < 0) { - i2 = -i2; - i = -i; /* Note: -LONG_MIN == LONG_MIN */ - neg_divisor = 1; - } - rem = i % i2; - - /* - * Remainder is (remainder + divisor) when the remainder is - * negative. Watch out for the special case of a LONG_MIN - * dividend and a negative divisor. Don't add the divisor in - * that case because the remainder should not be negative. - */ - - if (rem < 0 && !(neg_divisor && (i == LONG_MIN))) { - rem += i2; - } - } - - if ((neg_divisor && (rem > 0)) || - (!neg_divisor && (rem < 0))) { - rem = -rem; - } - iResult = rem; - } while (0); - - /* - * Reuse the valuePtr object already on stack if possible. - */ - - if (Tcl_IsShared(valuePtr)) { - if (doWide) { - TclNewWideIntObj(objResultPtr, wResult); - TRACE((LLD" "LLD" => "LLD"\n", w, w2, wResult)); - } else { - TclNewLongObj(objResultPtr, iResult); - TRACE(("%ld %ld => %ld\n", i, i2, iResult)); - } - NEXT_INST_F(1, 2, 1); - } else { /* reuse the valuePtr object */ - if (doWide) { - TRACE((LLD" "LLD" => "LLD"\n", w, w2, wResult)); - TclSetWideIntObj(valuePtr, wResult); - } else { - TRACE(("%ld %ld => %ld\n", i, i2, iResult)); - TclSetLongObj(valuePtr, iResult); - } - NEXT_INST_F(1, 1, 0); - } - } -#endif - case INST_EXPON: case INST_ADD: case INST_SUB: |