diff --git a/src/array.c b/src/array.c
index 7804a8d9e88126568bcee3c17331d16e34106fd2..ea9446b9358e0acdc59873679d9a76fe9548f2d7 100644
--- a/src/array.c
+++ b/src/array.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: array.c,v 1.142 2003/04/27 17:46:47 mast Exp $
+|| $Id: array.c,v 1.143 2003/04/28 00:32:42 mast Exp $
 */
 
 #include "global.h"
@@ -26,7 +26,7 @@
 #include "cyclic.h"
 #include "multiset.h"
 
-RCSID("$Id: array.c,v 1.142 2003/04/27 17:46:47 mast Exp $");
+RCSID("$Id: array.c,v 1.143 2003/04/28 00:32:42 mast Exp $");
 
 PMOD_EXPORT struct array empty_array=
 {
@@ -64,6 +64,14 @@ PMOD_EXPORT struct array weak_shrink_empty_array=
 struct array *gc_internal_array = &empty_array;
 static struct array *gc_mark_array_pos = 0;
 
+#ifdef TRACE_UNFINISHED_TYPE_FIELDS
+PMOD_EXPORT int accept_unfinished_type_fields = 0;
+PMOD_EXPORT void dont_accept_unfinished_type_fields (void *orig)
+{
+  accept_unfinished_type_fields = (int) orig;
+}
+#endif
+
 
 /* Allocate an array, this might be changed in the future to
  * allocate linked lists or something
@@ -89,8 +97,11 @@ PMOD_EXPORT struct array *low_allocate_array(ptrdiff_t size, ptrdiff_t extra_spa
   GC_ALLOC(v);
 
 
-  /* for now, we don't know what will go in here */
-  v->type_field=BIT_MIXED | BIT_UNFINISHED;
+  if (size)
+    /* for now, we don't know what will go in here */
+    v->type_field = BIT_MIXED | BIT_UNFINISHED;
+  else
+    v->type_field = 0;
   v->flags=0;
 
   v->malloced_size = DO_NOT_WARN((INT32)(size + extra_space));
@@ -1171,11 +1182,14 @@ PMOD_EXPORT void array_fix_type_field(struct array *v)
 
   if(v->flags & ARRAY_LVALUE)
   {
-    v->type_field=BIT_MIXED;
+    v->type_field=BIT_MIXED|BIT_UNFINISHED;
     return;
   }
 
-  for(e=0; e<v->size; e++) t |= 1 << ITEM(v)[e].type;
+  for(e=0; e<v->size; e++) {
+    check_svalue (ITEM(v) + e);
+    t |= 1 << ITEM(v)[e].type;
+  }
 
 #ifdef PIKE_DEBUG
   if(t & ~(v->type_field))
@@ -1199,6 +1213,13 @@ void array_check_type_field(struct array *v)
   if(v->flags & ARRAY_LVALUE)
     return;
 
+#ifdef TRACE_UNFINISHED_TYPE_FIELDS
+  if (v->type_field & BIT_UNFINISHED && !accept_unfinished_type_fields) {
+    fputs ("Array got an unfinished type field.\n", stderr);
+    describe_something (v, T_ARRAY, 2, 2, 0, NULL);
+  }
+#endif
+
   for(e=0; e<v->size; e++)
   {
     if(ITEM(v)[e].type > MAX_TYPE)
@@ -1973,7 +1994,9 @@ PMOD_EXPORT struct array *explode(struct pike_string *str,
       if(ret->size == ret->malloced_size)
       {
 	e=ret->size;
-	ret=resize_array(ret, e * 2);
+	ACCEPT_UNFINISHED_TYPE_FIELDS {
+	  ret=resize_array(ret, e * 2);
+	} END_ACCEPT_UNFINISHED_TYPE_FIELDS;
 	ret->size=e;
       }
 
@@ -1989,7 +2012,9 @@ PMOD_EXPORT struct array *explode(struct pike_string *str,
     if(ret->size == ret->malloced_size)
     {
       e=ret->size;
-      ret=resize_array(ret, e * 2);
+      ACCEPT_UNFINISHED_TYPE_FIELDS {
+	ret=resize_array(ret, e * 2);
+      } END_ACCEPT_UNFINISHED_TYPE_FIELDS;
       ret->size=e;
     }
 
@@ -2142,6 +2167,7 @@ PMOD_EXPORT struct array *reverse_array(struct array *a)
   ret=allocate_array_no_init(a->size,0);
   for(e=0;e<a->size;e++)
     assign_svalue_no_free(ITEM(ret)+e,ITEM(a)+a->size+~e);
+  ret->type_field = a->type_field;
   return ret;
 }
 
diff --git a/src/backend.cmod b/src/backend.cmod
index 6625f34313b9228e284464613aa17efc7d54968f..21d4741a8ba4c177fc05c76eb9658f511e3a70f5 100644
--- a/src/backend.cmod
+++ b/src/backend.cmod
@@ -2,11 +2,11 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: backend.cmod,v 1.41 2003/03/30 20:44:19 mast Exp $
+|| $Id: backend.cmod,v 1.42 2003/04/28 00:32:42 mast Exp $
 */
 
 #include "global.h"
-RCSID("$Id: backend.cmod,v 1.41 2003/03/30 20:44:19 mast Exp $");
+RCSID("$Id: backend.cmod,v 1.42 2003/04/28 00:32:42 mast Exp $");
 #include "fdlib.h"
 #include "backend.h"
 #include <errno.h>
@@ -1885,27 +1885,26 @@ PIKECLASS Backend
        {
 	 struct array *v;
 	 v=allocate_array_no_init(CALL(e)->args->size+2, 0);
-	 ITEM(v)[0].type=T_INT;
-	 ITEM(v)[0].subtype=NUMBER_NUMBER;
 	 ITEM(v)[0].u.integer=CALL(e)->tv.tv_sec - current_time.tv_sec;
 	 
 	 if(CALL(e)->caller)
 	 {
 	   ITEM(v)[1].type=T_OBJECT;
 	   add_ref(ITEM(v)[1].u.object=CALL(e)->caller);
+	   v->type_field = BIT_INT|BIT_OBJECT;
 	 }else{
-	   ITEM(v)[1].type=T_INT;
-	   ITEM(v)[1].subtype=NUMBER_NUMBER;
-	   ITEM(v)[1].u.integer=0;
+	   v->type_field = BIT_INT;
 	 }
-	 
-	 assign_svalues_no_free(ITEM(v)+2,
-				ITEM(CALL(e)->args),
-				CALL(e)->args->size,BIT_MIXED);
+
+	 v->type_field |=
+	   assign_svalues_no_free(ITEM(v)+2,
+				  ITEM(CALL(e)->args),
+				  CALL(e)->args->size,BIT_MIXED);
 	 
 	 ITEM(ret)[e].type=T_ARRAY;
 	 ITEM(ret)[e].u.array=v;
        }
+       ret->type_field = BIT_ARRAY;
        UNPROTECT_CALL_OUTS();
        return ret;
      }
diff --git a/src/builtin.cmod b/src/builtin.cmod
index 6381f6efc5bc5aaba1fd04f4326cb00f61a81a75..7742b31a6be779c50347607c4d8c070fb1e834a2 100644
--- a/src/builtin.cmod
+++ b/src/builtin.cmod
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: builtin.cmod,v 1.133 2003/04/27 16:17:33 mast Exp $
+|| $Id: builtin.cmod,v 1.134 2003/04/28 00:32:42 mast Exp $
 */
 
 #include "global.h"
@@ -857,7 +857,7 @@ PIKEFUN string function_name(program|function func)
 #ifdef PIKE_DEBUG
 	if (d_flag>5) {
 	  fprintf(stderr,
-		  "Failed to find symbol for program 0x%08p\n"
+		  "Failed to find symbol for program %p\n"
 		  "Parent program info:\n",
 		  func->u.program);
 	  dump_program_tables(func->u.program->parent, 0);
@@ -1492,15 +1492,18 @@ void low_backtrace(struct Pike_interpreter *i)
 
       if (numargs + varargs) {
 	bf->args = allocate_array_no_init(numargs + varargs, 0);
-	assign_svalues_no_free(bf->args->item, f->locals, numargs, BIT_MIXED);
+	bf->args->type_field =
+	  assign_svalues_no_free(bf->args->item, f->locals, numargs, BIT_MIXED);
 	if (varargs) {
-	  assign_svalues_no_free(bf->args->item + numargs,
-				 f->locals[numargs].u.array->item,
-				 varargs, BIT_MIXED);
+	  bf->args->type_field |=
+	    assign_svalues_no_free(bf->args->item + numargs,
+				   f->locals[numargs].u.array->item,
+				   varargs, BIT_MIXED);
 	}
       }
     }
   }
+  res->type_field = BIT_OBJECT;
   /* NOTE: res has already been pushed on the stack. */
 }
 
@@ -2750,6 +2753,7 @@ static void low_automap(int d,
   INT32 x,e,tmp,size=0x7fffffff;
   struct svalue *tmpargs=Pike_sp - args;
   struct array *ret;
+  TYPE_FIELD types;
 
   for(e=0;e<args;e++)
   {
@@ -2776,6 +2780,7 @@ static void low_automap(int d,
 #endif
 
   push_array(ret=allocate_array(size));
+  types = 0;
 
   for(x=0;x<size;x++)
   {
@@ -2799,9 +2804,10 @@ static void low_automap(int d,
       apply_svalue(fun,args);
     else
       low_automap(d+1,depth,fun,real_args,args);
-    dmalloc_touch_svalue(Pike_sp-1);
-    ITEM(ret)[x]=*--Pike_sp;
+    stack_pop_to_no_free (ITEM(ret) + x);
+    types |= 1 << ITEM(ret)[x].type;
   }
+  ret->type_field = types;
   stack_unlink(args);
 }
 
diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index 528f23876c19dbbd9047f467a8579166ebe62c7e..472e38629ca6a18fcaffdae0286e82d34109b575 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -2,11 +2,11 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: builtin_functions.c,v 1.489 2003/04/27 20:12:11 mast Exp $
+|| $Id: builtin_functions.c,v 1.490 2003/04/28 00:32:43 mast Exp $
 */
 
 #include "global.h"
-RCSID("$Id: builtin_functions.c,v 1.489 2003/04/27 20:12:11 mast Exp $");
+RCSID("$Id: builtin_functions.c,v 1.490 2003/04/28 00:32:43 mast Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -1787,9 +1787,11 @@ PMOD_EXPORT void f_all_constants(INT32 args)
 }
 
 /*! @decl array allocate(int size)
- *! @decl array allocate(int size, mixed zero)
+ *! @decl array allocate(int size, mixed init)
  *!
- *!   Allocate an array of @[size] elements and initialize them to @[zero].
+ *!   Allocate an array of @[size] elements. If @[init] is specified
+ *!   then each element is initialized by copying that value
+ *!   recursively.
  *!
  *! @seealso
  *!   @[sizeof()], @[aggregate()], @[arrayp()]
@@ -1812,11 +1814,18 @@ PMOD_EXPORT void f_allocate(INT32 args)
   if(args>1)
   {
     INT32 e;
+    struct svalue *init = Pike_sp - args + 1;
+    push_array (a);
     for(e=0;e<a->size;e++)
-      copy_svalues_recursively_no_free(a->item+e, Pike_sp-args+1, 1, 0);
+      copy_svalues_recursively_no_free(a->item+e, init, 1, 0);
+    a->type_field = 1 << init->type;
+    stack_pop_n_elems_keep_top (args);
+  }
+  else {
+    a->type_field = BIT_INT;
+    pop_n_elems(args);
+    push_array(a);
   }
-  pop_n_elems(args);
-  push_array(a);
 }
 
 /*! @decl object this_object(void|int level);
@@ -2206,10 +2215,10 @@ PMOD_EXPORT void f_indices(INT32 args)
     a=allocate_array_no_init(size,0);
     while(--size>=0)
     {
-      ITEM(a)[size].type=T_INT;
-      ITEM(a)[size].subtype=NUMBER_NUMBER;
+      /* Elements are already integers. */
       ITEM(a)[size].u.integer = DO_NOT_WARN((INT_TYPE)size);
     }
+    a->type_field = BIT_INT;
     break;
 
   case T_MAPPING:
@@ -2501,10 +2510,10 @@ PMOD_EXPORT void f_values(INT32 args)
     a = allocate_array_no_init(size,0);
     while(--size >= 0)
     {
-      ITEM(a)[size].type = T_INT;
-      ITEM(a)[size].subtype = NUMBER_NUMBER;
+      /* Elements are already integers. */
       ITEM(a)[size].u.integer = index_shared_string(Pike_sp[-args].u.string, size);
     }
+    a->type_field = BIT_INT;
     break;
 
   case T_ARRAY:
@@ -2523,10 +2532,10 @@ PMOD_EXPORT void f_values(INT32 args)
     a=allocate_array_no_init(size,0);
     while(--size>=0)
     {
-      ITEM(a)[size].type=T_INT;
-      ITEM(a)[size].subtype=NUMBER_NUMBER;
+      /* Elements are already integers. */
       ITEM(a)[size].u.integer=1;
     }
+    a->type_field = BIT_INT;
 #endif
     break;
 
@@ -3848,6 +3857,7 @@ PMOD_EXPORT void f_rows(INT32 args)
   INT32 e;
   struct array *a,*tmp;
   struct svalue *val;
+  TYPE_FIELD types;
 
   get_all_args("rows", args, "%*%a", &val, &tmp);
 
@@ -3856,21 +3866,27 @@ PMOD_EXPORT void f_rows(INT32 args)
   {
     struct svalue sval;
     tmp->type_field = BIT_MIXED | BIT_UNFINISHED;
+    types = 0;
     for(e=0;e<tmp->size;e++)
     {
       index_no_free(&sval, val, ITEM(tmp)+e);
+      types |= 1 << sval.type;
       free_svalue(ITEM(tmp)+e);
-      ITEM(tmp)[e]=sval;
+      move_svalue (ITEM(tmp) + e, &sval);
     }
+    tmp->type_field = types;
     stack_swap();
     pop_stack();
     return;
   }
 
   push_array(a=allocate_array(tmp->size));
-  
-  for(e=0;e<a->size;e++)
+  types = 0;
+  for(e=0;e<a->size;e++) {
     index_no_free(ITEM(a)+e, val, ITEM(tmp)+e);
+    types |= 1 << ITEM(a)[e].type;
+  }
+  a->type_field = types;
   
   Pike_sp--;
   dmalloc_touch_svalue(Pike_sp);
@@ -4624,10 +4640,10 @@ static void f_interleave_array(INT32 args)
       }
       nelems++;
     }
-    /* FIXME: Is this needed? Isn't T_INT default? */
     ITEM(min)[i].u.integer = low;
   }
 
+  min->type_field = T_INT;
   ref_push_array(order);
   f_sort(2);	/* Sort the order array on the minimum index */
 
@@ -4795,9 +4811,10 @@ static struct array *longest_ordered_sequence(struct array *a)
   res = low_allocate_array(top, 0); 
   while (ltop != -1)
   {
-    res->item[--top].u.integer = ltop;
+    ITEM(res)[--top].u.integer = ltop;
     ltop = links[ltop];
   }
+  res->type_field = T_INT;
 
   UNSET_ONERROR(tmp2);
   UNSET_ONERROR(tmp);
@@ -4846,6 +4863,7 @@ static struct array* diff_compare_table(struct array *a,struct array *b,int *u)
    struct mapping *map;
    struct svalue *pval;
    int i;
+   TYPE_FIELD types;
 
    if (u) {
      *u = 0;	/* Unique rows in array b */
@@ -4862,10 +4880,9 @@ static struct array* diff_compare_table(struct array *a,struct array *b,int *u)
 	 struct svalue val;
 	 val.type=T_ARRAY;
 	 val.u.array=low_allocate_array(1,1);
-	 val.u.array->item[0].type=T_INT;
-	 val.u.array->item[0].subtype=NUMBER_NUMBER;
-	 val.u.array->item[0].u.integer=i;
-	 mapping_insert(map,b->item+i,&val);
+	 ITEM(val.u.array)[0].u.integer=i;
+	 val.u.array->type_field = BIT_INT;
+	 mapping_insert(map,ITEM(b)+i,&val);
 	 free_svalue(&val);
 	 if (u) {
 	   (*u)++;
@@ -4881,21 +4898,25 @@ static struct array* diff_compare_table(struct array *a,struct array *b,int *u)
    }
 
    res=low_allocate_array(a->size,0);
+   types = 0;
 
    for (i=0; i<a->size; i++)
    {
       pval=low_mapping_lookup(map,a->item+i);
       if (!pval)
       {
-	 res->item[i].type=T_ARRAY;
-	 add_ref(res->item[i].u.array=&empty_array);
+	 ITEM(res)[i].type=T_ARRAY;
+	 add_ref(ITEM(res)[i].u.array=&empty_array);
+	 types |= BIT_ARRAY;
       }
       else
       {
-	 assign_svalue(res->item+i,pval);
+	 assign_svalue(ITEM(res)+i,pval);
+	 types |= 1 << ITEM(res)[i].type;
       }
    }
 
+   res->type_field = types;
    pop_stack();
    return res;
 }
@@ -5256,9 +5277,10 @@ static struct array *diff_longest_sequence(struct array *cmptbl, int blen)
        dml=stack[top-1];
        while (dml)
        {
-	  a->item[--top].u.integer=dml->x;
+	  ITEM(a)[--top].u.integer=dml->x;
 	  dml=dml->prev;
        }
+       a->type_field = BIT_INT;
    }
 
    free(stack);
@@ -5410,6 +5432,9 @@ static struct array *diff_dyn_longest_sequence(struct array *cmptbl, int blen)
 
   res = allocate_array(sz);
   if (!res) {
+    /* FIXME: This is never called, so there should probably be
+     * SET_ONERROR stuff somewhere. I can't find where dml_pool is
+     * initialized, though. /mast */
     int args = 0;
     if (dml_pool) {
       dml_free_pools(dml_pool);
@@ -5429,12 +5454,11 @@ static struct array *diff_dyn_longest_sequence(struct array *cmptbl, int blen)
 #ifdef DIFF_DEBUG
     fprintf(stderr, "  %02d: %d\n", i, dml->x);
 #endif /* DIFF_DEBUG */
-    res->item[i].type = T_INT;
-    res->item[i].subtype = 0;
     res->item[i].u.integer = dml->x;
     dml = dml->prev;
     i++;
   }
+  res->type_field = BIT_INT;
 #ifdef PIKE_DEBUG
   if (i != sz) {
     Pike_fatal("Consistency error in diff_dyn_longest_sequence()\n");
@@ -6284,8 +6308,14 @@ PMOD_EXPORT void f_object_variablep(INT32 args)
  *!   Remove elements that are duplicates.
  *!
  *! @returns
- *!   This function returns an copy of the array @[a] with all duplicate
- *!   values removed. The order of the values is kept in the result.
+ *!   This function returns an copy of the array @[a] with all
+ *!   duplicate values removed. The order of the values is kept in the
+ *!   result; it's always the first of several equal elements that is
+ *!   kept.
+ *!
+ *! @note
+ *!   Elements are compared with @[`==]. They are also hashed (see
+ *!   @[lfun::__hash] for further details if @[a] contains objects).
  */
 PMOD_EXPORT void f_uniq_array(INT32 args)
 {
@@ -6311,7 +6341,10 @@ PMOD_EXPORT void f_uniq_array(INT32 args)
   }
   dmalloc_touch_svalue(Pike_sp-1);
   Pike_sp--; /* keep the ref to 'b' */
-  b=resize_array(b,  j);
+  ACCEPT_UNFINISHED_TYPE_FIELDS {
+    b=resize_array(b,  j);
+  } END_ACCEPT_UNFINISHED_TYPE_FIELDS;
+  b->type_field = a->type_field;
   pop_n_elems(args-1); /* pop args and the mapping */
   push_array(b);
 }
@@ -6321,9 +6354,9 @@ PMOD_EXPORT void f_uniq_array(INT32 args)
  *!
  *!   Splice two or more arrays.
  *!
- *!   This means that the the array becomes an array of the first element
- *!   in the first given array, the first argument in next array and so on
- *!   for all arrays. Then the second elements are added, etc.
+ *!   This means that the returned array has the first element in the
+ *!   first given array, then the first argument in next array and so
+ *!   on for all arrays. Then the second elements are added, etc.
  *!
  *! @seealso
  *!   @[`/()], @[`*()], @[`+()], @[`-()], @[everynth()]
@@ -6334,10 +6367,6 @@ PMOD_EXPORT void f_splice(INT32 args)
   INT32 size=0x7fffffff;
   INT32 i,j,k;
 
-#ifdef PIKE_DEBUG
-  if(args < 0) Pike_fatal("Negative args to f_splice()\n");
-#endif
-
   for(i=0;i<args;i++)
     if (Pike_sp[i-args].type!=T_ARRAY) 
       SIMPLE_BAD_ARG_ERROR("splice", i+1, "array");
@@ -6380,6 +6409,7 @@ void f_everynth(INT32 args)
   INT32 start=0;
   struct array *a;
   struct array *ina;
+  TYPE_FIELD types;
   INT32 size=0;
 #ifdef PIKE_DEBUG
   if(args < 0) Pike_fatal("Negative args to f_everynth()\n");
@@ -6406,10 +6436,13 @@ void f_everynth(INT32 args)
   }
 
   a=allocate_array(((size=ina->size)-start+n-1)/n);
-  for(k=0; start<size; start+=n)
-    assign_svalue_no_free(a->item+(k++), ina->item+start);
+  types = 0;
+  for(k=0; start<size; k++, start+=n) {
+    assign_svalue_no_free(ITEM(a) + k, ina->item+start);
+    types |= 1 << ITEM(a)[k].type;
+  }
+  a->type_field=types;
 
-  a->type_field=ina->type_field;
   pop_n_elems(args);
   push_array(a);
   return;
@@ -6651,6 +6684,7 @@ PMOD_EXPORT void f_map_array(INT32 args)
   INT32 e;
   struct svalue *fun;
   struct array *ret,*foo;
+  TYPE_FIELD types;
 
   if (args < 2)
     SIMPLE_TOO_FEW_ARGS_ERROR("map_array", 2);
@@ -6662,16 +6696,18 @@ PMOD_EXPORT void f_map_array(INT32 args)
   fun=Pike_sp-args+1;
 
   ret=allocate_array(foo->size);
+  types = 0;
   SET_ONERROR(tmp, do_free_array, ret);
   for(e=0;e<foo->size;e++)
   {
-    push_svalue(foo->item+e);
+    push_svalue(ITEM(foo)+e);
     assign_svalues_no_free(Pike_sp,fun+1,args-2,-1);
     Pike_sp+=args-2;
     apply_svalue(fun,args-1);
-    ret->item[e]=*(--Pike_sp);
-    dmalloc_touch_svalue(Pike_sp);
+    stack_pop_to_no_free (ITEM(ret) + e);
+    types |= 1 << ITEM(ret)[e].type;
   }
+  ret->type_field = types;
   pop_n_elems(args);
   UNSET_ONERROR(tmp);
   push_array(ret);
@@ -6750,6 +6786,7 @@ PMOD_EXPORT void f_map(INT32 args)
    struct svalue *mysp;
    struct array *a,*d;
    int splice,i,n;
+   TYPE_FIELD types;
 
    if (args<1)
       SIMPLE_TOO_FEW_ARGS_ERROR("map", 1);
@@ -6901,15 +6938,17 @@ PMOD_EXPORT void f_map(INT32 args)
 	    n=Pike_sp[-1].u.integer;
 	    pop_stack();
 	    push_array(d=allocate_array(n));
+	    types = 0;
 	    stack_swap();
 	    for (i=0; i<n; i++)
 	    {
 	       stack_dup(); /* `[] */
 	       push_int(i);
 	       f_call_function(2);
-	       d->item[i]=*(--Pike_sp);
-	       dmalloc_touch_svalue(Pike_sp);
+	       stack_pop_to_no_free (ITEM(d) + i);
+	       types |= 1 << ITEM(d)->type;
 	    }
+	    d->type_field = types;
 	    pop_stack();
 	    free_svalue(mysp-3);
 	    mysp[-3]=*(--Pike_sp);
@@ -6945,6 +6984,7 @@ PMOD_EXPORT void f_map(INT32 args)
 	 /* ret[i]=fun(arr[i],@extra); */
          push_array(d=allocate_array(n));
 	 d=Pike_sp[-1].u.array;
+	 types = 0;
 
 	 if(mysp[-2].type == T_FUNCTION &&
 	    mysp[-2].subtype == FUNCTION_BUILTIN)
@@ -6962,20 +7002,20 @@ PMOD_EXPORT void f_map(INT32 args)
 	       (* fun)(1+splice);
 	       if(Pike_sp>spbase)
 	       {
-		 dmalloc_touch_svalue(Pike_sp-1);
-		 d->item[i]=*--Pike_sp;
+		 stack_pop_to_no_free (ITEM(d) + i);
+		 types |= 1 << ITEM(d)[i].type;
 		 pop_n_elems(Pike_sp-spbase);
 	       }
 	     }
 	   }else{
 	     for (i=0; i<n; i++)
 	     {
-	       push_svalue(a->item+i);
+	       push_svalue(ITEM(a)+i);
 	       (* fun)(1);
 	       if(Pike_sp>spbase)
 	       {
-		 dmalloc_touch_svalue(Pike_sp-1);
-		 d->item[i]=*--Pike_sp;
+		 stack_pop_to_no_free (ITEM(d) + i);
+		 types |= 1 << ITEM(d)[i].type;
 		 pop_n_elems(Pike_sp-spbase);
 	       }
 	     }
@@ -6983,7 +7023,7 @@ PMOD_EXPORT void f_map(INT32 args)
 	 }else{
 	   for (i=0; i<n; i++)
 	   {
-	     push_svalue(a->item+i);
+	     push_svalue(ITEM(a)+i);
 	     if (splice) 
 	     {
 	       add_ref_svalue(mysp-1);
@@ -6994,10 +7034,11 @@ PMOD_EXPORT void f_map(INT32 args)
 	     {
 	       apply_svalue(mysp-2,1);
 	     }
-	     dmalloc_touch_svalue(Pike_sp-1);
-	     d->item[i]=*--Pike_sp;
+	     stack_pop_to_no_free (ITEM(d) + i);
+	     types |= 1 << ITEM(d)[i].type;
 	   }
 	 }
+	 d->type_field = types;
 	 stack_pop_n_elems_keep_top(3); /* fun arr extra d -> d */
 	 return;
 
@@ -7012,10 +7053,10 @@ PMOD_EXPORT void f_map(INT32 args)
       case T_STRING:
 	 /* ret[i]=arr[i][fun](@extra); */
          push_array(d=allocate_array(n));
-	 d=Pike_sp[-1].u.array;
+	 types = 0;
 	 for (i=0; i<n; i++)
 	 {
-	    push_svalue(a->item+i);
+	    push_svalue(ITEM(a)+i);
 	    push_svalue(mysp-2);
 	    f_arrow(2);
 	    if(UNSAFE_IS_ZERO(Pike_sp-1))
@@ -7026,9 +7067,10 @@ PMOD_EXPORT void f_map(INT32 args)
 	    add_ref_svalue(mysp-1);
 	    push_array_items(mysp[-1].u.array);
 	    f_call_function(splice+1);
-	    d->item[i]=*--Pike_sp;
-	    dmalloc_touch_svalue(Pike_sp);
+	    stack_pop_to_no_free (ITEM(d) + i);
+	    types |= 1 << ITEM(d)[i].type;
 	 }
+	 d->type_field = types;
 	 stack_pop_n_elems_keep_top(3); /* fun arr extra d -> d */
 	 return;
 
@@ -7416,9 +7458,7 @@ void f_enumerate(INT32 args)
       push_array(d=allocate_array(n));
       for (i=0; i<n; i++)
       {
-	 d->item[i].u.integer=start;
-	 d->item[i].type=T_INT;
-	 d->item[i].subtype=NUMBER_NUMBER;
+	 ITEM(d)[i].u.integer=start;
 #ifdef AUTO_BIGNUM
 	 if ((step>0 && start+step<start) ||
 	     (step<0 && start+step>start)) /* overflow */
@@ -7435,6 +7475,7 @@ void f_enumerate(INT32 args)
 #endif
 	 start+=step;
       }
+      d->type_field = BIT_INT;
    }
    else if (args<=3 &&
 	    ((Pike_sp[1-args].type==T_INT ||
@@ -7457,19 +7498,22 @@ void f_enumerate(INT32 args)
 	 d->item[i].type=T_FLOAT;
 	 start+=step;
       }
+      d->type_field = BIT_FLOAT;
    }
    else
    {
+      TYPE_FIELD types = 0;
       get_all_args("enumerate", args, "%i", &n);
       if (n<0) SIMPLE_BAD_ARG_ERROR("enumerate",1,"int(0..)");
       if (args>4) pop_n_elems(args-4);
+      push_array(d=allocate_array(n));
       if (args<4)
       {
-	 push_array(d=allocate_array(n));
 	 push_svalue(Pike_sp-2); /* start */
 	 for (i=0; i<n; i++)
 	 {
-	    assign_svalue_no_free(d->item+i,Pike_sp-1);
+	    assign_svalue_no_free(ITEM(d)+i,Pike_sp-1);
+	    types |= 1 << ITEM(d)[i].type;
 	    if (i<n-1)
 	    {
 	       push_svalue(Pike_sp-4); /* step */
@@ -7479,11 +7523,11 @@ void f_enumerate(INT32 args)
       }
       else
       {
-	 push_array(d=allocate_array(n));
 	 push_svalue(Pike_sp-3); /* start */
 	 for (i=0; i<n; i++)
 	 {
-	    assign_svalue_no_free(d->item+i,Pike_sp-1);
+	    assign_svalue_no_free(ITEM(d)+i,Pike_sp-1);
+	    types |= 1 << ITEM(d)[i].type;
 	    if (i<n-1)
 	    {
 	       push_svalue(Pike_sp-3); /* function */
@@ -7493,6 +7537,7 @@ void f_enumerate(INT32 args)
 	    }
 	 }
       }
+      d->type_field = types;
       pop_stack();
       stack_pop_n_elems_keep_top(args);
    }
diff --git a/src/encode.c b/src/encode.c
index dd899c520f5b26f5fec6a885f1e1b69769ea307e..a62a26d10da150d051c40e09863461487e070dec 100644
--- a/src/encode.c
+++ b/src/encode.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: encode.c,v 1.171 2003/04/02 19:22:43 mast Exp $
+|| $Id: encode.c,v 1.172 2003/04/28 00:32:43 mast Exp $
 */
 
 #include "global.h"
@@ -27,7 +27,7 @@
 #include "bignum.h"
 #include "pikecode.h"
 
-RCSID("$Id: encode.c,v 1.171 2003/04/02 19:22:43 mast Exp $");
+RCSID("$Id: encode.c,v 1.172 2003/04/28 00:32:43 mast Exp $");
 
 /* #define ENCODE_DEBUG */
 
@@ -2161,6 +2161,7 @@ static void decode_value2(struct decode_data *data)
     case TAG_ARRAY:
     {
       struct array *a;
+      TYPE_FIELD types;
       if(num < 0)
 	Pike_error("Failed to decode array. (array size is negative)\n");
 
@@ -2174,13 +2175,14 @@ static void decode_value2(struct decode_data *data)
       SETUP_DECODE_MEMOBJ(T_ARRAY, array, a, allocate_array(num),
 			  free_svalues(ITEM(a), a->size, a->type_field));
 
+      types = 0;
       for(e=0;e<num;e++)
       {
 	decode_value2(data);
-	ITEM(a)[e]=Pike_sp[-1];
-	Pike_sp--;
-	dmalloc_touch_svalue(Pike_sp);
+	stack_pop_to_no_free (ITEM(a) + e);
+	types |= 1 << ITEM(a)[e].type;
       }
+      a->type_field = types;
       ref_push_array(a);
 #ifdef ENCODE_DEBUG
       data->depth -= 2;
@@ -2221,6 +2223,7 @@ static void decode_value2(struct decode_data *data)
     {
       struct multiset *m;
       struct array *a;
+      TYPE_FIELD types;
       if(num<0)
 	Pike_error("Failed to decode multiset. (multiset size is negative)\n");
 
@@ -2243,14 +2246,14 @@ static void decode_value2(struct decode_data *data)
       a=m->ind;
 #endif
 
+      types = 0;
       for(e=0;e<num;e++)
       {
 	decode_value2(data);
-	assign_svalue(a->item+e , Pike_sp-1);
-	pop_stack();
-	dmalloc_touch_svalue(Pike_sp);
+	stack_pop_to_no_free (ITEM(a) + e);
+	types |= 1 << ITEM(a)[e].type;
       }
-      array_fix_type_field(a);
+      a->type_field = types;
 #ifdef PIKE_NEW_MULTISETS
       {
 	struct multiset *l = mkmultiset (a);
@@ -2469,7 +2472,7 @@ static void decode_value2(struct decode_data *data)
 	  }
 	  /* Remove the extra entry from the stack. */
 	  ref_push_program(p);
-	  stack_pop_n_elems_keep_top(2);
+	  stack_pop_2_elems_keep_top();
 	  break;
 	}
 
diff --git a/src/interpret.c b/src/interpret.c
index e1a2739b3d06de0eb9665b4acb98fad268ae4da1..871f1385577a00275644a98dc23d395086ce4a3e 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -2,11 +2,11 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: interpret.c,v 1.303 2003/04/27 14:16:51 mast Exp $
+|| $Id: interpret.c,v 1.304 2003/04/28 00:32:43 mast Exp $
 */
 
 #include "global.h"
-RCSID("$Id: interpret.c,v 1.303 2003/04/27 14:16:51 mast Exp $");
+RCSID("$Id: interpret.c,v 1.304 2003/04/28 00:32:43 mast Exp $");
 #include "interpret.h"
 #include "object.h"
 #include "program.h"
@@ -301,11 +301,15 @@ void lvalue_to_svalue_no_free(struct svalue *to,struct svalue *lval)
     {
       INT32 e;
       struct array *a;
+      TYPE_FIELD types = 0;
       ONERROR err;
       a=allocate_array(lval[1].u.array->size>>1);
       SET_ONERROR(err, do_free_array, a);
-      for(e=0;e<a->size;e++)
-	lvalue_to_svalue_no_free(a->item+e, lval[1].u.array->item+(e<<1));
+      for(e=0;e<a->size;e++) {
+	lvalue_to_svalue_no_free(ITEM(a)+e, ITEM(lval[1].u.array)+(e<<1));
+	types |= 1 << ITEM(a)[e].type;
+      }
+      a->type_field = types;
       to->type = T_ARRAY;
       to->u.array=a;
       UNSET_ONERROR(err);
diff --git a/src/iterators.cmod b/src/iterators.cmod
index 220acb1c37eba57067349875f9d4643ebd237258..01de6dfe2619c501ff28e520ed1a1c371f8a3935 100644
--- a/src/iterators.cmod
+++ b/src/iterators.cmod
@@ -2,11 +2,11 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: iterators.cmod,v 1.40 2003/04/27 17:52:42 mast Exp $
+|| $Id: iterators.cmod,v 1.41 2003/04/28 00:32:43 mast Exp $
 */
 
 #include "global.h"
-RCSID("$Id: iterators.cmod,v 1.40 2003/04/27 17:52:42 mast Exp $");
+RCSID("$Id: iterators.cmod,v 1.41 2003/04/28 00:32:43 mast Exp $");
 #include "main.h"
 #include "object.h"
 #include "mapping.h"
@@ -1613,14 +1613,13 @@ PIKECLASS string_split_iterator
 		    }
 		  }
 		  split = allocate_array(num+1);
-		  split->item[0].type = T_INT;
 		  split->item[0].u.integer = split_val;
 		  for (i=0; i < num; i++) {
-		    split->item[i+1].type = T_INT;
 		    split->item[i+1].u.integer =
 		      index_shared_string((*from)->u.sval.u.array->
 					  item[i].u.string, 0);
-		  }		  
+		  }
+		  split->type_field = BIT_INT;
 		}
 		break;
 	      case F_APPLY:
@@ -1647,17 +1646,16 @@ PIKECLASS string_split_iterator
 		      return NULL;
 		    }
 		    split = allocate_array(num+1);
-		    split->item[0].type = T_INT;
 		    split->item[0].u.integer = split_val;
 		    tmp = CDR(*from);
 		    for (i = 1; tmp && (tmp->token == F_ARG_LIST);
 			 tmp = CDR(tmp)) {
 		      if (!CAR(tmp)) continue;
-		      split->item[i].type = T_INT;
 		      split->item[i].u.integer =
 			index_shared_string(CAR(tmp)->u.sval.u.string, 0);
 		      i++;
-		    }		    
+		    }
+		    split->type_field = BIT_INT;
 		  }
 		} else {
 		  return NULL;
diff --git a/src/main.c b/src/main.c
index 1afc16ba3c1632c67d070b91ed1619ce1574cb74..b786a93f6b39d5238722fceab42a5cc3e86b7d85 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2,11 +2,11 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: main.c,v 1.174 2003/04/12 23:32:46 nilsson Exp $
+|| $Id: main.c,v 1.175 2003/04/28 00:32:43 mast Exp $
 */
 
 #include "global.h"
-RCSID("$Id: main.c,v 1.174 2003/04/12 23:32:46 nilsson Exp $");
+RCSID("$Id: main.c,v 1.175 2003/04/28 00:32:43 mast Exp $");
 #include "fdlib.h"
 #include "backend.h"
 #include "module.h"
@@ -744,6 +744,7 @@ int dbm_main(int argc, char **argv)
       ITEM(a)[num].u.string=make_shared_string(argv[num]);
       ITEM(a)[num].type=T_STRING;
     }
+    a->type_field = BIT_STRING;
     push_array(a);
     
     for(num=0;environ[num];num++);
@@ -753,6 +754,7 @@ int dbm_main(int argc, char **argv)
       ITEM(a)[num].u.string=make_shared_string(environ[num]);
       ITEM(a)[num].type=T_STRING;
     }
+    a->type_field = BIT_STRING;
     push_array(a);
   
     apply(master(),"_main",2);
diff --git a/src/mapping.c b/src/mapping.c
index 85ad00061c4441096e016cd64b8d7eb8b8ed9807..bc2ac90386c6a3fe6e89c1090a2599dc02e81c83 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -2,11 +2,11 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: mapping.c,v 1.165 2003/04/01 18:10:21 nilsson Exp $
+|| $Id: mapping.c,v 1.166 2003/04/28 00:32:43 mast Exp $
 */
 
 #include "global.h"
-RCSID("$Id: mapping.c,v 1.165 2003/04/01 18:10:21 nilsson Exp $");
+RCSID("$Id: mapping.c,v 1.166 2003/04/28 00:32:43 mast Exp $");
 #include "main.h"
 #include "object.h"
 #include "mapping.h"
@@ -1247,6 +1247,7 @@ PMOD_EXPORT struct array *mapping_to_array(struct mapping *m)
       struct array *b=allocate_array(2);
       assign_svalue(b->item+0, & k->ind);
       assign_svalue(b->item+1, & k->val);
+      b->type_field = (1 << k->ind.type) | (1 << k->val.type);
       s->u.array=b;
       s->type=T_ARRAY;
       s++;
diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c
index 0afb1a52c07b5cc5123c43f67c58fb9919a54db9..2418f2e90a44302ca08edf94dd497f62f0f06d9f 100644
--- a/src/modules/files/efuns.c
+++ b/src/modules/files/efuns.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: efuns.c,v 1.126 2003/04/07 17:21:13 nilsson Exp $
+|| $Id: efuns.c,v 1.127 2003/04/28 00:32:43 mast Exp $
 */
 
 #include "global.h"
@@ -26,7 +26,7 @@
 #include "file_machine.h"
 #include "file.h"
 
-RCSID("$Id: efuns.c,v 1.126 2003/04/07 17:21:13 nilsson Exp $");
+RCSID("$Id: efuns.c,v 1.127 2003/04/28 00:32:43 mast Exp $");
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -110,12 +110,14 @@ struct array *encode_stat(PIKE_STAT_T *s)
 {
   struct array *a;
   a=allocate_array(7);
+  a->type_field = BIT_INT;
   ITEM(a)[0].u.integer=s->st_mode;
   switch(S_IFMT & s->st_mode)
   {
   case S_IFREG:
     push_int64((INT64)s->st_size);
-    ITEM(a)[1] = *(--sp);
+    stack_pop_to_no_free (ITEM(a) + 1);
+    if (ITEM(a)[1].type == T_OBJECT) a->type_field |= BIT_OBJECT;
     break;
     
   case S_IFDIR: ITEM(a)[1].u.integer=-2; break;
diff --git a/src/modules/system/memory.c b/src/modules/system/memory.c
index b319f5931ba3bed55168164335a5bab1627a3294..80ea9c6374ccfaf590c545010c1ab67d7fa4a504 100644
--- a/src/modules/system/memory.c
+++ b/src/modules/system/memory.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: memory.c,v 1.23 2003/03/29 11:25:40 marcus Exp $
+|| $Id: memory.c,v 1.24 2003/04/28 00:32:43 mast Exp $
 */
 
 /*! @module System
@@ -19,7 +19,7 @@
  *!	Don't blame Pike if you shoot your foot off.
  */
 #include "global.h"
-RCSID("$Id: memory.c,v 1.23 2003/03/29 11:25:40 marcus Exp $");
+RCSID("$Id: memory.c,v 1.24 2003/04/28 00:32:43 mast Exp $");
 
 #include "system_machine.h"
 
@@ -510,11 +510,10 @@ static void memory_cast(INT32 args)
       sv=ITEM(a);
       for (i=0; i<sz; i++)
       {
-	 sv->type=T_INT;
-	 sv->subtype=0;
 	 sv->u.integer=(((unsigned char*)(THIS->p)))[i];
 	 sv++;
       }
+      a->type_field = BIT_INT;
 
       push_array(a);
 
diff --git a/src/object.c b/src/object.c
index 5eb33f8db056206b8d61b7dd1f96e32a1733e187..04d507e791f71678ff65dbb46a97f9ca8c106bcd 100644
--- a/src/object.c
+++ b/src/object.c
@@ -2,11 +2,11 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: object.c,v 1.235 2003/03/30 20:26:49 mast Exp $
+|| $Id: object.c,v 1.236 2003/04/28 00:32:43 mast Exp $
 */
 
 #include "global.h"
-RCSID("$Id: object.c,v 1.235 2003/03/30 20:26:49 mast Exp $");
+RCSID("$Id: object.c,v 1.236 2003/04/28 00:32:43 mast Exp $");
 #include "object.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
@@ -1590,6 +1590,7 @@ PMOD_EXPORT struct array *object_indices(struct object *o)
 			 ID_FROM_INT(p,p->identifier_index[e])->name);
       ITEM(a)[e].type=T_STRING;
     }
+    a->type_field = BIT_STRING;
   }else{
     apply_lfun(o, LFUN__INDICES, 0);
     if(sp[-1].type != T_ARRAY)
@@ -1613,11 +1614,14 @@ PMOD_EXPORT struct array *object_values(struct object *o)
 
   if(FIND_LFUN(p,LFUN__VALUES)==-1)
   {
+    TYPE_FIELD types = 0;
     a=allocate_array_no_init(p->num_identifier_index,0);
     for(e=0;e<(int)p->num_identifier_index;e++)
     {
       low_object_index_no_free(ITEM(a)+e, o, p->identifier_index[e]);
+      types |= 1 << ITEM(a)[e].type;
     }
+    a->type_field = types;
   }else{
     apply_lfun(o, LFUN__VALUES, 0);
     if(sp[-1].type != T_ARRAY)
@@ -2196,6 +2200,7 @@ static void f_magic_indices (INT32 args)
 	copy_shared_string (ITEM(res)[i].u.string, ID_FROM_PTR (prog, ref)->name);
 	ITEM(res)[i++].type = T_STRING;
       }
+      res->type_field = BIT_STRING;
       sp[-1].u.array = resize_array (res, i);
       return;
     case 2:
@@ -2212,6 +2217,7 @@ static void f_magic_indices (INT32 args)
 			ID_FROM_INT (prog, prog->identifier_index[e])->name);
     ITEM(res)[e].type = T_STRING;
   }
+  res->type_field = BIT_STRING;
 }
 
 /*! @decl mixed ::_values()
@@ -2228,6 +2234,7 @@ static void f_magic_values (INT32 args)
   struct program *prog;
   struct inherit *inherit;
   struct array *res;
+  TYPE_FIELD types;
   int type = 0, e, i;
 
   if (args >= 1) {
@@ -2259,15 +2266,18 @@ static void f_magic_values (INT32 args)
       }
       pop_n_elems (args);
       push_array (res = allocate_array_no_init (prog->num_identifier_references, 0));
-      for (e = i = 0; e < (int) prog->num_identifier_references; e++) {
+      types = 0;
+      for (e = i = 0; e < (int) prog->num_identifier_references; e++, i++) {
 	struct reference *ref = prog->identifier_references + e;
 	struct identifier *id = ID_FROM_PTR (prog, ref);
 	if (ref->id_flags & ID_HIDDEN) continue;
 	if ((ref->id_flags & (ID_INHERITED|ID_PRIVATE)) ==
 	    (ID_INHERITED|ID_PRIVATE)) continue;
-	low_object_index_no_free (ITEM(res) + i++, obj,
+	low_object_index_no_free (ITEM(res) + i, obj,
 				  e + inherit->identifier_level);
+	types |= 1 << ITEM(res)[i].type;
       }
+      res->type_field = types;
       sp[-1].u.array = resize_array (res, i);
       return;
     case 2:
@@ -2280,9 +2290,13 @@ static void f_magic_values (INT32 args)
 
   pop_n_elems (args);
   push_array (res = allocate_array_no_init (prog->num_identifier_index, 0));
-  for (e = 0; e < (int) prog->num_identifier_index; e++)
+  types = 0;
+  for (e = 0; e < (int) prog->num_identifier_index; e++) {
     low_object_index_no_free (ITEM(res) + e, obj,
 			      prog->identifier_index[e] + inherit->identifier_level);
+    types |= 1 << ITEM(res)[e].type;
+  }
+  res->type_field = types;
 }
 
 /*! @endnamespace
diff --git a/src/opcodes.c b/src/opcodes.c
index 5a0fe8e75eb7e3d26b6f4881b74e8485806285ae..bf169839d0d101babeca2499eb806d2d92795d24 100644
--- a/src/opcodes.c
+++ b/src/opcodes.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: opcodes.c,v 1.144 2003/04/27 17:52:42 mast Exp $
+|| $Id: opcodes.c,v 1.145 2003/04/28 00:32:43 mast Exp $
 */
 
 #include "global.h"
@@ -30,7 +30,7 @@
 
 #define sp Pike_sp
 
-RCSID("$Id: opcodes.c,v 1.144 2003/04/27 17:52:42 mast Exp $");
+RCSID("$Id: opcodes.c,v 1.145 2003/04/28 00:32:43 mast Exp $");
 
 void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind)
 {
@@ -679,6 +679,7 @@ void o_cast(struct pike_type *type, INT32 run_time_type)
 	  ref_push_array(a);
 	}else{
 	  INT32 e;
+	  TYPE_FIELD types = 0;
 #ifdef PIKE_DEBUG
 	  struct svalue *save_sp=sp+1;
 #endif
@@ -689,9 +690,10 @@ void o_cast(struct pike_type *type, INT32 run_time_type)
 	  {
 	    push_svalue(tmp->item+e);
 	    o_cast(itype, run_time_itype);
-	    array_set_index(a,e,sp-1);
-	    pop_stack();
+	    stack_pop_to_no_free (ITEM(a) + e);
+	    types |= 1 << ITEM(a)[e].type;
 	  }
+	  a->type_field = types;
 #ifdef PIKE_DEBUG
 	  if(save_sp!=sp)
 	    Pike_fatal("o_cast left stack droppings.\n");
@@ -756,6 +758,7 @@ void o_cast(struct pike_type *type, INT32 run_time_type)
 #else  /* PIKE_NEW_MULTISETS */
 	  INT32 e;
 	  struct array *a;
+	  TYPE_FIELD types = 0;
 	  push_multiset(m=allocate_multiset(a=allocate_array(tmp->size)));
 	  
 	  SET_CYCLIC_RET(m);
@@ -764,9 +767,10 @@ void o_cast(struct pike_type *type, INT32 run_time_type)
 	  {
 	    push_svalue(tmp->item+e);
 	    o_cast(itype, run_time_itype);
-	    array_set_index(a,e,sp-1);
-	    pop_stack();
+	    stack_pop_to_no_free (ITEM(a) + e);
+	    types |= 1 << ITEM(a)[e].type;
 	  }
+	  a->type_field = types;
 	  order_multiset(m);
 #endif
 
diff --git a/src/operators.c b/src/operators.c
index fd62184a0636db76fa22a93e87bd42a09277c0f8..a6be98ef2334650ab463b48bb5fc9ee018507a22 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -2,12 +2,12 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: operators.c,v 1.176 2003/04/27 17:52:42 mast Exp $
+|| $Id: operators.c,v 1.177 2003/04/28 00:32:43 mast Exp $
 */
 
 #include "global.h"
 #include <math.h>
-RCSID("$Id: operators.c,v 1.176 2003/04/27 17:52:42 mast Exp $");
+RCSID("$Id: operators.c,v 1.177 2003/04/28 00:32:43 mast Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "multiset.h"
@@ -2135,11 +2135,11 @@ PMOD_EXPORT void o_multiply(void)
 	    assign_svalues_no_free(pos, ret->item, asize, ret->type_field);
 	  }
 	} else if (asize) {
-	  assign_svalues_no_free(pos,
-				 src->item,
-				 asize,
-				 src->type_field);
-	  array_fix_type_field(ret);
+	  ret->type_field =
+	    assign_svalues_no_free(pos,
+				   src->item,
+				   asize,
+				   src->type_field);
 	}
 	pop_n_elems(2);
 	push_array(ret);
diff --git a/src/post_modules/Unicode/unicode_module.cmod b/src/post_modules/Unicode/unicode_module.cmod
index 58efb38281514f157fd35e3e84f5bd8757a52581..000393611142359c1f853dce496cfe0cd407500a 100644
--- a/src/post_modules/Unicode/unicode_module.cmod
+++ b/src/post_modules/Unicode/unicode_module.cmod
@@ -2,13 +2,13 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: unicode_module.cmod,v 1.6 2002/10/21 17:06:55 marcus Exp $
+|| $Id: unicode_module.cmod,v 1.7 2003/04/28 00:32:43 mast Exp $
 */
 
 #include "global.h"
 #include "stralloc.h"
 #include "global.h"
-RCSID("$Id: unicode_module.cmod,v 1.6 2002/10/21 17:06:55 marcus Exp $");
+RCSID("$Id: unicode_module.cmod,v 1.7 2003/04/28 00:32:43 mast Exp $");
 #include "pike_macros.h"
 #include "interpret.h"
 #include "program.h"
@@ -38,6 +38,7 @@ static void push_words( int *d, struct words *w )
       make_shared_binary_string2( d+w->words[i].start,
 				  w->words[i].size );
   }
+  r->type_field = BIT_STRING;
   push_array( r );
   uc_words_free( w );
 }
diff --git a/src/post_modules/_ADT/circular_list.cmod b/src/post_modules/_ADT/circular_list.cmod
index 4c8821b30ea441120354cae97f32eba3cb05f767..fe630df3d45fd7503aac236e6f891c41d07ed6fb 100644
--- a/src/post_modules/_ADT/circular_list.cmod
+++ b/src/post_modules/_ADT/circular_list.cmod
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: circular_list.cmod,v 1.7 2003/04/08 15:53:57 jhs Exp $
+|| $Id: circular_list.cmod,v 1.8 2003/04/28 00:32:44 mast Exp $
 */
 
 #include "global.h"
@@ -305,10 +305,9 @@ PIKECLASS CircularList
     a=allocate_array_no_init(size,0);
     while(--size>=0)
     {
-      ITEM(a)[size].type=T_INT;
-      ITEM(a)[size].subtype=NUMBER_NUMBER;
       ITEM(a)[size].u.integer = DO_NOT_WARN((INT_TYPE)size);
     }
+    a->type_field = BIT_INT;
     RETURN a;
   }
 
@@ -704,14 +703,13 @@ PIKECLASS CircularList
  PIKEFUN mixed peekBack()
   {
     struct svalue ind;
-    struct svalue retval;
     if (THIS->size <= 0)
     {
       Pike_error("Can not peek an empty list.\n");
     }
     ind.u.integer=circ2array(THIS->size-1);
     ind.type =T_INT;
-    simple_array_index_no_free(&retval, THIS->a, &ind);
+    simple_array_index_no_free(Pike_sp, THIS->a, &ind);
     Pike_sp++;
   }
 
@@ -883,6 +881,7 @@ PIKECLASS CircularList
     if (arg->type == T_INT)
     {
       THIS->a =allocate_array_no_init(arg->u.integer, 0);
+      THIS->a->type_field = BIT_INT;
     }
     else if (arg->type == T_ARRAY)
     {
diff --git a/src/post_modules/_ADT/sequence.cmod b/src/post_modules/_ADT/sequence.cmod
index 5d65d6edfc179d26feff915d6c075d44923d2a2f..c725790c2bf4adf13912c929e3369ce95241be0e 100644
--- a/src/post_modules/_ADT/sequence.cmod
+++ b/src/post_modules/_ADT/sequence.cmod
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: sequence.cmod,v 1.7 2003/04/08 12:41:29 jhs Exp $
+|| $Id: sequence.cmod,v 1.8 2003/04/28 00:32:44 mast Exp $
 */
 
 #include "global.h"
@@ -276,10 +276,9 @@ PIKECLASS Sequence
     a=allocate_array_no_init(size,0);
     while(--size>=0)
     {
-      ITEM(a)[size].type=T_INT;
-      ITEM(a)[size].subtype=NUMBER_NUMBER;
       ITEM(a)[size].u.integer = DO_NOT_WARN((INT_TYPE)size);
     }
+    a->type_field = BIT_INT;
     RETURN a;
   }