diff --git a/src/interpret_functions.h b/src/interpret_functions.h
index 001864c483a1cadb4656d879135465e4f491eb42..4e95b499a983f04dcc568ea021b37c59a4cab5e3 100644
--- a/src/interpret_functions.h
+++ b/src/interpret_functions.h
@@ -509,24 +509,44 @@ OPCODE1(F_CLEAR_LOCAL, "clear local", 0, {
   SET_SVAL(Pike_fp->locals[arg1], PIKE_T_INT, NUMBER_NUMBER, integer, 0);
 });
 
-OPCODE2(F_ADD_LOCALS_AND_POP, "local += local", 0,{
+OPCODE2(F_ADD_LOCALS_AND_POP, "local += local", 0,
+{
   struct svalue *dst = Pike_fp->locals+arg1;
   struct svalue *src = Pike_fp->locals+arg2;
-  if( dst->type == PIKE_T_INT
-      && src->type == PIKE_T_INT
+  if( (dst->type|src->type) == PIKE_T_INT
       DO_IF_BIGNUM(
         &&(!INT_TYPE_ADD_OVERFLOW(src->u.integer,dst->u.integer))))
   {
     SET_SVAL_SUBTYPE(*dst,NUMBER_NUMBER);
     dst->u.integer += src->u.integer;
   }
+  else if( dst->type == src->type && dst->type == PIKE_T_STRING )
+  {
+      struct pike_string *srcs = src->u.string;
+      struct pike_string *dsts = dst->u.string;
+      if( dsts->len && srcs->len )
+      {
+          size_t tmp = dsts->len;
+          dsts = new_realloc_shared_string( dsts, tmp+srcs->len, MAX(srcs->size_shift,dsts->size_shift) );
+          update_flags_for_add( dsts, srcs );
+          pike_string_cpy(MKPCHARP_STR_OFF(dsts,tmp), srcs);
+          dst->u.string = low_end_shared_string( dsts );
+      }
+      else if( !dsts->len )
+      {
+          free_string( dsts );
+          dst->u.string = srcs;
+          srcs->refs++;
+          return;
+      }
+  }
   else
   {
-    push_svalue( dst );
+    *Pike_sp++ = *dst;
+    SET_SVAL_TYPE(*dst,PIKE_T_INT);
     push_svalue( src );
     f_add(2);
-    assign_svalue( Pike_fp->locals+arg1,Pike_sp-1);
-    pop_stack();
+    *dst = *--Pike_sp;
   }
 });
 
@@ -541,11 +561,11 @@ OPCODE2(F_ADD_LOCAL_INT_AND_POP, "local += number", 0,{
   }
   else
   {
-    push_svalue( dst );
+    *Pike_sp++ = *dst;
+    SET_SVAL_TYPE(*dst,PIKE_T_INT);
     push_int( arg2 );
     f_add(2);
-    assign_svalue( Pike_fp->locals+arg1,Pike_sp-1);
-    pop_stack();
+    *dst = *--Pike_sp;
   }
 });
 
@@ -561,80 +581,87 @@ OPCODE2(F_ADD_LOCAL_INT, "local += number local", 0,{
   }
   else
   {
-    push_svalue( dst );
+    *Pike_sp++ = *dst;
+    SET_SVAL_TYPE(*dst,PIKE_T_INT);
     push_int( arg2 );
     f_add(2);
-    assign_svalue( Pike_fp->locals+arg1,Pike_sp-1);
+    *dst = *--Pike_sp;
   }
 });
 
 OPCODE1(F_INC_LOCAL, "++local", I_UPDATE_SP, {
-  if( (TYPEOF(Pike_fp->locals[arg1]) == PIKE_T_INT)
+  struct svalue *dst = Pike_fp->locals+arg1;
+  if( (TYPEOF(*dst) == PIKE_T_INT)
       DO_IF_BIGNUM(
-      && (!INT_TYPE_ADD_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
+      && (!INT_TYPE_ADD_OVERFLOW(dst->u.integer, 1))
       )
       )
   {
-    push_int(++(Pike_fp->locals[arg1].u.integer));
-    SET_SVAL_SUBTYPE(Pike_fp->locals[arg1], NUMBER_NUMBER); /* Could have UNDEFINED there before. */
+    push_int(++dst->u.integer);
+    SET_SVAL_SUBTYPE(*dst, NUMBER_NUMBER); /* Could have UNDEFINED there before. */
   } else {
-    push_svalue(Pike_fp->locals+arg1);
+    *Pike_sp++ = *dst;
+    SET_SVAL_TYPE(*dst,PIKE_T_INT);
     push_int(1);
     f_add(2);
-    assign_svalue(Pike_fp->locals+arg1,Pike_sp-1);
+    assign_svalue(dst, Pike_sp-1);
   }
 });
 
 OPCODE1(F_POST_INC_LOCAL, "local++", I_UPDATE_SP, {
-  push_svalue( Pike_fp->locals + arg1);
-
-  if( (TYPEOF(Pike_fp->locals[arg1]) == PIKE_T_INT)
+  struct svalue *dst = Pike_fp->locals+arg1;
+  if( (TYPEOF(*dst) == PIKE_T_INT)
       DO_IF_BIGNUM(
-      && (!INT_TYPE_ADD_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
+      && (!INT_TYPE_ADD_OVERFLOW(dst->u.integer, 1))
       )
       )
   {
-    Pike_fp->locals[arg1].u.integer++;
-    SET_SVAL_SUBTYPE(Pike_fp->locals[arg1], NUMBER_NUMBER); /* Could have UNDEFINED there before. */
+    push_int( dst->u.integer++ );
+    SET_SVAL_SUBTYPE(*dst, NUMBER_NUMBER); /* Could have UNDEFINED there before. */
   } else {
-    push_svalue(Pike_fp->locals + arg1);
+    push_svalue( dst );
+    push_svalue( dst );
     push_int(1);
     f_add(2);
-    stack_pop_to(Pike_fp->locals + arg1);
+    stack_pop_to(dst);
   }
 });
 
 OPCODE1(F_INC_LOCAL_AND_POP, "++local and pop", 0, {
-  if( (TYPEOF(Pike_fp->locals[arg1]) == PIKE_T_INT)
+  struct svalue *dst = Pike_fp->locals+arg1;
+  if( (TYPEOF(*dst) == PIKE_T_INT)
       DO_IF_BIGNUM(
-      && (!INT_TYPE_ADD_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
+      && (!INT_TYPE_ADD_OVERFLOW(dst->u.integer, 1))
       )
       )
   {
-    Pike_fp->locals[arg1].u.integer++;
-    SET_SVAL_SUBTYPE(Pike_fp->locals[arg1], NUMBER_NUMBER); /* Could have UNDEFINED there before. */
+    dst->u.integer++;
+    SET_SVAL_SUBTYPE(*dst, NUMBER_NUMBER); /* Could have UNDEFINED there before. */
   } else {
-    push_svalue( Pike_fp->locals + arg1);
+    *Pike_sp++ = *dst;
+    SET_SVAL_TYPE(*dst,PIKE_T_INT);
     push_int(1);
     f_add(2);
-    stack_pop_to(Pike_fp->locals + arg1);
+    *dst = *--Pike_sp;
   }
 });
 
 OPCODE1(F_DEC_LOCAL, "--local", I_UPDATE_SP, {
-  if( (TYPEOF(Pike_fp->locals[arg1]) == PIKE_T_INT)
+  struct svalue *dst = Pike_fp->locals+arg1;
+  if( (TYPEOF(*dst) == PIKE_T_INT)
       DO_IF_BIGNUM(
-      && (!INT_TYPE_SUB_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
+      && (!INT_TYPE_SUB_OVERFLOW(dst->u.integer, 1))
       )
       )
   {
-    push_int(--(Pike_fp->locals[arg1].u.integer));
-    SET_SVAL_SUBTYPE(Pike_fp->locals[arg1], NUMBER_NUMBER); /* Could have UNDEFINED there before. */
+    push_int(--(dst->u.integer));
+    SET_SVAL_SUBTYPE(*dst, NUMBER_NUMBER); /* Could have UNDEFINED there before. */
   } else {
-    push_svalue(Pike_fp->locals+arg1);
+    *Pike_sp++ = *dst;
+    SET_SVAL_TYPE(*dst,PIKE_T_INT);
     push_int(1);
     o_subtract();
-    assign_svalue(Pike_fp->locals+arg1,Pike_sp-1);
+    assign_svalue(dst,Pike_sp-1);
   }
 });
 
@@ -658,19 +685,21 @@ OPCODE1(F_POST_DEC_LOCAL, "local--", I_UPDATE_SP, {
 });
 
 OPCODE1(F_DEC_LOCAL_AND_POP, "--local and pop", 0, {
-  if( (TYPEOF(Pike_fp->locals[arg1]) == PIKE_T_INT)
+  struct svalue *dst = Pike_fp->locals+arg1;
+  if( (TYPEOF(*dst) == PIKE_T_INT)
       DO_IF_BIGNUM(
-      && (!INT_TYPE_SUB_OVERFLOW(Pike_fp->locals[arg1].u.integer, 1))
+      && (!INT_TYPE_SUB_OVERFLOW(dst->u.integer, 1))
       )
       )
   {
-    Pike_fp->locals[arg1].u.integer--;
-    SET_SVAL_SUBTYPE(Pike_fp->locals[arg1], NUMBER_NUMBER); /* Could have UNDEFINED there before. */
+    --dst->u.integer;
+    SET_SVAL_SUBTYPE(*dst, NUMBER_NUMBER); /* Could have UNDEFINED there before. */
   } else {
-    push_svalue(Pike_fp->locals + arg1);
+    *Pike_sp++ = *dst;
+    SET_SVAL_TYPE(*dst,PIKE_T_INT);
     push_int(1);
     o_subtract();
-    stack_pop_to(Pike_fp->locals + arg1);
+    *dst = *--Pike_sp;
   }
 });