Tcl Source Code

Artifact [c1a3cc1ebc]
Login

Artifact c1a3cc1ebcd9d909ccc9027d7d834a3e4b910a12:

Attachment "binconcat.patch" to ticket [1953758fff] added by ferrieux 2008-04-29 06:47:35.
--- tcl8.5.1-orig/generic/tclExecute.c	Mon Feb  4 20:24:55 2008
+++ tcl8.5.1/generic/tclExecute.c	Mon Apr 28 23:28:47 2008
@@ -2020,19 +2020,42 @@
 	int opnd, length, appendLen = 0;
 	char *bytes, *p;
 	Tcl_Obj **currPtr;
+	int onlyb ;
 
 	opnd = TclGetUInt1AtPtr(pc+1);
 
 	/*
+	 * Detect only-bytearray-or-null case
+	 */
+	onlyb = 1;
+	for (currPtr=&OBJ_AT_DEPTH(opnd-1); currPtr<=&OBJ_AT_TOS; currPtr++) {
+	    if (((*currPtr)->typePtr != &tclByteArrayType)
+		&&((*currPtr)->bytes != tclEmptyStringRep))
+		{onlyb=0;break;}
+	}
+
+	/*
 	 * Compute the length to be appended.
 	 */
 
+	if (onlyb)
+	    {
+		for (currPtr=&OBJ_AT_DEPTH(opnd-2); currPtr<=&OBJ_AT_TOS; currPtr++) {
+		    if ((*currPtr)->bytes == tclEmptyStringRep)
+			continue; /* don't shimmer nulls */
+		    Tcl_GetByteArrayFromObj(*currPtr, &length);
+		    appendLen += length;
+		}
+	    }
+	else 
+	    {
 	for (currPtr=&OBJ_AT_DEPTH(opnd-2); currPtr<=&OBJ_AT_TOS; currPtr++) {
 	    bytes = TclGetStringFromObj(*currPtr, &length);
 	    if (bytes != NULL) {
 		appendLen += length;
 	    }
 	}
+	    }
 
 	/*
 	 * If nothing is to be appended, just return the first object by
@@ -2056,6 +2079,8 @@
 	 */
 
 	objResultPtr = OBJ_AT_DEPTH(opnd-1);
+	if (!onlyb)
+	    {
 	bytes = TclGetStringFromObj(objResultPtr, &length);
 #if !TCL_COMPILE_DEBUG
 	if (bytes != tclEmptyStringRep && !Tcl_IsShared(objResultPtr)) {
@@ -2088,6 +2113,37 @@
 	    }
 	}
 	*p = '\0';
+		
+	    } else {
+
+	    	bytes = Tcl_GetByteArrayFromObj(objResultPtr, &length);
+#if !TCL_COMPILE_DEBUG
+		if (!Tcl_IsShared(objResultPtr)) {
+		    bytes = Tcl_SetByteArrayLength(objResultPtr,length+appendLen);
+		    p = bytes + length;
+		    currPtr = &OBJ_AT_DEPTH(opnd - 2);
+		} else {
+#endif
+		    TclNewObj(objResultPtr);
+		    bytes = Tcl_SetByteArrayLength(objResultPtr,length+appendLen);
+		    p = bytes;
+		    currPtr = &OBJ_AT_DEPTH(opnd - 1);
+#if !TCL_COMPILE_DEBUG
+		}
+#endif
+		
+		/*
+		 * Append the remaining characters.
+		 */
+		
+		for (; currPtr <= &OBJ_AT_TOS; currPtr++) {
+		    if ((*currPtr)->bytes == tclEmptyStringRep)
+			continue; /* don't shimmer nulls */
+		    bytes = Tcl_GetByteArrayFromObj(*currPtr, &length);
+		    memcpy(p, bytes, (size_t) length);
+		    p += length;
+		}
+	   }
 
 	TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr);
 	NEXT_INST_V(2, opnd, 1);