diff --git a/src/array.c b/src/array.c
index 0af45d6b64c55c82b839742219fd4de5ccda6cf8..4e6d8ffbc9c90375076d629bc9c633ba41b40793 100644
--- a/src/array.c
+++ b/src/array.c
@@ -23,18 +23,28 @@
 #include "stuff.h"
 #include "bignum.h"
 
-RCSID("$Id: array.c,v 1.105 2001/04/30 17:31:28 mast Exp $");
+RCSID("$Id: array.c,v 1.106 2001/06/06 02:22:38 mast Exp $");
 
 PMOD_EXPORT struct array empty_array=
 {
   PIKE_CONSTANT_MEMOBJ_INIT(1), /* Never free */
-  &empty_array,          /* Next */
-  &empty_array,          /* previous (circular) */
+  &weak_empty_array,     /* Next */
+  &weak_shrink_empty_array, /* previous (circular) */
   0,                     /* Size = 0 */
   0,                     /* malloced Size = 0 */
   0,                     /* no types */
   0,			 /* no flags */
 };
+PMOD_EXPORT struct array weak_empty_array=
+{
+  PIKE_CONSTANT_MEMOBJ_INIT(1),
+  &weak_shrink_empty_array, &empty_array, 0, 0, 0, ARRAY_WEAK_FLAG
+};
+PMOD_EXPORT struct array weak_shrink_empty_array=
+{
+  PIKE_CONSTANT_MEMOBJ_INIT(1),
+  &empty_array, &weak_empty_array, 0, 0, 0, ARRAY_WEAK_FLAG|ARRAY_WEAK_SHRINK
+};
 
 struct array *gc_internal_array = &empty_array;
 static struct array *gc_mark_array_pos = 0;
@@ -101,8 +111,8 @@ static void array_free_no_free(struct array *v)
 PMOD_EXPORT void really_free_array(struct array *v)
 {
 #ifdef PIKE_DEBUG
-  if(v == & empty_array)
-    fatal("Tried to free the empty_array.\n");
+  if(v == & empty_array || v == &weak_empty_array || v == &weak_shrink_empty_array)
+    fatal("Tried to free some *_empty_array.\n");
 #endif
 
 #ifdef PIKE_DEBUG
@@ -122,6 +132,26 @@ PMOD_EXPORT void do_free_array(struct array *a)
     free_array(a);
 }
 
+PMOD_EXPORT struct array *array_set_flags(struct array *a, int flags)
+{
+  if (a->size)
+    a->flags = flags;
+  else {
+    free_array(a);
+    switch (flags) {
+      case 0:
+	add_ref(a = &empty_array); break;
+      case ARRAY_WEAK_FLAG:
+	add_ref(a = &weak_empty_array); break;
+      case ARRAY_WEAK_FLAG|ARRAY_WEAK_SHRINK:
+	add_ref(a = &weak_shrink_empty_array); break;
+      default:
+	fatal("Invalid flags %x\n", flags);
+    }
+  }
+  return a;
+}
+
 /*
  * Extract an svalue from an array
  */
@@ -1981,7 +2011,8 @@ void gc_mark_array_as_referenced(struct array *a)
   int e;
   if(gc_mark(a)) {
 #ifdef PIKE_DEBUG
-    if (a == &empty_array) fatal("Trying to gc mark empty_array.\n");
+    if (a == &empty_array || a == &weak_empty_array || a == &weak_shrink_empty_array)
+      fatal("Trying to gc mark some *_empty_array.\n");
 #endif
 
     if (a == gc_mark_array_pos)
@@ -2048,7 +2079,8 @@ void real_gc_cycle_check_array(struct array *a, int weak)
   GC_CYCLE_ENTER(a, weak) {
     int e;
 #ifdef PIKE_DEBUG
-    if (a == &empty_array) fatal("Trying to gc cycle check empty_array.\n");
+    if (a == &empty_array || a == &weak_empty_array || a == &weak_shrink_empty_array)
+      fatal("Trying to gc cycle check some *_empty_array.\n");
 #endif
 
     if (a->type_field & BIT_COMPLEX)
@@ -2110,6 +2142,8 @@ void gc_mark_all_arrays(void)
 {
   gc_mark_array_pos = gc_internal_array;
   gc_mark(&empty_array);
+  gc_mark(&weak_empty_array);
+  gc_mark(&weak_shrink_empty_array);
   while (gc_mark_array_pos != &empty_array) {
     struct array *a = gc_mark_array_pos;
 #ifdef PIKE_DEBUG
@@ -2145,7 +2179,7 @@ void gc_free_all_unreferenced_arrays(void)
 {
   struct array *a,*next;
 
-  for (a = gc_internal_array; a != &empty_array; a = next)
+  for (a = gc_internal_array; a != &weak_empty_array; a = next)
   {
 #ifdef PIKE_DEBUG
     if (!a)
@@ -2193,7 +2227,10 @@ void debug_dump_array(struct array *a)
 	  a->flags,
 	  a->size,
 	  a->malloced_size,
-	  a == &empty_array ? " (the empty_array)" : "");
+	  a == &empty_array ? " (the empty_array)" :
+	  a == &weak_empty_array ? " (the weak_empty_array)" :
+	  a == &weak_shrink_empty_array ? " (the weak_shrink_empty_array)" :
+	  "");
   fprintf(stderr,"Type field = ");
   debug_dump_type_field(a->type_field);
   fprintf(stderr,"\n");
@@ -2211,7 +2248,8 @@ void zap_all_arrays(void)
   {
 
 #if defined(PIKE_DEBUG) && defined(DEBUG_MALLOC)
-    if(verbose_debug_exit && a!=&empty_array)
+    if(verbose_debug_exit && a!=&empty_array &&
+       a!=&weak_empty_array && a!=&weak_shrink_empty_array)
       describe(a);
 #endif
     
@@ -2231,7 +2269,7 @@ void count_memory_in_arrays(INT32 *num_, INT32 *size_)
 {
   INT32 num=0, size=0;
   struct array *m;
-  for(m=empty_array.next;m!=&empty_array;m=m->next)
+  for(m=empty_array.next;m!=&weak_empty_array;m=m->next)
   {
     num++;
     size+=sizeof(struct array)+
diff --git a/src/array.h b/src/array.h
index 54ad7cfc0d810aa939d302be3ba516e235348e50..aa8f74e5c20b8e0555d04f2db05a40451ab7e33b 100644
--- a/src/array.h
+++ b/src/array.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: array.h,v 1.34 2001/04/30 17:31:29 mast Exp $
+ * $Id: array.h,v 1.35 2001/06/06 02:22:39 mast Exp $
  */
 #ifndef ARRAY_H
 #define ARRAY_H
@@ -34,7 +34,7 @@ struct array
 #define ARRAY_LVALUE 4
 #define ARRAY_WEAK_SHRINK 8
 
-PMOD_EXPORT extern struct array empty_array;
+PMOD_EXPORT extern struct array empty_array, weak_empty_array, weak_shrink_empty_array;
 extern struct array *gc_internal_array;
 
 #if defined(DEBUG_MALLOC) && defined(PIKE_DEBUG)
@@ -90,6 +90,7 @@ typedef short_cmpfun (*cmpfun_getter)(TYPE_T);
 PMOD_EXPORT struct array *low_allocate_array(ptrdiff_t size, ptrdiff_t extra_space);
 PMOD_EXPORT void really_free_array(struct array *v);
 PMOD_EXPORT void do_free_array(struct array *a);
+PMOD_EXPORT struct array *array_set_flags(struct array *a, int flags);
 PMOD_EXPORT void array_index_no_free(struct svalue *s,struct array *v,INT32 index);
 PMOD_EXPORT void array_index(struct svalue *s,struct array *v,INT32 index);
 PMOD_EXPORT void simple_array_index_no_free(struct svalue *s,
@@ -180,6 +181,8 @@ PMOD_EXPORT struct array *explode_array(struct array *a, struct array *b);
 PMOD_EXPORT struct array *implode_array(struct array *a, struct array *b);
 /* Prototypes end here */
 
+#define array_get_flags(a) ((a)->flags)
+
 #define gc_cycle_check_array(X, WEAK) \
   gc_cycle_enqueue((gc_cycle_check_cb *) real_gc_cycle_check_array, (X), (WEAK))
 
diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index 50172187dee3201a9d87a16185f53bbbe68cbf85..7b9db9a6d163a4a2b5a82562c3cd35e1705b9d31 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: builtin_functions.c,v 1.372 2001/06/05 10:11:52 hubbe Exp $");
+RCSID("$Id: builtin_functions.c,v 1.373 2001/06/06 02:22:39 mast Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -3370,6 +3370,7 @@ void f_set_weak_flag(INT32 args)
 {
   struct svalue *s;
   INT_TYPE ret;
+  int flags;
 
   get_all_args("set_weak_flag",args,"%*%i",&s,&ret);
 
@@ -3378,17 +3379,19 @@ void f_set_weak_flag(INT32 args)
   switch(s->type)
   {
     case T_ARRAY:
-      SETFLAG(s->u.array->flags,ARRAY_WEAK_FLAG,ret & PIKE_WEAK_VALUES);
+      flags = array_get_flags(s->u.array);
+      SETFLAG(flags,ARRAY_WEAK_FLAG,ret & PIKE_WEAK_VALUES);
+      s->u.array = array_set_flags(s->u.array, flags);
       break;
-    case T_MAPPING: {
-      int flags = mapping_get_flags(s->u.mapping);
+    case T_MAPPING:
+      flags = mapping_get_flags(s->u.mapping);
       flags = (flags & ~PIKE_WEAK_BOTH) | (ret & PIKE_WEAK_BOTH);
       mapping_set_flags(s->u.mapping, flags);
       break;
-    }
     case T_MULTISET:
-      SETFLAG(s->u.multiset->ind->flags,(ARRAY_WEAK_FLAG|ARRAY_WEAK_SHRINK),
-	      ret & PIKE_WEAK_INDICES);
+      flags = array_get_flags(s->u.multiset->ind);
+      SETFLAG(flags,(ARRAY_WEAK_FLAG|ARRAY_WEAK_SHRINK), ret & PIKE_WEAK_INDICES);
+      s->u.multiset->ind = array_set_flags(s->u.multiset->ind, flags);
       break;
     default:
       SIMPLE_BAD_ARG_ERROR("set_weak_flag",1,"array|mapping|multiset");
diff --git a/src/gc.c b/src/gc.c
index bce638854090358abcfb303447c8d6b7873265b2..35b1753a3100fcc9d9358816ae7bffc1169dbec9 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -30,7 +30,7 @@ struct callback *gc_evaluator_callback=0;
 
 #include "block_alloc.h"
 
-RCSID("$Id: gc.c,v 1.151 2001/05/19 05:30:18 mast Exp $");
+RCSID("$Id: gc.c,v 1.152 2001/06/06 02:22:39 mast Exp $");
 
 /* Run garbage collect approximately every time
  * 20 percent of all arrays, objects and programs is
@@ -95,7 +95,7 @@ RCSID("$Id: gc.c,v 1.151 2001/05/19 05:30:18 mast Exp $");
 #define GC_VERBOSE_DO(X)
 #endif
 
-INT32 num_objects = 1;		/* Account for empty_array. */
+INT32 num_objects = 3;		/* Account for *_empty_array. */
 INT32 num_allocs =0;
 ptrdiff_t alloc_threshold = MIN_ALLOC_THRESHOLD;
 PMOD_EXPORT int Pike_in_gc = 0;