diff --git a/src/Makefile.in b/src/Makefile.in
index a80a14d09b99305943e36046fa9abba0b428f5ff..5d5b002114e6f67b567be5bd2c44793ab9a73ac4 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -67,6 +67,7 @@ MAKE_FLAGS = "prefix=$(prefix)" "exec_prefix=$(exec_prefix)" "CC=$(CC)" "OTHERFL
 OBJ= \
  language.o \
  constants.o \
+ cyclic.o \
  array.o \
  backend.o \
  builtin_functions.o \
diff --git a/src/array.c b/src/array.c
index db9d2e1acb1441ebb128f71ed58d15acba12a171..202c61c614824235435f02b554a12769af8924f9 100644
--- a/src/array.c
+++ b/src/array.c
@@ -27,6 +27,7 @@ struct array empty_array=
   0,                     /* Size = 0 */
   0,                     /* malloced Size = 0 */
   0,                     /* no types */
+  0,			 /* no flags */
 };
 
 
@@ -143,8 +144,8 @@ void array_index(struct svalue *s,struct array *v,INT32 index)
   free_array(v);
 }
 
-
-void simple_array_index_no_free(struct svalue *s,struct array *a,struct svalue *ind)
+void simple_array_index_no_free(struct svalue *s,
+				struct array *a,struct svalue *ind)
 {
   INT32 i;
   switch(ind->type)
@@ -164,7 +165,7 @@ void simple_array_index_no_free(struct svalue *s,struct array *a,struct svalue *
       s[0]=sp[-1];
       sp--;
       break;
-
+	
     default:
       error("Index is not an integer.\n");
   }
diff --git a/src/array.h b/src/array.h
index 96f97c20bcb97827c696e36da74e817fe5b1918d..009bccf099f1088f25fd22c0f82a000ae19f286f 100644
--- a/src/array.h
+++ b/src/array.h
@@ -20,9 +20,11 @@ struct array
 			 * Bits can be set that don't exist in the array
 			 * though.
 			 */
+  INT16 flags;          /* ARRAY_* flags */
   struct svalue item[1];
 };
 
+#define ARRAY_CYCLIC 1
 
 extern struct array empty_array;
 
diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index b61d3f0cda196637643833b0756164c0446b2e28..dbf0874dc5cdcd042531bb36e4248586965af107 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: builtin_functions.c,v 1.45 1997/09/11 02:13:10 hubbe Exp $");
+RCSID("$Id: builtin_functions.c,v 1.46 1997/10/03 02:25:35 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -35,6 +35,7 @@ RCSID("$Id: builtin_functions.c,v 1.45 1997/09/11 02:13:10 hubbe Exp $");
 #include "module_support.h"
 #include "module.h"
 #include "opcodes.h"
+#include "cyclic.h"
 
 #ifdef HAVE_CRYPT_H
 #include <crypt.h>
@@ -1294,6 +1295,7 @@ void f_column(INT32 args)
 {
   INT32 e;
   struct array *a,*tmp;
+  DECLARE_CYCLIC();
 
   if(args < 2)
     error("Too few arguments to column().\n");
@@ -1302,14 +1304,23 @@ void f_column(INT32 args)
     error("Bad argument 1 to column().\n");
 
   tmp=sp[-args].u.array;
-  push_array(a=allocate_array(tmp->size));
+  if((a=(struct array *)BEGIN_CYCLIC(tmp,0)))
+  {
+    a->refs++;
+    pop_n_elems(args);
+    push_array(a);
+  }else{
+    push_array(a=allocate_array(tmp->size));
+    SET_CYCLIC_RET(a);
 
-  for(e=0;e<a->size;e++)
-    index_no_free(ITEM(a)+e, ITEM(tmp)+e, sp-args);
+    for(e=0;e<a->size;e++)
+      index_no_free(ITEM(a)+e, ITEM(tmp)+e, sp-args);
 
-  a->refs++;
-  pop_n_elems(args+1);
-  push_array(a);
+    END_CYCLIC();
+    a->refs++;
+    pop_n_elems(args+1);
+    push_array(a);
+  }
 }
 
 #ifdef DEBUG
diff --git a/src/cyclic.c b/src/cyclic.c
new file mode 100644
index 0000000000000000000000000000000000000000..cb8a7395a25d5a26914efeb647a2cc8732808403
--- /dev/null
+++ b/src/cyclic.c
@@ -0,0 +1,65 @@
+#include "cyclic.h"
+
+#define CYCLIC_HASH_SIZE 4711
+
+CYCLIC *cyclic_hash[CYCLIC_HASH_SIZE];
+
+void unlink_cyclic(CYCLIC *c)
+{
+  unsigned int h;
+  CYCLIC **p;
+  h=(int)c->id;
+  h*=33;
+  h|=(int)c->a;
+  h*=33;
+  h|=(int)c->b;
+  h*=33;
+  h|=(int)c->th;
+  h*=33;
+  h%=CYCLIC_HASH_SIZE;
+
+  for(p=cyclic_hash+h;*p;p=&(p[0]->next))
+  {
+    if(c == *p)
+    {
+      *p=c->next;
+      UNSET_ONERROR(c->onerr);
+      return;
+    }
+  }
+  fatal("Unlink cyclic on lost cyclic struct.\n");
+}
+
+void *begin_cyclic(CYCLIC *c,
+		   void *id,
+		   void *th,
+		   void *a,
+		   void *b)
+{
+  unsigned int h;
+  CYCLIC *p;
+
+  h=(int)id;
+  h*=33;
+  h|=(int)a;
+  h*=33;
+  h|=(int)b;
+  h*=33;
+  h|=(int)th;
+  h*=33;
+  h%=CYCLIC_HASH_SIZE;
+
+  for(p=cyclic_hash[h];p;p=p->next)
+    if(a == p->a && b==p->b && id==p->id)
+      return p->ret;
+
+  c->ret=(void *)1;
+  c->a=a;
+  c->b=b;
+  c->id=id;
+  c->th=th;
+  c->next=cyclic_hash[h];
+  cyclic_hash[h]=c;
+  SET_ONERROR(c->onerr, unlink_cyclic, &c);
+  return 0;
+}
diff --git a/src/cyclic.h b/src/cyclic.h
new file mode 100644
index 0000000000000000000000000000000000000000..374948d5f174ca1af5103b10706b4439ef30286e
--- /dev/null
+++ b/src/cyclic.h
@@ -0,0 +1,39 @@
+#ifndef CYCLIC_H
+#define CYCLIC_H
+
+#include "error.h"
+#include "threads.h"
+
+typedef struct CYCLIC
+{
+  ONERROR onerr;
+  void *th;
+  void *id,*a,*b;
+  void *ret;
+  struct CYCLIC *next;
+} CYCLIC;
+
+
+#define DECLARE_CYCLIC() \
+  static char cyclic_identifier__; \
+  CYCLIC cyclic_struct__
+
+#define BEGIN_CYCLIC(A,B) \
+   begin_cyclic(&cyclic_struct__, &cyclic_identifier__, th_self(), (void *)(A), (void *)(B))
+
+#define SET_CYCLIC_RET(RET) \
+   cyclic_struct__.ret=(void *)(RET)
+
+#define END_CYCLIC()  unlink_cyclic(&cyclic_struct__)
+
+/* Prototypes begin here */
+void unlink_cyclic(CYCLIC *c);
+void *begin_cyclic(CYCLIC *c,
+		   void *id,
+		   void *thread,
+		   void *a,
+		   void *b);
+/* Prototypes end here */
+
+#endif /* CYCLIC_H */
+
diff --git a/src/testsuite.in b/src/testsuite.in
index 2b901081da4c8a23c48010e93239614da0dc9ab4..4c55135a4dda8a55ce78053c14c9a3010419ba07 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,4 +1,4 @@
-test_true([["$Id: testsuite.in,v 1.55 1997/09/29 00:57:55 hubbe Exp $"]])
+test_true([["$Id: testsuite.in,v 1.56 1997/10/03 02:25:37 hubbe Exp $"]])
 test_eq(1e1,10.0)
 test_eq(1E1,10.0)
 test_eq(1e+1,10.0)
@@ -10,7 +10,7 @@ test_eq("\x20","\040")
 test_eq(class { static int foo=17; }()->foo,0)
 test_eval_error(class { static int foo=17; }()->foo=18;)
 test_equal( [[ ({ (["foo":"bar"]), (<"foo">), ([]) })->foo ]], [[ ({"bar",1,0}) ]])
-test_eval_error([[mixed a=({([]),0}); a[1]=a; return a->foo;]])
+test_any([[mixed a=({([]),0}); a[1]=a; return a->foo[0];]],0)
 
 test_any([[
 class p1 { int foo() { return 1; }};
diff --git a/src/threads.h b/src/threads.h
index 0f223848e36bdd9460c264d6f1d638336b738525..cfe2e395298567e2fd1878dab481f4b30a36ade1 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -279,6 +279,7 @@ void th_cleanup(void);
 #define th_init()
 #define th_cleanup()
 #define th_init_programs()
+#define th_self() ((void*)0)
 #endif /* _REENTRANT */