summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--generic/tclCompCmds.c46
2 files changed, 35 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index fac6c7e..3be8437 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2002-02-25 Miguel Sofer <msofer@users.sourceforge.net>
+
+ * generic/tclCompCmds: fixing a bug in patch dated 2002-02-22, in
+ the code for [for] and [while]. Under certain conditions, for long
+ bodies, the exception range parameters were badly computed. Tests
+ forthcoming: I still can't reproduce the conditions in the
+ testsuite (!), although the bug (with assorted segfault or panic!)
+ can be triggered from the console or with the new parse.bench in
+ tclbench.
+
2002-02-25 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* compat/strtoul.c, compat/strtol.c, compat/strtod.c: Added UCHAR,
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index caed2cd..c3b731f 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.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: tclCompCmds.c,v 1.25 2002/02/22 19:54:02 msofer Exp $
+ * RCS: @(#) $Id: tclCompCmds.c,v 1.26 2002/02/25 14:15:10 msofer Exp $
*/
#include "tclInt.h"
@@ -492,7 +492,6 @@ TclCompileExprCmd(interp, parsePtr, envPtr)
*
*----------------------------------------------------------------------
*/
-
int
TclCompileForCmd(interp, parsePtr, envPtr)
Tcl_Interp *interp; /* Used for error reporting. */
@@ -502,7 +501,7 @@ TclCompileForCmd(interp, parsePtr, envPtr)
{
Tcl_Token *startTokenPtr, *testTokenPtr, *nextTokenPtr, *bodyTokenPtr;
JumpFixup jumpEvalCondFixup;
- int testCodeOffset, bodyCodeOffset, jumpDist;
+ int testCodeOffset, bodyCodeOffset, nextCodeOffset, jumpDist;
int bodyRange, nextRange, code;
char buffer[32 + TCL_INTEGER_SPACE];
int savedStackDepth = envPtr->currStackDepth;
@@ -572,9 +571,9 @@ TclCompileForCmd(interp, parsePtr, envPtr)
* "for start cond next body" produces then:
* start
* goto A
- * B: body
- * next
- * A: cond -> result
+ * B: body : bodyCodeOffset
+ * next : nextCodeOffset, continueOffset
+ * A: cond -> result : testCodeOffset
* if (result) goto B
*/
@@ -585,7 +584,6 @@ TclCompileForCmd(interp, parsePtr, envPtr)
*/
bodyCodeOffset = (envPtr->codeNext - envPtr->codeStart);
- envPtr->exceptArrayPtr[bodyRange].codeOffset = bodyCodeOffset;
code = TclCompileCmdWord(interp, bodyTokenPtr+1,
bodyTokenPtr->numComponents, envPtr);
@@ -608,10 +606,7 @@ TclCompileForCmd(interp, parsePtr, envPtr)
*/
envPtr->currStackDepth = savedStackDepth;
- envPtr->exceptArrayPtr[bodyRange].continueOffset =
- (envPtr->codeNext - envPtr->codeStart);
- envPtr->exceptArrayPtr[nextRange].codeOffset =
- (envPtr->codeNext - envPtr->codeStart);
+ nextCodeOffset = (envPtr->codeNext - envPtr->codeStart);
code = TclCompileCmdWord(interp, nextTokenPtr+1,
nextTokenPtr->numComponents, envPtr);
envPtr->currStackDepth = savedStackDepth + 1;
@@ -637,6 +632,8 @@ TclCompileForCmd(interp, parsePtr, envPtr)
jumpDist = testCodeOffset - jumpEvalCondFixup.codeOffset;
if (TclFixupForwardJump(envPtr, &jumpEvalCondFixup, jumpDist, 127)) {
bodyCodeOffset += 3;
+ nextCodeOffset += 3;
+ testCodeOffset += 3;
}
envPtr->currStackDepth = savedStackDepth;
@@ -658,9 +655,14 @@ TclCompileForCmd(interp, parsePtr, envPtr)
}
/*
- * Set the loop's break target.
+ * Set the loop's offsets and break target.
*/
+ envPtr->exceptArrayPtr[bodyRange].codeOffset = bodyCodeOffset;
+ envPtr->exceptArrayPtr[bodyRange].continueOffset = nextCodeOffset;
+
+ envPtr->exceptArrayPtr[nextRange].codeOffset = nextCodeOffset;
+
envPtr->exceptArrayPtr[bodyRange].breakOffset =
envPtr->exceptArrayPtr[nextRange].breakOffset =
(envPtr->codeNext - envPtr->codeStart);
@@ -1132,7 +1134,6 @@ FreeForeachInfo(clientData)
*
*----------------------------------------------------------------------
*/
-
int
TclCompileIfCmd(interp, parsePtr, envPtr)
Tcl_Interp *interp; /* Used for error reporting. */
@@ -2965,16 +2966,20 @@ TclCompileWhileCmd(interp, parsePtr, envPtr)
* rotation" optimisation (which eliminates one branch from the loop).
* "while cond body" produces then:
* goto A
- * B: body
- * A: cond -> result
+ * B: body : bodyCodeOffset
+ * A: cond -> result : testCodeOffset, continueOffset
* if (result) goto B
+ *
+ * The infinite loop "while 1 body" produces:
+ * B: body : all three offsets here
+ * goto B
*/
if (loopMayEnd) {
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpEvalCondFixup);
+ testCodeOffset = 0; /* avoid compiler warning */
} else {
testCodeOffset = (envPtr->codeNext - envPtr->codeStart);
- envPtr->exceptArrayPtr[range].continueOffset = testCodeOffset;
}
@@ -2983,8 +2988,6 @@ TclCompileWhileCmd(interp, parsePtr, envPtr)
*/
bodyCodeOffset = (envPtr->codeNext - envPtr->codeStart);
- envPtr->exceptArrayPtr[range].codeOffset = bodyCodeOffset;
-
code = TclCompileCmdWord(interp, bodyTokenPtr+1,
bodyTokenPtr->numComponents, envPtr);
envPtr->currStackDepth = savedStackDepth + 1;
@@ -3007,12 +3010,11 @@ TclCompileWhileCmd(interp, parsePtr, envPtr)
if (loopMayEnd) {
testCodeOffset = (envPtr->codeNext - envPtr->codeStart);
- envPtr->exceptArrayPtr[range].continueOffset = testCodeOffset;
jumpDist = testCodeOffset - jumpEvalCondFixup.codeOffset;
if (TclFixupForwardJump(envPtr, &jumpEvalCondFixup, jumpDist, 127)) {
bodyCodeOffset += 3;
+ testCodeOffset += 3;
}
-
envPtr->currStackDepth = savedStackDepth;
code = TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
if (code != TCL_OK) {
@@ -3041,9 +3043,11 @@ TclCompileWhileCmd(interp, parsePtr, envPtr)
/*
- * Set the loop's break target.
+ * Set the loop's body, continue and break offsets.
*/
+ envPtr->exceptArrayPtr[range].continueOffset = testCodeOffset;
+ envPtr->exceptArrayPtr[range].codeOffset = bodyCodeOffset;
envPtr->exceptArrayPtr[range].breakOffset =
(envPtr->codeNext - envPtr->codeStart);