summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorMiguel Sofer <miguel.sofer@gmail.com>2002-06-11 12:38:22 (GMT)
committerMiguel Sofer <miguel.sofer@gmail.com>2002-06-11 12:38:22 (GMT)
commit0eff1d6bf32b22f58751446875eb73b29f14d832 (patch)
treea4a65d969f8546df611523e01e5e7c2639435024 /generic
parentffa5cb21c298b67cfc7add97fdd50753c1423e7b (diff)
downloadtcl-0eff1d6bf32b22f58751446875eb73b29f14d832.zip
tcl-0eff1d6bf32b22f58751446875eb73b29f14d832.tar.gz
tcl-0eff1d6bf32b22f58751446875eb73b29f14d832.tar.bz2
generic/tclExecute.c: optimised algorithm for exception range lookup
Diffstat (limited to 'generic')
-rw-r--r--generic/tclExecute.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index fa19db4..cd92324 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.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: tclExecute.c,v 1.60 2002/06/07 10:38:03 dkf Exp $
+ * RCS: @(#) $Id: tclExecute.c,v 1.61 2002/06/11 12:38:22 msofer Exp $
*/
#include "tclInt.h"
@@ -1384,6 +1384,12 @@ TclExecuteByteCode(interp, codePtr)
}
case INST_EVAL_STK:
+ /*
+ * Note to maintainers: it is important that INST_EVAL_STK
+ * pop its argument from the stack before jumping to
+ * checkForCatch! DO NOT OPTIMISE!
+ */
+
objPtr = POP_OBJECT();
DECACHE_STACK_INFO();
result = TclCompEvalObj(interp, objPtr);
@@ -4775,25 +4781,28 @@ GetExceptRangeForPc(pc, catchOnly, codePtr)
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;
}
}
}