From ab2a78be642be26075e2998347d71359a6b3c500 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 13 Jul 2016 19:06:22 +0000 Subject: New private flag value INDEX_TEMP_TABLE. Used to signal to Tcl_GetIndexFromObj*() routines that the table in which lookups are done has a fleeting existence. Thus there is no value in caching any results, since the cache can never be useful. Improvement over existing hackery where cache is stored and then freed to avoid bogus results. Likely candidate to eventually push to the public interface. --- generic/tclFCmd.c | 10 ++-------- generic/tclIndexObj.c | 13 +++++++------ generic/tclInt.h | 9 +++++++++ 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/generic/tclFCmd.c b/generic/tclFCmd.c index bb814ea..80898fc 100644 --- a/generic/tclFCmd.c +++ b/generic/tclFCmd.c @@ -1079,12 +1079,9 @@ TclFileAttrsCmd( } if (Tcl_GetIndexFromObj(interp, objv[0], attributeStrings, - "option", 0, &index) != TCL_OK) { + "option", INDEX_TEMP_TABLE, &index) != TCL_OK) { goto end; } - if (attributeStringsAllocated != NULL) { - TclFreeIntRep(objv[0]); - } if (Tcl_FSFileAttrsGet(interp, index, filePtr, &objPtr) != TCL_OK) { goto end; @@ -1107,12 +1104,9 @@ TclFileAttrsCmd( for (i = 0; i < objc ; i += 2) { if (Tcl_GetIndexFromObj(interp, objv[i], attributeStrings, - "option", 0, &index) != TCL_OK) { + "option", INDEX_TEMP_TABLE, &index) != TCL_OK) { goto end; } - if (attributeStringsAllocated != NULL) { - TclFreeIntRep(objv[i]); - } if (i + 1 == objc) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "value for \"%s\" missing", TclGetString(objv[i]))); diff --git a/generic/tclIndexObj.c b/generic/tclIndexObj.c index 2281d22..c6873af 100644 --- a/generic/tclIndexObj.c +++ b/generic/tclIndexObj.c @@ -114,6 +114,7 @@ Tcl_GetIndexFromObj( int flags, /* 0 or TCL_EXACT */ int *indexPtr) /* Place to store resulting integer index. */ { + if (!(flags & INDEX_TEMP_TABLE)) { /* * See if there is a valid cached result from a previous lookup (doing the @@ -135,6 +136,7 @@ Tcl_GetIndexFromObj( return TCL_OK; } } + } return Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, sizeof(char *), msg, flags, indexPtr); } @@ -211,13 +213,8 @@ GetIndexFromObjList( tablePtr[objc] = NULL; result = Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, - sizeof(char *), msg, flags, indexPtr); - - /* - * The internal rep must be cleared since tablePtr will go away. - */ + sizeof(char *), msg, flags | INDEX_TEMP_TABLE, indexPtr); - TclFreeIntRep(objPtr); ckfree(tablePtr); return result; @@ -279,6 +276,7 @@ Tcl_GetIndexFromObjStruct( * See if there is a valid cached result from a previous lookup. */ + if (!(flags & INDEX_TEMP_TABLE)) { if (objPtr->typePtr == &indexType) { indexRep = objPtr->internalRep.twoPtrValue.ptr1; if (indexRep->tablePtr==tablePtr && indexRep->offset==offset) { @@ -286,6 +284,7 @@ Tcl_GetIndexFromObjStruct( return TCL_OK; } } + } /* * Lookup the value of the object in the table. Accept unique @@ -340,6 +339,7 @@ Tcl_GetIndexFromObjStruct( * operation. */ + if (!(flags & INDEX_TEMP_TABLE)) { if (objPtr->typePtr == &indexType) { indexRep = objPtr->internalRep.twoPtrValue.ptr1; } else { @@ -351,6 +351,7 @@ Tcl_GetIndexFromObjStruct( indexRep->tablePtr = (void *) tablePtr; indexRep->offset = offset; indexRep->index = index; + } *indexPtr = index; return TCL_OK; diff --git a/generic/tclInt.h b/generic/tclInt.h index 33476ed..4ecac7d 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2548,6 +2548,15 @@ typedef struct TclFileAttrProcs { } TclFileAttrProcs; /* + * Private flag value which controls Tcl_GetIndexFromObj*() routines + * to instruct them not to cache lookups because the table will not + * live long enough to make it worthwhile. Must not clash with public + * flag value TCL_EXACT. + */ + +#define INDEX_TEMP_TABLE 2 + +/* * Opaque handle used in pipeline routines to encapsulate platform-dependent * state. */ -- cgit v0.12