summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/tclExecute.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index ad06d99..06456d3 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -11,7 +11,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.192 2005/06/20 23:10:24 dkf Exp $
+ * RCS: @(#) $Id: tclExecute.c,v 1.193 2005/06/29 03:29:00 mdejong Exp $
*/
#include "tclInt.h"
@@ -4224,10 +4224,11 @@ TclExecuteByteCode(interp, codePtr)
double d;
int boolvar;
long i;
+ int negate_value = 1;
Tcl_WideInt w;
Tcl_ObjType *tPtr;
Tcl_Obj *valuePtr;
-
+
valuePtr = *tosPtr;
tPtr = valuePtr->typePtr;
if (IS_INTEGER_TYPE(tPtr)
@@ -4247,6 +4248,23 @@ TclExecuteByteCode(interp, codePtr)
char *s = Tcl_GetStringFromObj(valuePtr, &length);
if (TclLooksLikeInt(s, length)) {
GET_WIDE_OR_INT(result, valuePtr, i, w);
+
+ /*
+ * An integer was parsed. If parsing a literal that
+ * is the smallest long value, then it would have
+ * been promoted to a wide since it would not fit in
+ * a long type without the leading '-'. Convert
+ * back to the smallest possible long.
+ */
+
+ if ((result == TCL_OK) &&
+ (*pc == INST_UMINUS) &&
+ (valuePtr->typePtr == &tclWideIntType) &&
+ (w == -Tcl_LongAsWide(LONG_MIN))) {
+ valuePtr->typePtr = &tclIntType;
+ valuePtr->internalRep.longValue = LONG_MIN;
+ negate_value = 0;
+ }
} else {
result = Tcl_GetDoubleFromObj(NULL, valuePtr, &d);
}
@@ -4270,11 +4288,14 @@ TclExecuteByteCode(interp, codePtr)
*/
if (tPtr == &tclIntType) {
i = valuePtr->internalRep.longValue;
- TclNewLongObj(objResultPtr, -i);
+ if (negate_value) {
+ i = -i;
+ }
+ TclNewLongObj(objResultPtr, i);
TRACE_WITH_OBJ(("%ld => ", i), objResultPtr);
} else if (tPtr == &tclWideIntType) {
TclGetWide(w,valuePtr);
- TclNewWideIntObj(objResultPtr, -w);
+ TclNewWideIntObj(objResultPtr, -w);
TRACE_WITH_OBJ((LLD" => ", w), objResultPtr);
} else {
d = valuePtr->internalRep.doubleValue;
@@ -4288,7 +4309,10 @@ TclExecuteByteCode(interp, codePtr)
*/
if (tPtr == &tclIntType) {
i = valuePtr->internalRep.longValue;
- TclSetLongObj(valuePtr, -i);
+ if (negate_value) {
+ i = -i;
+ }
+ TclSetLongObj(valuePtr, i);
TRACE_WITH_OBJ(("%ld => ", i), valuePtr);
} else if (tPtr == &tclWideIntType) {
TclGetWide(w,valuePtr);