diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2015-08-03 07:17:27 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2015-08-03 07:17:27 (GMT) |
commit | a46065fc3397a5a80b92980442a10e58bbadd912 (patch) | |
tree | 9d7bc92065a14ccc034c856e6fddd2721e59fd8d /generic/tclExecute.c | |
parent | ec20498ab74fd4c48e24dcc7ecc9ff9e36b3ba72 (diff) | |
download | tcl-a46065fc3397a5a80b92980442a10e58bbadd912.zip tcl-a46065fc3397a5a80b92980442a10e58bbadd912.tar.gz tcl-a46065fc3397a5a80b92980442a10e58bbadd912.tar.bz2 |
Backport the fixes to handling of continue in for-step clauses.
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r-- | generic/tclExecute.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index b9415e5..553abed 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -615,7 +615,7 @@ static void DeleteExecStack(ExecStack *esPtr); static void DupExprCodeInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); static void FreeExprCodeInternalRep(Tcl_Obj *objPtr); -static ExceptionRange * GetExceptRangeForPc(unsigned char *pc, int catchOnly, +static ExceptionRange * GetExceptRangeForPc(unsigned char *pc, int searchMode, ByteCode *codePtr); static const char * GetSrcInfoForPc(unsigned char *pc, ByteCode *codePtr, int *lengthPtr); @@ -7347,7 +7347,7 @@ TclExecuteByteCode( } #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))); @@ -7453,7 +7453,7 @@ TclExecuteByteCode( #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 @@ -7944,13 +7944,14 @@ GetSrcInfoForPc( * ExceptionRange. * * Results: - * In the normal case, catchOnly is 0 (false) and this procedure returns - * a pointer to the most closely enclosing ExceptionRange structure - * regardless of whether it is a loop or catch exception range. This is - * appropriate when processing a TCL_BREAK or TCL_CONTINUE, which will be - * "handled" either by a loop exception range or a closer catch range. If - * catchOnly is nonzero, this procedure ignores loop exception ranges and - * returns a pointer to the closest catch range. If no matching + * If the searchMode is TCL_ERROR, this procedure ignores loop exception + * ranges and returns a pointer to the closest catch range. If the + * searchMode is TCL_BREAK, this procedure returns a pointer to the most + * closely enclosing ExceptionRange regardless of whether it is a loop or + * catch exception range. If the searchMode is TCL_CONTINUE, this + * procedure returns a pointer to the most closely enclosing + * ExceptionRange (of any type) skipping only loop exception ranges if + * they don't have a sensible continueOffset defined. If no matching * ExceptionRange is found that encloses pc, a NULL is returned. * * Side effects: @@ -7965,10 +7966,12 @@ GetExceptRangeForPc( * 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. */ { @@ -7994,8 +7997,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; } } |