summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2015-08-02 16:17:00 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2015-08-02 16:17:00 (GMT)
commite9e00655085d4adea3b0d81b30827c598cb4dcc1 (patch)
treebe086c2ef7f7e58c8c3e14705acd13ac0eaf7be7
parentbaede06dd8e3f85ac6630f1af5d84e159871ea3f (diff)
downloadtcl-e9e00655085d4adea3b0d81b30827c598cb4dcc1.zip
tcl-e9e00655085d4adea3b0d81b30827c598cb4dcc1.tar.gz
tcl-e9e00655085d4adea3b0d81b30827c598cb4dcc1.tar.bz2
And another problem with continue in for-step clauses, this time a problem in how TEBC handled an edge case in the semantics.
-rw-r--r--generic/tclExecute.c25
-rw-r--r--tests/for.test2
2 files changed, 17 insertions, 10 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index b3f0c4d..2fa0928 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -758,7 +758,7 @@ static Tcl_Obj * ExecuteExtendedUnaryMathOp(int opcode,
Tcl_Obj *valuePtr);
static void FreeExprCodeInternalRep(Tcl_Obj *objPtr);
static ExceptionRange * GetExceptRangeForPc(const unsigned char *pc,
- int catchOnly, ByteCode *codePtr);
+ int searchMode, ByteCode *codePtr);
static const char * GetSrcInfoForPc(const unsigned char *pc,
ByteCode *codePtr, int *lengthPtr,
const unsigned char **pcBeg, int *cmdIdxPtr);
@@ -7955,7 +7955,7 @@ TEBCresume(
}
#endif
if ((result == TCL_CONTINUE) || (result == TCL_BREAK)) {
- rangePtr = GetExceptRangeForPc(pc, /*catchOnly*/ 0, codePtr);
+ rangePtr = GetExceptRangeForPc(pc, result, codePtr);
if (rangePtr == NULL) {
TRACE_APPEND(("no encl. loop or catch, returning %s\n",
StringForResultCode(result)));
@@ -8116,7 +8116,7 @@ TEBCresume(
#endif
goto abnormalReturn;
}
- rangePtr = GetExceptRangeForPc(pc, /*catchOnly*/ 1, codePtr);
+ rangePtr = GetExceptRangeForPc(pc, TCL_ERROR, codePtr);
if (rangePtr == NULL) {
/*
* This is only possible when compiling a [catch] that sends its
@@ -10129,14 +10129,16 @@ GetSrcInfoForPc(
static ExceptionRange *
GetExceptRangeForPc(
- const unsigned char *pc, /* The program counter value for which to
+ const unsigned char *pc, /* The program counter value for which to
* search for a closest enclosing exception
* range. This points to a bytecode
* instruction in codePtr's code. */
- int catchOnly, /* If 0, consider either loop or catch
- * ExceptionRanges in search. If nonzero
+ int searchMode, /* If TCL_BREAK, consider either loop or catch
+ * ExceptionRanges in search. If TCL_ERROR
* consider only catch ranges (and ignore any
- * closer loop ranges). */
+ * closer loop ranges). If TCL_CONTINUE, look
+ * for loop ranges that define a continue
+ * point or a catch range. */
ByteCode *codePtr) /* Points to the ByteCode in which to search
* for the enclosing ExceptionRange. */
{
@@ -10162,8 +10164,13 @@ GetExceptRangeForPc(
start = rangePtr->codeOffset;
if ((start <= pcOffset) &&
(pcOffset < (start + rangePtr->numCodeBytes))) {
- if ((!catchOnly)
- || (rangePtr->type == CATCH_EXCEPTION_RANGE)) {
+ if (rangePtr->type == CATCH_EXCEPTION_RANGE) {
+ return rangePtr;
+ }
+ if (searchMode == TCL_BREAK) {
+ return rangePtr;
+ }
+ if (searchMode == TCL_CONTINUE && rangePtr->continueOffset != -1){
return rangePtr;
}
}
diff --git a/tests/for.test b/tests/for.test
index 6c710bb..1a65274 100644
--- a/tests/for.test
+++ b/tests/for.test
@@ -1314,7 +1314,7 @@ test for-8.9 {break in for-step clause} {
list $i $j $k
}}
} {2 1 3}
-test for-8.10 {continue in for-step clause} knownBug {
+test for-8.10 {continue in for-step clause} {
apply {{} {
for {set k 0} {$k < 3} {incr k} {
set j 0