summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2016-10-13 16:56:23 (GMT)
committerdgp <dgp@users.sourceforge.net>2016-10-13 16:56:23 (GMT)
commitc98e9eebb58e1b55ba13f8af8714a8a1e580d746 (patch)
treec39ef5c763275e6a9d929d7ab59e5579ca1fdb1b
parent6293f8f90ba51c630d5e941443b9ca582ba23357 (diff)
parent23b011c32d44c8182e0a04316704b590bd2920dd (diff)
downloadtcl-c98e9eebb58e1b55ba13f8af8714a8a1e580d746.zip
tcl-c98e9eebb58e1b55ba13f8af8714a8a1e580d746.tar.gz
tcl-c98e9eebb58e1b55ba13f8af8714a8a1e580d746.tar.bz2
Merge INST_STR_REPLACE fixes and improvements.
-rw-r--r--generic/tclExecute.c127
-rw-r--r--generic/tclStringObj.c10
2 files changed, 52 insertions, 85 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index df36958..85e059b 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -19,7 +19,6 @@
#include "tclCompile.h"
#include "tclOOInt.h"
#include "tommath.h"
-#include "tclStringRep.h"
#include <math.h>
#include <assert.h>
@@ -5731,51 +5730,29 @@ TEBCresume(
if (length3 - 1 == toIdx - fromIdx) {
unsigned char *bytes1, *bytes2;
- /*
- * Flush the info in the string internal rep that refers to the
- * about-to-be-invalidated UTF-8 rep. This indicates that a new
- * buffer needs to be allocated, and assumes that the value is
- * already of tclStringTypePtr type, which should be true provided
- * we call it after Tcl_GetUnicodeFromObj.
- */
-#define MarkStringInternalRepForFlush(objPtr) \
- (GET_STRING(objPtr)->allocated = 0)
-
if (Tcl_IsShared(valuePtr)) {
objResultPtr = Tcl_DuplicateObj(valuePtr);
- if (TclIsPureByteArray(objResultPtr)
- && TclIsPureByteArray(value3Ptr)) {
- bytes1 = Tcl_GetByteArrayFromObj(objResultPtr, NULL);
- bytes2 = Tcl_GetByteArrayFromObj(value3Ptr, NULL);
- memcpy(bytes1 + fromIdx, bytes2, length3);
- } else {
- ustring1 = Tcl_GetUnicodeFromObj(objResultPtr, NULL);
- ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
- memcpy(ustring1 + fromIdx, ustring2,
- length3 * sizeof(Tcl_UniChar));
- MarkStringInternalRepForFlush(objResultPtr);
- }
- Tcl_InvalidateStringRep(objResultPtr);
- TclDecrRefCount(value3Ptr);
- TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
- NEXT_INST_F(1, 1, 1);
} else {
- if (TclIsPureByteArray(valuePtr)
- && TclIsPureByteArray(value3Ptr)) {
- bytes1 = Tcl_GetByteArrayFromObj(valuePtr, NULL);
- bytes2 = Tcl_GetByteArrayFromObj(value3Ptr, NULL);
- memcpy(bytes1 + fromIdx, bytes2, length3);
- } else {
- ustring1 = Tcl_GetUnicodeFromObj(valuePtr, NULL);
- ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
- memcpy(ustring1 + fromIdx, ustring2,
- length3 * sizeof(Tcl_UniChar));
- MarkStringInternalRepForFlush(valuePtr);
- }
- Tcl_InvalidateStringRep(valuePtr);
- TclDecrRefCount(value3Ptr);
- TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
+ objResultPtr = valuePtr;
+ }
+ if (TclIsPureByteArray(objResultPtr)
+ && TclIsPureByteArray(value3Ptr)) {
+ bytes1 = Tcl_GetByteArrayFromObj(objResultPtr, NULL);
+ bytes2 = Tcl_GetByteArrayFromObj(value3Ptr, NULL);
+ memcpy(bytes1 + fromIdx, bytes2, length3);
+ } else {
+ ustring1 = Tcl_GetUnicodeFromObj(objResultPtr, NULL);
+ ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
+ memcpy(ustring1 + fromIdx, ustring2,
+ length3 * sizeof(Tcl_UniChar));
+ }
+ Tcl_InvalidateStringRep(objResultPtr);
+ TclDecrRefCount(value3Ptr);
+ TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+ if (objResultPtr == valuePtr) {
NEXT_INST_F(1, 0, 0);
+ } else {
+ NEXT_INST_F(1, 1, 1);
}
}
@@ -5791,57 +5768,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);
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index e3cede6..2930fa1 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -2948,6 +2948,16 @@ UpdateStringOfString(
{
String *stringPtr = GET_STRING(objPtr);
+ /*
+ * This routine is only called when we need to generate the
+ * string rep objPtr->bytes because it does not exist -- it is NULL.
+ * In that circumstance, any lingering claim about the size of
+ * memory pointed to by that NULL pointer is clearly bogus, and
+ * needs a reset.
+ */
+
+ stringPtr->allocated = 0;
+
if (stringPtr->numChars == 0) {
TclInitStringRep(objPtr, tclEmptyStringRep, 0);
} else {