diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2003-04-28 12:34:21 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2003-04-28 12:34:21 (GMT) |
commit | 9fe48f681df7e7a45aee145405151f0bef5d5808 (patch) | |
tree | a7dfc6ac4db8ceaa9a7d3fceccf59bbe274caa74 /generic/tclExecute.c | |
parent | 270dd26ada27456d73cfdcaf7623fee880227569 (diff) | |
download | tcl-9fe48f681df7e7a45aee145405151f0bef5d5808.zip tcl-9fe48f681df7e7a45aee145405151f0bef5d5808.tar.gz tcl-9fe48f681df7e7a45aee145405151f0bef5d5808.tar.bz2 |
Made [incr] able to accept and work with wide increments [Bug 728838]
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r-- | generic/tclExecute.c | 83 |
1 files changed, 56 insertions, 27 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index bcdb242..3d324a5 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.99 2003/04/18 20:03:50 hobbs Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.100 2003/04/28 12:34:25 dkf Exp $ */ #include "tclInt.h" @@ -1060,6 +1060,7 @@ TclExecuteByteCode(interp, codePtr) int length; long i = 0; /* Init. avoids compiler warning. */ Tcl_WideInt w; + int isWide; register int cleanup; Tcl_Obj *objResultPtr; char *part1, *part2; @@ -1872,8 +1873,10 @@ TclExecuteByteCode(interp, codePtr) valuePtr = stackPtr[stackTop]; if (valuePtr->typePtr == &tclIntType) { i = valuePtr->internalRep.longValue; + isWide = 0; } else if (valuePtr->typePtr == &tclWideIntType) { - TclGetLongFromWide(i,valuePtr); + w = valuePtr->internalRep.wideValue; + isWide = 1; } else { REQUIRE_WIDE_OR_INT(result, valuePtr, i, w); if (result != TCL_OK) { @@ -1882,7 +1885,7 @@ TclExecuteByteCode(interp, codePtr) Tcl_AddErrorInfo(interp, "\n (reading increment)"); goto checkForCatch; } - FORCE_LONG(valuePtr, i, w); + isWide = (valuePtr->typePtr == &tclWideIntType); } stackTop--; TclDecrRefCount(valuePtr); @@ -1902,6 +1905,7 @@ TclExecuteByteCode(interp, codePtr) case INST_INCR_SCALAR_STK_IMM: case INST_INCR_STK_IMM: i = TclGetInt1AtPtr(pc+1); + isWide = 0; pcAdjustment = 2; doIncrStk: @@ -1933,6 +1937,7 @@ TclExecuteByteCode(interp, codePtr) case INST_INCR_ARRAY1_IMM: opnd = TclGetUInt1AtPtr(pc+1); i = TclGetInt1AtPtr(pc+2); + isWide = 0; pcAdjustment = 3; doIncrArray: @@ -1957,6 +1962,7 @@ TclExecuteByteCode(interp, codePtr) case INST_INCR_SCALAR1_IMM: opnd = TclGetUInt1AtPtr(pc+1); i = TclGetInt1AtPtr(pc+2); + isWide = 0; pcAdjustment = 3; doIncrScalar: @@ -1977,35 +1983,58 @@ TclExecuteByteCode(interp, codePtr) && !TclIsVarUndefined(varPtr) && (varPtr->tracePtr == NULL) && ((arrayPtr == NULL) - || (arrayPtr->tracePtr == NULL)) - && (objPtr->typePtr == &tclIntType)) { - /* - * No errors, no traces, the variable already has an - * integer value: inline processing. - */ + || (arrayPtr->tracePtr == NULL))) { + if (objPtr->typePtr == &tclIntType && !isWide) { + /* + * No errors, no traces, the variable already has an + * integer value: inline processing. + */ - i += objPtr->internalRep.longValue; - if (Tcl_IsShared(objPtr)) { - objResultPtr = Tcl_NewLongObj(i); - TclDecrRefCount(objPtr); - Tcl_IncrRefCount(objResultPtr); - varPtr->value.objPtr = objResultPtr; - } else { - Tcl_SetLongObj(objPtr, i); - objResultPtr = objPtr; + i += objPtr->internalRep.longValue; + if (Tcl_IsShared(objPtr)) { + objResultPtr = Tcl_NewLongObj(i); + TclDecrRefCount(objPtr); + Tcl_IncrRefCount(objResultPtr); + varPtr->value.objPtr = objResultPtr; + } else { + Tcl_SetLongObj(objPtr, i); + objResultPtr = objPtr; + } + goto doneIncr; + } else if (objPtr->typePtr == &tclWideIntType && isWide) { + /* + * No errors, no traces, the variable already has a + * wide integer value: inline processing. + */ + + w += objPtr->internalRep.wideValue; + if (Tcl_IsShared(objPtr)) { + objResultPtr = Tcl_NewWideIntObj(w); + TclDecrRefCount(objPtr); + Tcl_IncrRefCount(objResultPtr); + varPtr->value.objPtr = objResultPtr; + } else { + Tcl_SetWideIntObj(objPtr, w); + objResultPtr = objPtr; + } + goto doneIncr; } - TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); + } + DECACHE_STACK_INFO(); + if (isWide) { + objResultPtr = TclPtrIncrWideVar(interp, varPtr, arrayPtr, part1, + part2, w, TCL_LEAVE_ERR_MSG); } else { - DECACHE_STACK_INFO(); objResultPtr = TclPtrIncrVar(interp, varPtr, arrayPtr, part1, - part2, i, TCL_LEAVE_ERR_MSG); - CACHE_STACK_INFO(); - if (objResultPtr == NULL) { - TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp)))); - result = TCL_ERROR; - goto checkForCatch; - } + part2, i, TCL_LEAVE_ERR_MSG); + } + CACHE_STACK_INFO(); + if (objResultPtr == NULL) { + TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp)))); + result = TCL_ERROR; + goto checkForCatch; } + doneIncr: TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); #ifndef TCL_COMPILE_DEBUG if (*(pc+pcAdjustment) == INST_POP) { |