Index: ChangeLog
===================================================================
RCS file: /cvsroot/tcl/tcl/ChangeLog,v
retrieving revision 1.527
diff -u -r1.527 ChangeLog
--- ChangeLog	2001/08/21 01:09:13	1.527
+++ ChangeLog	2001/08/21 12:44:14
@@ -1,3 +1,12 @@
+2001-08-21  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompCmds.c:
+	* generic/tclCompile.c:
+	* generic/tclCompile.h:
+	* generic/tclExecute.c: optimisation of exception range lookups,
+	moving some calculations to compile time, and reversing the order
+	of lookup to avoid some tests.
+
 2001-08-20  Jeff Hobbs  <jeffh@ActiveState.com>
 
 	* library/http/http.tcl (geturl): added port number to Host:
Index: generic/tclCompCmds.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclCompCmds.c,v
retrieving revision 1.9
diff -u -r1.9 tclCompCmds.c
--- generic/tclCompCmds.c	2001/06/28 00:42:39	1.9
+++ generic/tclCompCmds.c	2001/08/21 12:44:16
@@ -330,7 +330,7 @@
 	goto done;
     }
     maxDepth = envPtr->maxStackDepth;
-    envPtr->exceptArrayPtr[range].numCodeBytes =
+    envPtr->exceptArrayPtr[range].endOffset =
 	    (envPtr->codeNext - envPtr->codeStart) - startOffset;
 		    
     /*
@@ -607,7 +607,7 @@
 	goto done;
     }
     maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
-    envPtr->exceptArrayPtr[bodyRange].numCodeBytes =
+    envPtr->exceptArrayPtr[bodyRange].endOffset =
 	    (envPtr->codeNext - envPtr->codeStart)
 	    - envPtr->exceptArrayPtr[bodyRange].codeOffset;
     TclEmitOpcode(INST_POP, envPtr);
@@ -630,7 +630,7 @@
 	goto done;
     }
     maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
-    envPtr->exceptArrayPtr[nextRange].numCodeBytes =
+    envPtr->exceptArrayPtr[nextRange].endOffset =
 	    (envPtr->codeNext - envPtr->codeStart)
 	    - envPtr->exceptArrayPtr[nextRange].codeOffset;
     TclEmitOpcode(INST_POP, envPtr);
@@ -964,7 +964,7 @@
 	goto done;
     }
     maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
-    envPtr->exceptArrayPtr[range].numCodeBytes =
+    envPtr->exceptArrayPtr[range].endOffset =
 	    (envPtr->codeNext - envPtr->codeStart)
 	    - envPtr->exceptArrayPtr[range].codeOffset;
     TclEmitOpcode(INST_POP, envPtr);
@@ -2467,7 +2467,7 @@
 	goto error;
     }
     maxDepth = TclMax(envPtr->maxStackDepth, maxDepth);
-    envPtr->exceptArrayPtr[range].numCodeBytes =
+    envPtr->exceptArrayPtr[range].endOffset =
 	    (envPtr->codeNext - envPtr->codeStart)
 	    - envPtr->exceptArrayPtr[range].codeOffset;
     TclEmitOpcode(INST_POP, envPtr);
Index: generic/tclCompile.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclCompile.c,v
retrieving revision 1.22
diff -u -r1.22 tclCompile.c
--- generic/tclCompile.c	2001/05/17 02:13:02	1.22
+++ generic/tclCompile.c	2001/08/21 12:44:18
@@ -1603,6 +1603,23 @@
 #endif
     
     /*
+     * For all exception ranges: convert endOffsets from
+     * "relative to the start of the range" to "relative to the
+     * start of the bytecode"
+     */
+
+    {
+	ExceptionRange *rangePtr, *lastRangePtr;
+
+	rangePtr = codePtr->exceptArrayPtr;
+	lastRangePtr = rangePtr + codePtr->numExceptRanges;
+	for (;  rangePtr < lastRangePtr; rangePtr++) {
+	    rangePtr->endOffset += rangePtr->codeOffset;
+	}
+    }
+	
+
+    /*
      * Record various compilation-related statistics about the new ByteCode
      * structure. Don't include overhead for statistics-related fields.
      */
@@ -2154,7 +2171,7 @@
     rangePtr->type = type;
     rangePtr->nestingLevel = envPtr->exceptDepth;
     rangePtr->codeOffset = -1;
-    rangePtr->numCodeBytes = -1;
+    rangePtr->endOffset = -1;
     rangePtr->breakOffset = -1;
     rangePtr->continueOffset = -1;
     rangePtr->catchOffset = -1;
@@ -3018,7 +3035,7 @@
 		    ((rangePtr->type == LOOP_EXCEPTION_RANGE)
 			    ? "loop" : "catch"),
 		    rangePtr->codeOffset,
-		    (rangePtr->codeOffset + rangePtr->numCodeBytes - 1));
+		    rangePtr->endOffset - 1);
 	    switch (rangePtr->type) {
 	    case LOOP_EXCEPTION_RANGE:
 		fprintf(stdout,	"continue %d, break %d\n",
Index: generic/tclCompile.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclCompile.h,v
retrieving revision 1.15
diff -u -r1.15 tclCompile.h
--- generic/tclCompile.h	2001/05/17 02:13:02	1.15
+++ generic/tclCompile.h	2001/08/21 12:44:19
@@ -98,7 +98,10 @@
 				 * range surrounding a PC at runtime. */
     int codeOffset;		/* Offset of the first instruction byte of
 				 * the code range. */
-    int numCodeBytes;		/* Number of bytes in the code range. */
+    int endOffset;              /* During compilation, number of bytes in 
+				 * the code range. After the generation of the
+				 * bytecodeobject, offset of the first byte 
+				 * after the range */
     int breakOffset;		/* If LOOP_EXCEPTION_RANGE, the target PC
 				 * offset for a break command in the range. */
     int continueOffset;		/* If LOOP_EXCEPTION_RANGE and not -1, the
Index: generic/tclExecute.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclExecute.c,v
retrieving revision 1.26
diff -u -r1.26 tclExecute.c
--- generic/tclExecute.c	2001/07/03 23:39:10	1.26
+++ generic/tclExecute.c	2001/08/21 12:44:22
@@ -3893,29 +3893,30 @@
     int numRanges = codePtr->numExceptRanges;
     register ExceptionRange *rangePtr;
     int pcOffset = (pc - codePtr->codeStart);
-    register int i, level;
 
     if (numRanges == 0) {
 	return NULL;
     }
+
+    /*
+     * As nested exception ranges are recorded in order, we insure that the 
+     * deepest range is found first by inspecting them backwards, starting at
+     * the last
+     */
+
     rangeArrayPtr = codePtr->exceptArrayPtr;
+    rangePtr = rangeArrayPtr + numRanges - 1; 
 
-    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;
-		    }
-		}
+    for (;  rangePtr>= rangeArrayPtr;  rangePtr--) {
+	if ((rangePtr->codeOffset <= pcOffset)
+	        && (pcOffset < rangePtr->endOffset)) {
+	    if ((!catchOnly)
+		|| (rangePtr->type == CATCH_EXCEPTION_RANGE)) {
+		return rangePtr;
 	    }
 	}
     }
-    return NULL;
+    return NULL; 
 }
 
 /*
