From d5ff54059dda1b7a925361e016193915d3e1cccd Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 28 Mar 2016 19:03:14 +0000 Subject: There's a "parsedVarName" Tcl_ObjType that remembers how a variable name breaks down into the name of an array and the name of an element. It has been storing them in an intrep as a Tcl_Obj holding the array name and an allocated string holding the element name. This branch revises the intrep strategy to use Tcl_Obj's to hold both parts. This reduces copying and seems to simplify the code. Also "nulled out" the UpdateStringProc for the type which can never be called. I think this is a better answer, but I'd like any other informed opinions. --- generic/tclVar.c | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/generic/tclVar.c b/generic/tclVar.c index 5574f30..3c1b01f 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -206,7 +206,9 @@ static Tcl_UpdateStringProc PanicOnUpdateVarName; static Tcl_FreeInternalRepProc FreeParsedVarName; static Tcl_DupInternalRepProc DupParsedVarName; +#if 0 static Tcl_UpdateStringProc UpdateParsedVarName; +#endif static Tcl_UpdateStringProc PanicOnUpdateVarName; static Tcl_SetFromAnyProc PanicOnSetVarName; @@ -237,7 +239,13 @@ static const Tcl_ObjType localVarNameType = { static const Tcl_ObjType tclParsedVarNameType = { "parsedVarName", - FreeParsedVarName, DupParsedVarName, UpdateParsedVarName, PanicOnSetVarName + FreeParsedVarName, DupParsedVarName, +#if 0 +UpdateParsedVarName, +#else +PanicOnUpdateVarName, +#endif + PanicOnSetVarName }; /* @@ -536,7 +544,9 @@ TclObjLookupVarEx( const char *errMsg = NULL; CallFrame *varFramePtr = iPtr->varFramePtr; const char *part2 = part2Ptr? TclGetString(part2Ptr):NULL; +#if 0 char *newPart2 = NULL; +#endif *arrayPtrPtr = NULL; if (typePtr == &localVarNameType) { @@ -583,9 +593,13 @@ TclObjLookupVarEx( } return NULL; } +#if 0 part2 = newPart2 = part1Ptr->internalRep.twoPtrValue.ptr2; if (newPart2) { part2Ptr = Tcl_NewStringObj(newPart2, -1); +#else + if ((part2Ptr = part1Ptr->internalRep.twoPtrValue.ptr2)) { +#endif if (createPart2) { Tcl_IncrRefCount(part2Ptr); } @@ -629,11 +643,15 @@ TclObjLookupVarEx( len2 = len1 - i - 2; len1 = i; +#if 0 newPart2 = ckalloc(len2 + 1); memcpy(newPart2, part2, (unsigned) len2); *(newPart2+len2) = '\0'; part2 = newPart2; part2Ptr = Tcl_NewStringObj(newPart2, -1); +#else + part2Ptr = Tcl_NewStringObj(part2, len2); +#endif if (createPart2) { Tcl_IncrRefCount(part2Ptr); } @@ -658,7 +676,12 @@ TclObjLookupVarEx( Tcl_IncrRefCount(part1Ptr); objPtr->internalRep.twoPtrValue.ptr1 = part1Ptr; +#if 0 objPtr->internalRep.twoPtrValue.ptr2 = (void *) part2; +#else + Tcl_IncrRefCount(part2Ptr); + objPtr->internalRep.twoPtrValue.ptr2 = part2Ptr; +#endif typePtr = part1Ptr->typePtr; part1 = TclGetString(part1Ptr); @@ -683,9 +706,11 @@ TclObjLookupVarEx( Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME", TclGetString(part1Ptr), NULL); } +#if 0 if (newPart2) { Tcl_DecrRefCount(part2Ptr); } +#endif return NULL; } @@ -734,9 +759,11 @@ TclObjLookupVarEx( *arrayPtrPtr = varPtr; varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr, flags, msg, createPart1, createPart2, varPtr, -1); +#if 0 if (newPart2) { Tcl_DecrRefCount(part2Ptr); } +#endif } return varPtr; } @@ -5592,11 +5619,11 @@ FreeParsedVarName( Tcl_Obj *objPtr) { register Tcl_Obj *arrayPtr = objPtr->internalRep.twoPtrValue.ptr1; - register char *elem = objPtr->internalRep.twoPtrValue.ptr2; + register Tcl_Obj *elem = objPtr->internalRep.twoPtrValue.ptr2; if (arrayPtr != NULL) { TclDecrRefCount(arrayPtr); - ckfree(elem); + TclDecrRefCount(elem); } objPtr->typePtr = NULL; } @@ -5607,17 +5634,11 @@ DupParsedVarName( Tcl_Obj *dupPtr) { register Tcl_Obj *arrayPtr = srcPtr->internalRep.twoPtrValue.ptr1; - register char *elem = srcPtr->internalRep.twoPtrValue.ptr2; - char *elemCopy; - unsigned elemLen; + register Tcl_Obj *elem = srcPtr->internalRep.twoPtrValue.ptr2; if (arrayPtr != NULL) { Tcl_IncrRefCount(arrayPtr); - elemLen = strlen(elem); - elemCopy = ckalloc(elemLen + 1); - memcpy(elemCopy, elem, elemLen); - *(elemCopy + elemLen) = '\0'; - elem = elemCopy; + Tcl_IncrRefCount(elem); } dupPtr->internalRep.twoPtrValue.ptr1 = arrayPtr; @@ -5625,6 +5646,7 @@ DupParsedVarName( dupPtr->typePtr = &tclParsedVarNameType; } +#if 0 static void UpdateParsedVarName( Tcl_Obj *objPtr) @@ -5659,6 +5681,7 @@ UpdateParsedVarName( *p++ = ')'; *p = '\0'; } +#endif /* *---------------------------------------------------------------------- -- cgit v0.12