diff options
| author | Miguel Sofer <miguel.sofer@gmail.com> | 2002-06-11 12:38:22 (GMT) | 
|---|---|---|
| committer | Miguel Sofer <miguel.sofer@gmail.com> | 2002-06-11 12:38:22 (GMT) | 
| commit | 81201bff15bb25a70543f6ea4d698437c8572f19 (patch) | |
| tree | a4a65d969f8546df611523e01e5e7c2639435024 | |
| parent | 92f6045e0fda3e2f7476d2ce156c749863467ac4 (diff) | |
| download | tcl-81201bff15bb25a70543f6ea4d698437c8572f19.zip tcl-81201bff15bb25a70543f6ea4d698437c8572f19.tar.gz tcl-81201bff15bb25a70543f6ea4d698437c8572f19.tar.bz2  | |
generic/tclExecute.c: optimised algorithm for exception range lookup
| -rw-r--r-- | ChangeLog | 5 | ||||
| -rw-r--r-- | generic/tclExecute.c | 39 | 
2 files changed, 29 insertions, 15 deletions
@@ -1,3 +1,8 @@ +2002-06-10  Miguel Sofer  <msofer@users.sourceforge.net> + +	* generic/tclExecute.c: optimised algorithm for exception range +	lookup; part of [Patch 453709]. +  2002-06-10  Vince Darley  <vincentdarley@users.sourceforge.net>  	* unix/tclUnixFCmd.c: fixed [Bug #566669] 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;  	    }  	}      }  | 
