diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2005-12-18 22:42:14 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2005-12-18 22:42:14 (GMT) |
commit | 9e980b0bde0e1bd6f6c549832502dcf9b5f6b623 (patch) | |
tree | 3aac20695f552a296f60f9a1ae5948f95ad97afe /generic | |
parent | 6947dd1dec4d0417fddeeefed65c0ae6008bcf48 (diff) | |
download | tcl-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.c | 29 |
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. |