Index: ChangeLog
===================================================================
RCS file: /cvsroot/tcl/tcl/ChangeLog,v
retrieving revision 1.894
diff -u -r1.894 ChangeLog
--- ChangeLog	6 Mar 2002 11:28:08 -0000	1.894
+++ ChangeLog	6 Mar 2002 14:30:19 -0000
@@ -1,3 +1,8 @@
+2002-03-06  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c (GetExceptRangeForPc): faster lookup
+	algorithm [Patch 453709].
+
 2002-03-06  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
 
 	* doc/lsearch.n: Documentation of new features, plus examples.
Index: generic/tclExecute.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclExecute.c,v
retrieving revision 1.49
diff -u -r1.49 tclExecute.c
--- generic/tclExecute.c	28 Feb 2002 13:03:53 -0000	1.49
+++ generic/tclExecute.c	6 Mar 2002 14:30:22 -0000
@@ -4830,25 +4830,28 @@
     int numRanges = codePtr->numExceptRanges;
     register ExceptionRange *rangePtr;
     int pcOffset = (pc - codePtr->codeStart);
-    register int i, level;
+    register int start;
 
     if (numRanges == 0) {
 	return NULL;
     }
-    rangeArrayPtr = codePtr->exceptArrayPtr;
 
-    for (level = codePtr->maxExceptDepth;  level >= 0;  level--) {
-	for (i = 0;  i < numRanges;  i++) {
-	    rangePtr = &(rangeArrayPtr[i]);
-	    if (rangePtr->nestingLevel == level) {
-		int start = rangePtr->codeOffset;
-		int end   = (start + rangePtr->numCodeBytes);
-		if ((start <= pcOffset) && (pcOffset < end)) {
-		    if ((!catchOnly)
-			    || (rangePtr->type == CATCH_EXCEPTION_RANGE)) {
-			return rangePtr;
-		    }
-		}
+    /* 
+     * This exploits peculiarities of our compiler: nested ranges
+     * are always *after* their containing ranges, so that by scanning
+     * backwards we are sure that the first matching range is indeed
+     * the deepest.
+     */
+
+    rangeArrayPtr = codePtr->exceptArrayPtr;
+    rangePtr = rangeArrayPtr + numRanges;
+    while (--rangePtr >= rangeArrayPtr) {
+	start = rangePtr->codeOffset;
+	if ((start <= pcOffset) &&
+	        (pcOffset < (start + rangePtr->numCodeBytes))) {
+	    if ((!catchOnly)
+		    || (rangePtr->type == CATCH_EXCEPTION_RANGE)) {
+		return rangePtr;
 	    }
 	}
     }
