diff --git a/src/operators.c b/src/operators.c
index 9ceb7370284d25f85dfcbfbb6711d694c97bfa79..1264daa7f834377865c358b784d3dcdb687add95 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -5,7 +5,7 @@
 \*/
 #include <math.h>
 #include "global.h"
-RCSID("$Id: operators.c,v 1.6 1997/01/28 03:10:22 hubbe Exp $");
+RCSID("$Id: operators.c,v 1.7 1997/02/11 07:11:51 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "multiset.h"
@@ -87,6 +87,7 @@ void f_add(INT32 args)
   {
     struct pike_string *r;
     char *buf;
+    INT32 tmp;
 
     switch(args)
     {
@@ -95,50 +96,21 @@ void f_add(INT32 args)
       size=0;
       for(e=-args;e<0;e++) size+=sp[e].u.string->len;
 
-#if 1
-      if(sp[-args].u.string->refs==1)
-      {
-	struct pike_string *tmp=sp[-args].u.string;
-
-	unlink_pike_string(tmp);
-	r=(struct pike_string *)realloc((char *)tmp,
-					sizeof(struct pike_string)+size);
-	
-	if(!r)
-	{
-	  r=begin_shared_string(size);
-	  MEMCPY(r->str, sp[-args].u.string->str, sp[-args].u.string->len);
-	  free((char *)r);
-	}
-
-	buf=r->str + r->len;
-	r->len=size;
-	r->str[size]=0;
-
-	for(e=-args+1;e<0;e++)
-	{
-	  MEMCPY(buf,sp[e].u.string->str,sp[e].u.string->len);
-	  buf+=sp[e].u.string->len;
-	}
-	sp[-args].u.string=end_shared_string(r);
-	for(e=-args+1;e<0;e++) free_string(sp[e].u.string);
-	sp-=args-1;
-	return;
-      }
-#endif
-      r=begin_shared_string(size);
-      buf=r->str;
-      for(e=-args;e<0;e++)
+      tmp=sp[-args].u.string->len;
+      r=realloc_shared_string(sp[-args].u.string,size);
+      sp[-args].type=T_INT;
+      buf=r->str+tmp;
+      for(e=-args+1;e<0;e++)
       {
 	MEMCPY(buf,sp[e].u.string->str,sp[e].u.string->len);
 	buf+=sp[e].u.string->len;
       }
-      r=end_shared_string(r);
+      sp[-args].u.string=end_shared_string(r);
+      sp[-args].type=T_STRING;
+      for(e=-args+1;e<0;e++) free_string(sp[e].u.string);
+      sp-=args-1;
     }
 
-    for(e=-args;e<0;e++) free_string(sp[e].u.string);
-    sp-=args;
-    push_string(r);
     break;
   }
 
diff --git a/src/stralloc.c b/src/stralloc.c
index 104729e4f890b0a34f659ebac306fdf195212ba2..6a721a935c194d7476d3e40f8a71244cf7ac2087 100644
--- a/src/stralloc.c
+++ b/src/stralloc.c
@@ -447,6 +447,39 @@ int my_strcmp(struct pike_string *a,struct pike_string *b)
   return low_binary_strcmp(a->str,a->len,b->str,b->len);
 }
 
+struct pike_string *realloc_unlinked_string(struct pike_string *a, INT32 size)
+{
+  struct pike_string *r;
+  r=(struct pike_string *)realloc((char *)a,
+					sizeof(struct pike_string)+size);
+	
+  if(!r)
+  {
+    r=begin_shared_string(size);
+    MEMCPY(r->str, a->str, a->len);
+    free((char *)a);
+  }
+
+  r->len=size;
+  r->str[size]=0;
+  return r;
+}
+
+/* Returns an unlinked string ready for end_shared_string */
+struct pike_string *realloc_shared_string(struct pike_string *a, INT32 size)
+{
+  struct pike_string *r;
+  if(a->refs==1)
+  {
+    unlink_pike_string(a);
+    return realloc_unlinked_string(a, size);
+  }else{
+    r=begin_shared_string(size);
+    MEMCPY(r->str, a->str, a->len);
+    return r;
+  }
+}
+
 /*** Add strings ***/
 struct pike_string *add_shared_strings(struct pike_string *a,
 					 struct pike_string *b)
diff --git a/src/stralloc.h b/src/stralloc.h
index 22b5fe0a961f43fc2156bb56454c09413022e714..aeb3b12cf50d4a62c817a3e487b5543ce2c43bfe 100644
--- a/src/stralloc.h
+++ b/src/stralloc.h
@@ -52,6 +52,8 @@ int low_quick_binary_strcmp(char *a,INT32 alen,
 			    char *b,INT32 blen);
 int my_quick_strcmp(struct pike_string *a,struct pike_string *b);
 int my_strcmp(struct pike_string *a,struct pike_string *b);
+struct pike_string *realloc_unlinked_string(struct pike_string *a, INT32 size);
+struct pike_string *realloc_shared_string(struct pike_string *a, INT32 size);
 struct pike_string *add_shared_strings(struct pike_string *a,
 					 struct pike_string *b);
 struct pike_string *string_replace(struct pike_string *str,