From 61df5f46580699c45d9263e3e98a0cf3f2006672 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 13 Oct 2016 15:37:45 +0000 Subject: Streamline the substring copying case of [string replace] bytecode execution. --- generic/tclExecute.c | 66 ++++++++++++++++++---------------------------------- 1 file changed, 23 insertions(+), 43 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 34d92d3..cd27f6b 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5804,57 +5804,37 @@ TEBCresume( * Remove substring using copying. */ - if (length3 == 0) { - if (fromIdx > 0) { - objResultPtr = Tcl_NewUnicodeObj(ustring1, fromIdx); - if (toIdx < length) { - Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1, - length - toIdx); - } - } else { - objResultPtr = Tcl_NewUnicodeObj(ustring1 + toIdx + 1, - length - toIdx); - } - TclDecrRefCount(value3Ptr); - TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr))); - NEXT_INST_F(1, 1, 1); - } - - /* - * Splice string pieces by full copying. - */ - + objResultPtr = NULL; if (fromIdx > 0) { objResultPtr = Tcl_NewUnicodeObj(ustring1, fromIdx); - Tcl_AppendObjToObj(objResultPtr, value3Ptr); - if (toIdx < length) { - Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1, - length - toIdx); + } + if (length3 > 0) { + if (objResultPtr) { + Tcl_AppendObjToObj(objResultPtr, value3Ptr); + } else if (Tcl_IsShared(value3Ptr)) { + objResultPtr = Tcl_DuplicateObj(value3Ptr); + } else { + objResultPtr = value3Ptr; } - } else if (Tcl_IsShared(value3Ptr)) { - objResultPtr = Tcl_DuplicateObj(value3Ptr); - if (toIdx < length) { + } + if (toIdx < length) { + if (objResultPtr) { Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1, length - toIdx); - } - } else { - /* - * Be careful with splicing the stack in this case; we have a - * refCount:1 object in value3Ptr and we want to append to it and - * make it be the refCount:1 object at the top of the stack - * afterwards. [Bug 82e7f67325] - */ - - if (toIdx < length) { - Tcl_AppendUnicodeToObj(value3Ptr, ustring1 + toIdx + 1, + } else { + objResultPtr = Tcl_NewUnicodeObj(ustring1 + toIdx + 1, length - toIdx); } - TRACE_APPEND(("\"%.30s\"\n", O2S(value3Ptr))); - TclDecrRefCount(valuePtr); - OBJ_AT_TOS = value3Ptr; /* Tricky! */ - NEXT_INST_F(1, 0, 0); } - TclDecrRefCount(value3Ptr); + if (objResultPtr == NULL) { + /* This has to be the case [string replace $s 0 end {}] */ + /* which has result {} which is same as value3Ptr. */ + objResultPtr = value3Ptr; + } + if (objResultPtr != value3Ptr) { + /* See [Bug 82e7f67325] */ + TclDecrRefCount(value3Ptr); + } TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr))); NEXT_INST_F(1, 1, 1); -- cgit v0.12