diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2012-02-16 13:51:02 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2012-02-16 13:51:02 (GMT) |
commit | b4ca6b5a992c406bbf4f3ef73ecb5ae2a8d878a6 (patch) | |
tree | b94afa1b480c83e5095e24e1d8596e4c76b8708a /generic/tclExecute.c | |
parent | 182448a5403990b1f583b5f9cf6cf6d8e2b7c8de (diff) | |
download | tcl-b4ca6b5a992c406bbf4f3ef73ecb5ae2a8d878a6.zip tcl-b4ca6b5a992c406bbf4f3ef73ecb5ae2a8d878a6.tar.gz tcl-b4ca6b5a992c406bbf4f3ef73ecb5ae2a8d878a6.tar.bz2 |
* generic/tclExecute.c (INST_LIST_RANGE_IMM): Enhance implementation
so that shortening a (not multiply-referenced) list by lopping the end
off with [lrange] or [lreplace] is efficient.
Diffstat (limited to 'generic/tclExecute.c')
-rw-r--r-- | generic/tclExecute.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 92b6612..e402634 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -4310,12 +4310,33 @@ TEBCresume( */ if (fromIdx<=toIdx && fromIdx<objc && toIdx>=0) { - if (fromIdx<0) { + if (fromIdx < 0) { fromIdx = 0; } if (toIdx >= objc) { toIdx = objc-1; } + if (fromIdx == 0 && toIdx != objc-1 && !Tcl_IsShared(valuePtr)) { + /* + * BEWARE! This is looking inside the implementation of the + * list type. + */ + + List *listPtr = valuePtr->internalRep.twoPtrValue.ptr1; + + if (listPtr->refCount == 1) { + TRACE(("\"%.30s\" %d %d => ", O2S(valuePtr), + TclGetInt4AtPtr(pc+1), TclGetInt4AtPtr(pc+5))); + for (index=toIdx+1 ; index<objc-1 ; index++) { + TclDecrRefCount(objv[index]); + } + listPtr->elemCount = toIdx+1; + listPtr->canonicalFlag = 1; + TclInvalidateStringRep(valuePtr); + TRACE_APPEND(("%.30s\n", O2S(valuePtr))); + NEXT_INST_F(9, 0, 0); + } + } objResultPtr = Tcl_NewListObj(toIdx-fromIdx+1, objv+fromIdx); } else { TclNewObj(objResultPtr); @@ -5716,7 +5737,7 @@ TEBCresume( } result = TclIncrObj(interp, valuePtr, value2Ptr); if (result == TCL_OK) { - Tcl_InvalidateStringRep(dictPtr); + TclInvalidateStringRep(dictPtr); } TclDecrRefCount(value2Ptr); } |