summaryrefslogtreecommitdiffstats
path: root/generic/tclExecute.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2005-11-30 14:59:39 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2005-11-30 14:59:39 (GMT)
commit53c04f83d2b2ef25f90e34e7d05273f965790caa (patch)
tree1b07469f13d8ee2956bcb114e0992788298dc395 /generic/tclExecute.c
parentc3ae410bfd9c50b4b93c65bb20d96aca055c8c81 (diff)
downloadtcl-53c04f83d2b2ef25f90e34e7d05273f965790caa.zip
tcl-53c04f83d2b2ef25f90e34e7d05273f965790caa.tar.gz
tcl-53c04f83d2b2ef25f90e34e7d05273f965790caa.tar.bz2
New TEBC opcode, INST_JUMP_TABLE, for compiling the simple (and common) case of
[switch] into a jump-table. Much faster for long switches. Also compiler support for generating the new instruction where appropriate.
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r--generic/tclExecute.c58
1 files changed, 41 insertions, 17 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 38a7a6e..31870b5 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -12,7 +12,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.221 2005/11/27 02:33:49 das Exp $
+ * RCS: @(#) $Id: tclExecute.c,v 1.222 2005/11/30 14:59:40 dkf Exp $
*/
#include "tclInt.h"
@@ -2601,25 +2601,23 @@ TclExecuteByteCode(
* ---------------------------------------------------------
*/
- case INST_JUMP1:
- {
- int opnd;
+ case INST_JUMP1: {
+ int opnd;
- opnd = TclGetInt1AtPtr(pc+1);
- TRACE(("%d => new pc %u\n", opnd,
- (unsigned int)(pc + opnd - codePtr->codeStart)));
- NEXT_INST_F(opnd, 0, 0);
- }
+ opnd = TclGetInt1AtPtr(pc+1);
+ TRACE(("%d => new pc %u\n", opnd,
+ (unsigned int)(pc + opnd - codePtr->codeStart)));
+ NEXT_INST_F(opnd, 0, 0);
+ }
- case INST_JUMP4:
- {
- int opnd;
+ case INST_JUMP4: {
+ int opnd;
- opnd = TclGetInt4AtPtr(pc+1);
- TRACE(("%d => new pc %u\n", opnd,
- (unsigned int)(pc + opnd - codePtr->codeStart)));
- NEXT_INST_F(opnd, 0, 0);
- }
+ opnd = TclGetInt4AtPtr(pc+1);
+ TRACE(("%d => new pc %u\n", opnd,
+ (unsigned int)(pc + opnd - codePtr->codeStart)));
+ NEXT_INST_F(opnd, 0, 0);
+ }
{
int jmpOffset[2];
@@ -2680,6 +2678,32 @@ TclExecuteByteCode(
NEXT_INST_F(jmpOffset[b], 1, 0);
}
+ case INST_JUMP_TABLE: {
+ Tcl_HashEntry *hPtr;
+ JumptableInfo *jtPtr;
+ int opnd;
+
+ /*
+ * Jump to location looked up in a hashtable; fall through to next
+ * instr if lookup fails.
+ */
+
+ opnd = TclGetInt4AtPtr(pc+1);
+ jtPtr = (JumptableInfo *) codePtr->auxDataArrayPtr[opnd].clientData;
+ TRACE(("%d => %.20s ", opnd, O2S(*tosPtr)));
+ hPtr = Tcl_FindHashEntry(&jtPtr->hashTable, Tcl_GetString(*tosPtr));
+ if (hPtr != NULL) {
+ int jumpOffset = (int) Tcl_GetHashValue(hPtr);
+
+ TRACE_APPEND(("found in table, new pc %u\n",
+ (unsigned int)(pc - codePtr->codeStart + jumpOffset)));
+ NEXT_INST_F(jumpOffset, 1, 0);
+ } else {
+ TRACE_APPEND(("not found in table\n"));
+ NEXT_INST_F(5, 1, 0);
+ }
+ }
+
/*
* These two instructions are now redundant: the complete logic of the LOR
* and LAND is now handled by the expression compiler.