Tcl Source Code

Artifact [7e9c3b735c]
Login

Artifact 7e9c3b735c90ba0ed0cfd5341e775f2fac490a4b:

Attachment "binconcat2.patch" to ticket [1953758fff] added by ferrieux 2008-06-29 16:06:58.
Index: generic/tclExecute.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclExecute.c,v
retrieving revision 1.373
diff -b -u -r1.373 tclExecute.c
--- generic/tclExecute.c	13 Jun 2008 05:45:10 -0000	1.373
+++ generic/tclExecute.c	29 Jun 2008 08:57:08 -0000
@@ -2122,19 +2122,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
@@ -2158,6 +2181,8 @@
 	 */
 
 	objResultPtr = OBJ_AT_DEPTH(opnd-1);
+	if (!onlyb)
+	    {
 	bytes = TclGetStringFromObj(objResultPtr, &length);
 #if !TCL_COMPILE_DEBUG
 	if (bytes != tclEmptyStringRep && !Tcl_IsShared(objResultPtr)) {
@@ -2191,6 +2216,37 @@
 	}
 	*p = '\0';
 
+	    } else {
+
+	    bytes = (char *) Tcl_GetByteArrayFromObj(objResultPtr, &length);
+#if !TCL_COMPILE_DEBUG
+		if (!Tcl_IsShared(objResultPtr)) {
+		    bytes = (char *) Tcl_SetByteArrayLength(objResultPtr,length+appendLen);
+		    p = bytes + length;
+		    currPtr = &OBJ_AT_DEPTH(opnd - 2);
+		} else {
+#endif
+		    TclNewObj(objResultPtr);
+		    bytes = (char *) 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 = (char *) Tcl_GetByteArrayFromObj(*currPtr, &length);
+		    memcpy(p, bytes, (size_t) length);
+		    p += length;
+		}
+	   }
+
 	TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr);
 	NEXT_INST_V(2, opnd, 1);
     }