summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--generic/tclExecute.c13
-rw-r--r--generic/tclInt.h15
-rw-r--r--generic/tclObj.c22
-rw-r--r--tests/execute.test16
5 files changed, 48 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 3f6a0f1..6be728c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2006-07-21 Miguel Sofer <msofer@users.sf.net>
+ * generic/tclExecute.c:
+ * tests/execute.test (execute-9.1): dgp's fix for [Bug 1522803].
+
2006-07-20 Daniel Steffen <das@users.sourceforge.net>
* macosx/tclMacOSXNotify.c (Tcl_InitNotifier, Tcl_WaitForEvent): create
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 96677f9..0870219 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.238 2006/07/20 06:17:38 das Exp $
+ * RCS: @(#) $Id: tclExecute.c,v 1.239 2006/07/21 10:47:18 msofer Exp $
*/
#include "tclInt.h"
@@ -1791,7 +1791,7 @@ TclExecuteByteCode(
*/
DECACHE_STACK_INFO();
- Tcl_ResetResult(interp);
+ /*Tcl_ResetResult(interp);*/
result = TclEvalObjvInternal(interp, objc, objv, bytes, length, 0);
CACHE_STACK_INFO();
@@ -1890,7 +1890,7 @@ TclExecuteByteCode(
objPtr = *tosPtr;
DECACHE_STACK_INFO();
- Tcl_ResetResult(interp);
+ /*Tcl_ResetResult(interp);*/
result = Tcl_ExprObj(interp, objPtr, &valuePtr);
CACHE_STACK_INFO();
if (result != TCL_OK) {
@@ -5205,17 +5205,21 @@ TclExecuteByteCode(
}
case INST_BREAK:
+ /*
DECACHE_STACK_INFO();
Tcl_ResetResult(interp);
CACHE_STACK_INFO();
+ */
result = TCL_BREAK;
cleanup = 0;
goto processExceptionReturn;
case INST_CONTINUE:
+ /*
DECACHE_STACK_INFO();
Tcl_ResetResult(interp);
CACHE_STACK_INFO();
+ */
result = TCL_CONTINUE;
cleanup = 0;
goto processExceptionReturn;
@@ -5411,6 +5415,7 @@ TclExecuteByteCode(
case INST_END_CATCH:
catchTop--;
+ Tcl_ResetResult(interp);
result = TCL_OK;
TRACE(("=> catchTop=%d\n", (catchTop - initCatchTop - 1)));
NEXT_INST_F(1, 0, 0);
@@ -5474,7 +5479,7 @@ TclExecuteByteCode(
goto checkForCatch;
}
if (objResultPtr == NULL) {
- Tcl_ResetResult(interp);
+ /*Tcl_ResetResult(interp);*/
Tcl_AppendResult(interp, "key \"", TclGetString(*tosPtr),
"\" not known in dictionary", NULL);
TRACE_WITH_OBJ(("%u => ERROR ", opnd), Tcl_GetObjResult(interp));
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 35addc8..cb4a70f 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -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: tclInt.h,v 1.272 2006/07/05 05:34:44 dgp Exp $
+ * RCS: @(#) $Id: tclInt.h,v 1.273 2006/07/21 10:47:19 msofer Exp $
*/
#ifndef _TCLINT
@@ -2624,15 +2624,20 @@ MODULE_SCOPE void TclInvalidateNsPath(Namespace *nsPtr);
(objPtr)->length = 0; \
(objPtr)->typePtr = NULL
+/* Invalidate the string rep first so we can use the bytes value \
+ * for our pointer chain, and signal an obj deletion (as opposed \
+ * to shimmering) with 'length == -1' */ \
+
# define TclDecrRefCount(objPtr) \
if (--(objPtr)->refCount <= 0) { \
+ if ((objPtr)->bytes \
+ && ((objPtr)->bytes != tclEmptyStringRep)) { \
+ ckfree((char *) (objPtr)->bytes); \
+ } \
+ (objPtr)->length = -1; \
if ((objPtr)->typePtr && (objPtr)->typePtr->freeIntRepProc) { \
TclFreeObj(objPtr); \
} else { \
- if ((objPtr)->bytes \
- && ((objPtr)->bytes != tclEmptyStringRep)) { \
- ckfree((char *) (objPtr)->bytes); \
- } \
TclFreeObjStorage(objPtr); \
TclIncrObjsFreed(); \
} \
diff --git a/generic/tclObj.c b/generic/tclObj.c
index 521a49b..6463904 100644
--- a/generic/tclObj.c
+++ b/generic/tclObj.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: tclObj.c,v 1.109 2006/07/20 06:17:39 das Exp $
+ * RCS: @(#) $Id: tclObj.c,v 1.110 2006/07/21 10:47:19 msofer Exp $
*/
#include "tclInt.h"
@@ -111,13 +111,8 @@ typedef struct PendingObjData {
#define ObjDeletePending(contextPtr) ((contextPtr)->deletionCount > 0)
#define ObjOnStack(contextPtr) ((contextPtr)->deletionStack != NULL)
#define PushObjToDelete(contextPtr,objPtr) \
- /* Invalidate the string rep first so we can use the bytes value \
- * for our pointer chain. */ \
- if (((objPtr)->bytes != NULL) \
- && ((objPtr)->bytes != tclEmptyStringRep)) { \
- ckfree((char *) (objPtr)->bytes); \
- } \
- /* Now push onto the head of the stack. */ \
+ /* The string rep is already invalidated so we can use the bytes value \
+ * for our pointer chain: push onto the head of the stack. */ \
(objPtr)->bytes = (char *) ((contextPtr)->deletionStack); \
(contextPtr)->deletionStack = (objPtr)
#define PopObjToDelete(contextPtr,objPtrVar) \
@@ -849,6 +844,13 @@ TclFreeObj(
Tcl_Panic("Reference count for %lx was negative", objPtr);
}
+ /* Invalidate the string rep first so we can use the bytes value
+ * for our pointer chain, and signal an obj deletion (as opposed
+ * to shimmering) with 'length == -1' */
+
+ TclInvalidateStringRep(objPtr);
+ objPtr->length = -1;
+
if (ObjDeletePending(context)) {
PushObjToDelete(context, objPtr);
} else {
@@ -857,7 +859,6 @@ TclFreeObj(
typePtr->freeIntRepProc(objPtr);
ObjDeletionUnlock(context);
}
- TclInvalidateStringRep(objPtr);
Tcl_MutexLock(&tclObjMutex);
ckfree((char *) objPtr);
@@ -923,9 +924,6 @@ TclFreeObj(
objPtr->typePtr->freeIntRepProc(objPtr);
ObjDeletionUnlock(context);
- if (objPtr->bytes && (objPtr->bytes != tclEmptyStringRep)) {
- ckfree((char *) objPtr->bytes);
- }
TclFreeObjStorage(objPtr);
TclIncrObjsFreed();
ObjDeletionLock(context);
diff --git a/tests/execute.test b/tests/execute.test
index 1b3d75f..0175706 100644
--- a/tests/execute.test
+++ b/tests/execute.test
@@ -14,7 +14,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: execute.test,v 1.22 2006/03/21 11:12:29 dkf Exp $
+# RCS: @(#) $Id: execute.test,v 1.23 2006/07/21 10:47:19 msofer Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest 2
@@ -760,6 +760,20 @@ test execute-8.3 {Stack restoration} -body {
interp recursionlimit {} $limit
} -result {too many nested evaluations (infinite loop?)}
+test execute-9.1 {Interp result resetting [Bug 1522803]} {
+ set c 0
+ catch {
+ catch {set foo}
+ expr {1/$c}
+ }
+ if {[string match *foo* $::errorInfo]} {
+ set result "Bad errorInfo: $::errorInfo"
+ } else {
+ set result SUCCESS
+ }
+ set result
+} SUCCESS
+
# cleanup
if {[info commands testobj] != {}} {
testobj freeallvars