diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | generic/tclExecute.c | 13 | ||||
-rw-r--r-- | generic/tclInt.h | 15 | ||||
-rw-r--r-- | generic/tclObj.c | 22 | ||||
-rw-r--r-- | tests/execute.test | 16 |
5 files changed, 48 insertions, 22 deletions
@@ -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 |