summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2005-12-18 22:42:14 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2005-12-18 22:42:14 (GMT)
commit9e980b0bde0e1bd6f6c549832502dcf9b5f6b623 (patch)
tree3aac20695f552a296f60f9a1ae5948f95ad97afe /generic
parent6947dd1dec4d0417fddeeefed65c0ae6008bcf48 (diff)
downloadtcl-9e980b0bde0e1bd6f6c549832502dcf9b5f6b623.zip
tcl-9e980b0bde0e1bd6f6c549832502dcf9b5f6b623.tar.gz
tcl-9e980b0bde0e1bd6f6c549832502dcf9b5f6b623.tar.bz2
Fix [Bug 1382528]; thanks to Anton Kovalenko for finding this.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclCompCmds.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index 2c63d5b..e62ab03 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.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: tclCompCmds.c,v 1.82 2005/11/30 14:59:40 dkf Exp $
+ * RCS: @(#) $Id: tclCompCmds.c,v 1.83 2005/12/18 22:42:18 dkf Exp $
*/
#include "tclInt.h"
@@ -669,7 +669,7 @@ TclCompileDictCmd(
} else if (size==3 && strncmp(cmd, "for", 3)==0) {
Tcl_Token *varsTokenPtr, *dictTokenPtr, *bodyTokenPtr;
int keyVarIndex, valueVarIndex, nameChars, loopRange, catchRange;
- int infoIndex, jumpDisplacement, bodyTargetOffset, doneTargetOffset;
+ int infoIndex, jumpDisplacement, bodyTargetOffset, emptyTargetOffset;
int endTargetOffset;
const char **argv;
Tcl_DString buffer;
@@ -740,7 +740,7 @@ TclCompileDictCmd(
CompileWord(envPtr, dictTokenPtr, interp);
TclEmitInstInt4( INST_DICT_FIRST, infoIndex, envPtr);
- doneTargetOffset = CurrentOffset(envPtr);
+ emptyTargetOffset = CurrentOffset(envPtr);
TclEmitInstInt4( INST_JUMP_TRUE4, 0, envPtr);
/*
@@ -795,16 +795,6 @@ TclCompileDictCmd(
TclEmitInstInt4( INST_DICT_NEXT, infoIndex, envPtr);
jumpDisplacement = bodyTargetOffset - CurrentOffset(envPtr);
TclEmitInstInt4( INST_JUMP_FALSE4, jumpDisplacement, envPtr);
-
- /*
- * Otherwise we're done (the jump after the DICT_FIRST points here)
- * and we need to pop the bogus key/value pair (pushed to keep stack
- * calculations easy!)
- */
-
- jumpDisplacement = CurrentOffset(envPtr) - doneTargetOffset;
- TclUpdateInstInt4AtPc(INST_JUMP_TRUE4, jumpDisplacement,
- envPtr->codeStart + doneTargetOffset);
TclEmitOpcode( INST_POP, envPtr);
TclEmitOpcode( INST_POP, envPtr);
@@ -836,6 +826,19 @@ TclCompileDictCmd(
TclEmitOpcode( INST_RETURN_STK, envPtr);
/*
+ * Otherwise we're done (the jump after the DICT_FIRST points here)
+ * and we need to pop the bogus key/value pair (pushed to keep stack
+ * calculations easy!) Note that we skip the END_CATCH. [Bug 1382528]
+ */
+
+ jumpDisplacement = CurrentOffset(envPtr) - emptyTargetOffset;
+ TclUpdateInstInt4AtPc(INST_JUMP_TRUE4, jumpDisplacement,
+ envPtr->codeStart + emptyTargetOffset);
+ TclEmitOpcode( INST_POP, envPtr);
+ TclEmitOpcode( INST_POP, envPtr);
+ TclEmitInstInt4( INST_DICT_DONE, infoIndex, envPtr);
+
+ /*
* Final stage of the command (normal case) is that we push an empty
* object. This is done last to promote peephole optimization when
* it's dropped immediately.