summaryrefslogtreecommitdiffstats
path: root/generic/tclExecute.c
diff options
context:
space:
mode:
authordas <das>2007-11-17 15:12:42 (GMT)
committerdas <das>2007-11-17 15:12:42 (GMT)
commita75ccdf70dc42b23b35a9c60419bf8ef203b14b1 (patch)
treed75ed1e9e829ec2cecb818da81fe92a6da40d721 /generic/tclExecute.c
parenta3b4f81896bf2f0b9eef411b23e362eeccfddbc1 (diff)
downloadtcl-a75ccdf70dc42b23b35a9c60419bf8ef203b14b1.zip
tcl-a75ccdf70dc42b23b35a9c60419bf8ef203b14b1.tar.gz
tcl-a75ccdf70dc42b23b35a9c60419bf8ef203b14b1.tar.bz2
* generic/tclExecute.c (TclExecuteByteCode:INST_EXIST_*): Fix read
traces not firing on non-existent array elements. [Bug 1833522]
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r--generic/tclExecute.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 9569188..710da15 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -13,7 +13,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.350 2007/11/16 05:32:02 das Exp $
+ * RCS: @(#) $Id: tclExecute.c,v 1.351 2007/11/17 15:12:43 das Exp $
*/
#include "tclInt.h"
@@ -3127,16 +3127,18 @@ TclExecuteByteCode(
TRACE(("%u => ", opnd));
if (ReadTraced(varPtr)) {
DECACHE_STACK_INFO();
- if (TclObjCallVarTraces(iPtr, NULL, varPtr, NULL, NULL,
- TCL_TRACE_READS, 0, opnd) != TCL_OK) {
+ TclObjCallVarTraces(iPtr, NULL, varPtr, NULL, NULL,
+ TCL_TRACE_READS, 0, opnd);
+ CACHE_STACK_INFO();
+ if (TclIsVarUndefined(varPtr)) {
+ TclCleanupVar(varPtr, NULL);
varPtr = NULL;
}
- CACHE_STACK_INFO();
}
/*
* Tricky! Arrays always exist.
*/
- if (varPtr == NULL || varPtr->value.objPtr == NULL) {
+ if (varPtr == NULL || TclIsVarUndefined(varPtr)) {
objResultPtr = constants[0];
} else {
objResultPtr = constants[1];
@@ -3159,25 +3161,29 @@ TclExecuteByteCode(
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
NEXT_INST_F(5, 1, 1);
} else if (!ReadTraced(varPtr)) {
- objResultPtr = constants[varPtr->value.objPtr != NULL ? 1:0];
+ objResultPtr = constants[TclIsVarUndefined(varPtr) ? 0 : 1];
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
NEXT_INST_F(5, 1, 1);
}
}
varPtr = TclLookupArrayElement(interp, NULL, part2Ptr, 0, "access",
- 0, 0, arrayPtr, opnd);
- if (varPtr&&(ReadTraced(varPtr)||(arrayPtr&&ReadTraced(arrayPtr)))) {
- DECACHE_STACK_INFO();
- if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, NULL,
- part2Ptr, TCL_TRACE_READS, 0, opnd) != TCL_OK) {
+ 0, 1, arrayPtr, opnd);
+ if (varPtr) {
+ if (ReadTraced(varPtr) || (arrayPtr && ReadTraced(arrayPtr))) {
+ DECACHE_STACK_INFO();
+ TclObjCallVarTraces(iPtr, arrayPtr, varPtr, NULL, part2Ptr,
+ TCL_TRACE_READS, 0, opnd);
+ CACHE_STACK_INFO();
+ }
+ if (TclIsVarUndefined(varPtr)) {
+ TclCleanupVar(varPtr, arrayPtr);
varPtr = NULL;
}
- CACHE_STACK_INFO();
}
if (varPtr == NULL) {
objResultPtr = constants[0];
} else {
- objResultPtr = constants[varPtr->value.objPtr != NULL ? 1 : 0];
+ objResultPtr = constants[TclIsVarUndefined(varPtr) ? 0 : 1];
}
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
NEXT_INST_F(5, 1, 1);
@@ -3199,19 +3205,23 @@ TclExecuteByteCode(
doExistStk:
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, 0, "access",
- /*createPart1*/0, /*createPart2*/0, &arrayPtr);
- if (varPtr&&(ReadTraced(varPtr)||(arrayPtr&&ReadTraced(arrayPtr)))) {
- DECACHE_STACK_INFO();
- if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, part1Ptr,
- part2Ptr, TCL_TRACE_READS, 0, -1) != TCL_OK) {
+ /*createPart1*/0, /*createPart2*/1, &arrayPtr);
+ if (varPtr) {
+ if (ReadTraced(varPtr) || (arrayPtr && ReadTraced(arrayPtr))) {
+ DECACHE_STACK_INFO();
+ TclObjCallVarTraces(iPtr, arrayPtr, varPtr, part1Ptr, part2Ptr,
+ TCL_TRACE_READS, 0, -1);
+ CACHE_STACK_INFO();
+ }
+ if (TclIsVarUndefined(varPtr)) {
+ TclCleanupVar(varPtr, arrayPtr);
varPtr = NULL;
}
- CACHE_STACK_INFO();
}
if (!varPtr) {
objResultPtr = constants[0];
} else {
- objResultPtr = constants[varPtr->value.objPtr != NULL ? 1:0];
+ objResultPtr = constants[TclIsVarUndefined(varPtr) ? 0 : 1];
}
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
NEXT_INST_V(pcAdjustment, cleanup, 1);