diff --git a/src/array.c b/src/array.c
index b1274c4b26ffab34dc8d034072995c53ea457d11..3bda19735a273dbd25dce0d860053ae2a51772df 100644
--- a/src/array.c
+++ b/src/array.c
@@ -20,8 +20,9 @@
 #include "gc.h"
 #include "main.h"
 #include "security.h"
+#include "stuff.h"
 
-RCSID("$Id: array.c,v 1.53 1999/08/21 23:21:06 noring Exp $");
+RCSID("$Id: array.c,v 1.54 1999/09/16 23:56:08 hubbe Exp $");
 
 struct array empty_array=
 {
@@ -1349,7 +1350,26 @@ int check_that_array_is_constant(struct array *a)
 {
   array_fix_type_field(a);
   if(a->type_field & (BIT_FUNCTION | BIT_OBJECT))
-    return 0;
+  {
+    int e;
+    for(e=0;e<a->size;e++)
+    {
+      switch(ITEM(a)[e].type)
+      {
+	case T_FUNCTION:
+	  if(ITEM(a)[e].subtype == FUNCTION_BUILTIN) continue;
+	  /* Fall through */
+	case T_OBJECT:
+	  if(ITEM(a)[e].u.object -> next == ITEM(a)[e].u.object)
+	  {
+	    /* This is a fake object used during the
+	     * compilation!
+	     */
+	    return 0;
+	  }
+      }
+    }
+  }
   return 1;
 }
 
@@ -1359,6 +1379,9 @@ node *make_node_from_array(struct array *a)
   INT32 e;
 
   array_fix_type_field(a);
+  if(!a->size)
+      return mkefuncallnode("aggregate",0);
+    
   if(a->type_field == BIT_INT)
   {
     for(e=0; e<a->size; e++)
@@ -1369,6 +1392,40 @@ node *make_node_from_array(struct array *a)
       return mkefuncallnode("allocate",mkintnode(a->size));
     }
   }
+  if(!is_more_than_one_bit(a->type_field))
+  {
+    e=0;
+    switch(a->type_field)
+    {
+      case BIT_INT:
+	for(e=1; e<a->size; e++)
+	  if(ITEM(a)[e].u.integer != ITEM(a)[0].u.integer)
+	    break;
+	if(e==a->size && ITEM(a)[0].u.integer==0)
+	  return mkefuncallnode("allocate",mkintnode(a->size));
+	break;
+	
+      case BIT_STRING:
+      case BIT_PROGRAM:
+      case BIT_OBJECT:
+	for(e=1; e<a->size; e++)
+	  if(ITEM(a)[e].u.refs != ITEM(a)[0].u.refs)
+	    break;
+	break;
+	
+      case BIT_FUNCTION:
+	for(e=1; e<a->size; e++)
+	  if(ITEM(a)[e].u.object != ITEM(a)[0].u.object ||
+	     ITEM(a)[e].subtype != ITEM(a)[0].subtype)
+	    break;
+	break;
+    }
+    if(e == a->size)
+      return mkefuncallnode("allocate",mknode(F_ARG_LIST,
+					      mkintnode(a->size),
+					      mksvaluenode(ITEM(a))));
+  }
+  
   if(check_that_array_is_constant(a))
   {
     s.type=T_ARRAY;
diff --git a/src/docode.c b/src/docode.c
index 7b276ac050c0f914150ee6aa4d4f27852232a794..6e8c3683e9156185b12963562596c77437de7efc 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: docode.c,v 1.49 1999/08/03 00:45:09 hubbe Exp $");
+RCSID("$Id: docode.c,v 1.50 1999/09/16 23:56:09 hubbe Exp $");
 #include "las.h"
 #include "program.h"
 #include "language.h"
@@ -235,6 +235,24 @@ static int do_docode2(node *n,int flags)
     flags &=~DO_INDIRECT;
   }
 
+  /* Stack check */
+  {
+    long x_= ((char *)&x_) + STACK_DIRECTION * (32768) - stack_top ;
+    x_*=STACK_DIRECTION;						
+    if(x_>0)
+    {
+      yyerror("Too dep recursion in compiler. (please report this)");
+
+      emit(F_NUMBER,0);
+      if(flags & DO_LVALUE)
+      {
+	emit(F_NUMBER,0);
+	return 2;
+      }
+      return 1;
+    }
+  }
+
   switch(n->token)
   {
   case F_MAGIC_INDEX:
diff --git a/src/las.c b/src/las.c
index 6b388920115376e5f1f7caa9d75223e76b4dda0b..40156ef252d0188ecf7a5c881168cbfce3251c0d 100644
--- a/src/las.c
+++ b/src/las.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: las.c,v 1.86 1999/09/11 08:15:55 hubbe Exp $");
+RCSID("$Id: las.c,v 1.87 1999/09/16 23:56:10 hubbe Exp $");
 
 #include "language.h"
 #include "interpret.h"
@@ -354,9 +354,6 @@ node *mknode(short token,node *a,node *b)
   if(a) a->parent = res;
   if(b) b->parent = res;
 
-  /* We try to optimize most things, but argument lists are hard... */
-  if(token != F_ARG_LIST && (a || b))
-    res->node_info |= OPT_TRY_OPTIMIZE;
 
   switch(token)
   {
@@ -378,6 +375,7 @@ node *mknode(short token,node *a,node *b)
   case F_MAGIC_INDEX:
   case F_MAGIC_SET_INDEX:
     res->node_info |= OPT_EXTERNAL_DEPEND;
+    break;
 
   case F_UNDEFINED:
     res->node_info |= OPT_EXTERNAL_DEPEND | OPT_SIDE_EFFECT;
@@ -413,6 +411,10 @@ node *mknode(short token,node *a,node *b)
     break;
     
     default:
+      /* We try to optimize most things, but argument lists are hard... */
+      if(token != F_ARG_LIST && (a || b))
+	res->node_info |= OPT_TRY_OPTIMIZE;
+
       res->tree_info = res->node_info;
       if(a) res->tree_info |= a->tree_info;
       if(b) res->tree_info |= b->tree_info;
diff --git a/src/testsuite.in b/src/testsuite.in
index f3e2cafef5532d90e5c810cc713698cc62d1b6ea..4ea253d7dd90fad59e5724ccc3261f723d6afa4c 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,4 +1,4 @@
-test_true([["$Id: testsuite.in,v 1.195 1999/09/14 22:54:52 noring Exp $"]])
+test_true([["$Id: testsuite.in,v 1.196 1999/09/16 23:56:12 hubbe Exp $"]])
 cond([[all_constants()->_verify_internals]],
 [[
   test_do(_verify_internals())
@@ -2585,6 +2585,7 @@ test_eq(all_constants()["all_constants"],all_constants)
 test_true(arrayp(allocate(0)))
 test_equal(allocate(2),({0,0}))
 test_false(allocate(2)==({0,0}))
+test_true(allocate(65536,random))
 
 // - backtrace
 test_true(arrayp(backtrace()))