From 5adcddcdf6c8e339bf99b907ca0c68e5b2843d7f Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Sat, 10 Nov 2007 23:36:55 +0000 Subject: * generic/tclExecute.c: fast path for INST_LIST_INDEX when the index is not a list. --- generic/tclExecute.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 79fe487..2f3d617 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -13,7 +13,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.343 2007/11/09 21:35:18 msofer Exp $ + * RCS: @(#) $Id: tclExecute.c,v 1.344 2007/11/10 23:36:55 msofer Exp $ */ #include "tclInt.h" @@ -3412,6 +3412,10 @@ TclExecuteByteCode( case INST_LIST_INDEX: { /*** lindex with objc == 3 ***/ + /* Variables also for INST_LIST_INDEX_IMM */ + + int listc, idx, opnd, pcAdjustment; + Tcl_Obj **listv; Tcl_Obj *valuePtr, *value2Ptr; /* @@ -3425,6 +3429,16 @@ TclExecuteByteCode( * Extract the desired list element. */ + result = Tcl_ListObjGetElements(interp, valuePtr, &listc, &listv); + if ((result == TCL_OK) && (value2Ptr->typePtr != &tclListType) + && (TclGetIntForIndex(NULL , value2Ptr, listc-1, &idx) == TCL_OK)) { + + Tcl_DecrRefCount(value2Ptr); + tosPtr--; + pcAdjustment = 1; + goto lindexFastPath; + } + objResultPtr = TclLindexList(interp, valuePtr, value2Ptr); if (objResultPtr) { /* @@ -3440,14 +3454,11 @@ TclExecuteByteCode( result = TCL_ERROR; goto checkForCatch; } - } - case INST_LIST_INDEX_IMM: { + case INST_LIST_INDEX_IMM: /*** lindex with objc==3 and index in bytecode stream ***/ - int listc, idx, opnd; - Tcl_Obj **listv; - Tcl_Obj *valuePtr; + pcAdjustment = 5; /* * Pop the list and get the index. @@ -3473,6 +3484,8 @@ TclExecuteByteCode( } else { idx = opnd; } + + lindexFastPath: if (idx >= 0 && idx < listc) { objResultPtr = listv[idx]; } else { @@ -3481,7 +3494,7 @@ TclExecuteByteCode( TRACE_WITH_OBJ(("\"%.30s\" %d => ", O2S(valuePtr), opnd), objResultPtr); - NEXT_INST_F(5, 1, 1); + NEXT_INST_F(pcAdjustment, 1, 1); } else { TRACE_WITH_OBJ(("\"%.30s\" %d => ERROR: ", O2S(valuePtr), opnd), Tcl_GetObjResult(interp)); -- cgit v0.12