diff options
author | Miguel Sofer <miguel.sofer@gmail.com> | 2007-07-11 21:27:27 (GMT) |
---|---|---|
committer | Miguel Sofer <miguel.sofer@gmail.com> | 2007-07-11 21:27:27 (GMT) |
commit | 95089adb47fee26e3c41c8d88e3dfd356d48dcc2 (patch) | |
tree | ece8e7586529705cc7d47f00e42666eb3ed271cc /generic | |
parent | 2c819f71e6342fb519e96c5cb316a08b63adeaa9 (diff) | |
download | tcl-95089adb47fee26e3c41c8d88e3dfd356d48dcc2.zip tcl-95089adb47fee26e3c41c8d88e3dfd356d48dcc2.tar.gz tcl-95089adb47fee26e3c41c8d88e3dfd356d48dcc2.tar.bz2 |
2007-07-11 Miguel Sofer <msofer@users.sf.net>
* generic/tclCompCmds.c (TclCompileWhileCmd):
* generic/tclCompile.c (TclCompileScript):
Corrected faulty avoidance of INST_START_CMD when the first opcode
in a script is within a loop (as produced by 'while 1'), so that
the corresponding command is properly counted [Bug 1752146].
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclCompCmds.c | 8 | ||||
-rw-r--r-- | generic/tclCompile.c | 35 |
2 files changed, 28 insertions, 15 deletions
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index c50849b..8176295 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.112 2007/06/28 21:10:38 patthoyts Exp $ + * RCS: @(#) $Id: tclCompCmds.c,v 1.113 2007/07/11 21:27:28 msofer Exp $ */ #include "tclInt.h" @@ -4400,6 +4400,12 @@ TclCompileWhileCmd( TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpEvalCondFixup); testCodeOffset = 0; /* Avoid compiler warning. */ } else { + /* + * Make sure that the first command in the body is preceded by an + * INST_START_CMD, and hence counted properly. [Bug 1752146] + */ + + envPtr->atCmdStart = 0; testCodeOffset = CurrentOffset(envPtr); } diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 79d0c5b..d55df75 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclCompile.c,v 1.123 2007/06/21 18:41:16 dgp Exp $ + * RCS: @(#) $Id: tclCompile.c,v 1.124 2007/07/11 21:27:28 msofer Exp $ */ #include "tclInt.h" @@ -870,7 +870,7 @@ TclInitCompileEnv( envPtr->cmdMapPtr = envPtr->staticCmdMapSpace; envPtr->cmdMapEnd = COMPILEENV_INIT_CMD_MAP_SIZE; envPtr->mallocedCmdMap = 0; - envPtr->atCmdStart = 0; + envPtr->atCmdStart = 1; /* * TIP #280: Set up the extended command location information, based on @@ -1354,31 +1354,38 @@ TclCompileScript( /* * Mark the start of the command; the proper bytecode * length will be updated later. There is no need to - * do this for the first command in the compile env, + * do this for the first bytecode in the compile env, * as the check is done before calling - * TclExecuteByteCode(). Remark that we are compiling - * the first cmd in the environment exactly when - * (savedCodeNext == 0) + * TclExecuteByteCode(). Do emit an INST_START_CMD in + * special cases where the first bytecode is in a + * loop, to insure that the corresponding command is + * counted properly. Compilers for commands able to + * produce such a beast (currently 'while 1' only) set + * envPtr->atCmdStart to 0 in order to signal this + * case. [Bug 1752146] + * Note that the environment is initialised with + * atCmdStart=1 to avoid emitting ISC for the first + * command. */ - if (savedCodeNext != 0) { - if (envPtr->atCmdStart) { + if (envPtr->atCmdStart) { + if (savedCodeNext != 0) { /* * Increase the number of commands being * started at the current point. Note that * this depends on the exact layout of the * INST_START_CMD's operands, so be careful! */ - + unsigned char *fixPtr = envPtr->codeNext - 4; - + TclStoreInt4AtPtr(TclGetUInt4AtPtr(fixPtr)+1, fixPtr); - } else { - TclEmitInstInt4(INST_START_CMD, 0, envPtr); - TclEmitInt4(1, envPtr); - update = 1; } + } else { + TclEmitInstInt4(INST_START_CMD, 0, envPtr); + TclEmitInt4(1, envPtr); + update = 1; } code = (cmdPtr->compileProc)(interp, parsePtr, envPtr); |