diff --git a/src/array.c b/src/array.c
index f87188cb349759dd4468b7a0238fa3d087b321ec..b29321892933743ad32d383e98fba4b1d3aaa849 100644
--- a/src/array.c
+++ b/src/array.c
@@ -23,7 +23,7 @@
 #include "stuff.h"
 #include "bignum.h"
 
-RCSID("$Id: array.c,v 1.118 2001/09/24 14:21:10 grubba Exp $");
+RCSID("$Id: array.c,v 1.119 2001/09/25 05:55:09 hubbe Exp $");
 
 PMOD_EXPORT struct array empty_array=
 {
@@ -1582,31 +1582,14 @@ PMOD_EXPORT struct array *and_arrays(struct array *a, struct array *b)
   }
 }
 
-int check_that_array_is_constant(struct array *a)
+int array_is_constant(struct array *a,
+		      struct processing *p)
 {
   array_fix_type_field(a);
-  if(a->type_field & (BIT_FUNCTION | BIT_OBJECT))
-  {
-    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;
+  return svalues_are_constant(ITEM(a),
+			      a->size,
+			      a->type_field,
+			      p);
 }
 
 node *make_node_from_array(struct array *a)
@@ -1666,7 +1649,7 @@ node *make_node_from_array(struct array *a)
 					      mksvaluenode(ITEM(a))));
   }
   
-  if(check_that_array_is_constant(a))
+  if(array_is_constant(a,0))
   {
     debug_malloc_touch(a);
     s.type=T_ARRAY;
diff --git a/src/array.h b/src/array.h
index 3985501645dcee860eb6a4b87458be8378ad6679..49c40523bc7966617363051f035c9d02ecf0278c 100644
--- a/src/array.h
+++ b/src/array.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: array.h,v 1.37 2001/08/31 06:53:36 hubbe Exp $
+ * $Id: array.h,v 1.38 2001/09/25 05:55:10 hubbe Exp $
  */
 #ifndef ARRAY_H
 #define ARRAY_H
@@ -96,7 +96,6 @@ PMOD_EXPORT void array_index(struct svalue *s,struct array *v,INT32 index);
 PMOD_EXPORT void simple_array_index_no_free(struct svalue *s,
 				struct array *a,struct svalue *ind);
 PMOD_EXPORT void array_free_index(struct array *v,INT32 index);
-PMOD_EXPORT void array_set_index(struct array *v,INT32 index, struct svalue *s);
 PMOD_EXPORT void simple_set_index(struct array *a,struct svalue *ind,struct svalue *s);
 PMOD_EXPORT struct array *array_insert(struct array *v,struct svalue *s,INT32 index);
 PMOD_EXPORT struct array *resize_array(struct array *a, INT32 size);
@@ -113,7 +112,7 @@ PMOD_EXPORT struct array *copy_array(struct array *v);
 PMOD_EXPORT void check_array_for_destruct(struct array *v);
 PMOD_EXPORT INT32 array_find_destructed_object(struct array *v);
 INT32 *get_order(struct array *v, cmpfun fun);
-int set_svalue_cmpfun(const struct svalue *a, const struct svalue *b);
+INLINE int set_svalue_cmpfun(const struct svalue *a, const struct svalue *b);
 PMOD_EXPORT void sort_array_destructively(struct array *v);
 PMOD_EXPORT INT32 *get_set_order(struct array *a);
 PMOD_EXPORT INT32 *get_switch_order(struct array *a);
@@ -135,14 +134,16 @@ INT32 * merge(struct array *a,struct array *b,INT32 opcode);
 PMOD_EXPORT struct array *array_zip(struct array *a, struct array *b,INT32 *zipper);
 PMOD_EXPORT struct array *add_arrays(struct svalue *argp, INT32 args);
 PMOD_EXPORT int array_equal_p(struct array *a, struct array *b, struct processing *p);
-PMOD_EXPORT struct array *merge_array_with_order(struct array *a, struct array *b,INT32 op);
+PMOD_EXPORT struct array *merge_array_with_order(struct array *a,
+						 struct array *b, INT32 op);
 PMOD_EXPORT struct array *merge_array_without_order2(struct array *a, struct array *b,INT32 op);
 PMOD_EXPORT struct array *merge_array_without_order(struct array *a,
 					struct array *b,
 					INT32 op);
 PMOD_EXPORT struct array *subtract_arrays(struct array *a, struct array *b);
 PMOD_EXPORT struct array *and_arrays(struct array *a, struct array *b);
-int check_that_array_is_constant(struct array *a);
+int array_is_constant(struct array *a,
+		      struct processing *p);
 node *make_node_from_array(struct array *a);
 PMOD_EXPORT void push_array_items(struct array *a);
 void describe_array_low(struct array *a, struct processing *p, int indent);
@@ -160,7 +161,7 @@ PMOD_EXPORT struct pike_string *implode(struct array *a,struct pike_string *del)
 PMOD_EXPORT struct array *copy_array_recursively(struct array *a,struct processing *p);
 PMOD_EXPORT void apply_array(struct array *a, INT32 args);
 PMOD_EXPORT struct array *reverse_array(struct array *a);
-PMOD_EXPORT void array_replace(struct array *a,
+void array_replace(struct array *a,
 		   struct svalue *from,
 		   struct svalue *to);
 PMOD_EXPORT void check_array(struct array *a);
diff --git a/src/mapping.c b/src/mapping.c
index 543a66ec578971f711ed5e60dfc2e6d22593de70..723c68c2d417b80c59acc36afd0dbf25e2ba85ca 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: mapping.c,v 1.137 2001/09/24 14:44:47 grubba Exp $");
+RCSID("$Id: mapping.c,v 1.138 2001/09/25 05:55:10 hubbe Exp $");
 #include "main.h"
 #include "object.h"
 #include "mapping.h"
@@ -1726,7 +1726,7 @@ node *make_node_from_mapping(struct mapping *m)
 
   mapping_fix_type_field(m);
 
-  if((m->data->ind_types | m->data->val_types) & (BIT_FUNCTION | BIT_OBJECT))
+  if(!mapping_is_constant(m,0))
   {
     struct array *ind, *val;
     node *n;
@@ -2457,3 +2457,24 @@ void zap_all_mappings(void)
   }
 }
 
+int mapping_is_constant(struct mapping *m,
+			struct processing *p)
+{
+  INT32 e;
+  struct keypair *k;
+  struct mapping_data *md=m->data;
+
+  if( (md->ind_types | md->val_types) & ~(BIT_INT|BIT_FLOAT|BIT_STRING))
+  {
+    md->valrefs++;
+    add_ref(md);
+    NEW_MAPPING_LOOP(md)
+      {
+	if(!svalues_are_constant(&k->ind, 1, md->ind_types, p)) return 0;
+	if(!svalues_are_constant(&k->val, 1, md->val_types, p)) return 0;
+      }
+    md->valrefs--;
+    free_mapping_data(md);
+  }
+  return 1;
+}
diff --git a/src/mapping.h b/src/mapping.h
index 6b8158755eec58a824bbcbfb84bf270c98e11c3a..03be4c631659e1f2f86950e206fca250c29bab2d 100644
--- a/src/mapping.h
+++ b/src/mapping.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: mapping.h,v 1.39 2001/06/30 17:50:36 mast Exp $
+ * $Id: mapping.h,v 1.40 2001/09/25 05:55:11 hubbe Exp $
  */
 #ifndef MAPPING_H
 #define MAPPING_H
@@ -95,6 +95,12 @@ PMOD_PROTO void really_free_mapping(struct mapping *md);
 /* Prototypes begin here */
 BLOCK_ALLOC(mapping, 511)
 
+
+
+
+
+
+static void check_mapping_type_fields(struct mapping *m);
 PMOD_EXPORT struct mapping *debug_allocate_mapping(int size);
 PMOD_EXPORT void really_free_mapping_data(struct mapping_data *md);
 PMOD_EXPORT void do_free_mapping(struct mapping *m);
@@ -154,10 +160,9 @@ PMOD_EXPORT struct mapping *add_mappings(struct svalue *argp, INT32 args);
 PMOD_EXPORT int mapping_equal_p(struct mapping *a, struct mapping *b, struct processing *p);
 void describe_mapping(struct mapping *m,struct processing *p,int indent);
 node *make_node_from_mapping(struct mapping *m);
-PMOD_EXPORT void f_m_delete(INT32 args);
 PMOD_EXPORT void f_aggregate_mapping(INT32 args);
 PMOD_EXPORT struct mapping *copy_mapping_recursively(struct mapping *m,
-					 struct processing *p);
+						     struct processing *p);
 PMOD_EXPORT void mapping_search_no_free(struct svalue *to,
 			    struct mapping *m,
 			    struct svalue *look_for,
@@ -165,16 +170,18 @@ PMOD_EXPORT void mapping_search_no_free(struct svalue *to,
 void check_mapping(struct mapping *m);
 void check_all_mappings(void);
 void gc_mark_mapping_as_referenced(struct mapping *m);
+void real_gc_cycle_check_mapping(struct mapping *m, int weak);
 unsigned gc_touch_all_mappings(void);
 void gc_check_all_mappings(void);
 void gc_mark_all_mappings(void);
-void real_gc_cycle_check_mapping(struct mapping *m, int weak);
 void gc_cycle_check_all_mappings(void);
 void gc_zap_ext_weak_refs_in_mappings(void);
 void gc_free_all_unreferenced_mappings(void);
 void simple_describe_mapping(struct mapping *m);
 void debug_dump_mapping(struct mapping *m);
 void zap_all_mappings(void);
+int mapping_is_constant(struct mapping *m,
+			struct processing *p);
 /* Prototypes end here */
 
 #define allocate_mapping(X) dmalloc_touch(struct mapping *,debug_allocate_mapping(X))
diff --git a/src/multiset.c b/src/multiset.c
index 04e3113ddaf20ea78bda1cfbd865a50c70eb7094..8588c2dbb04348c0cf842d19f8eebb4d5ab03a93 100644
--- a/src/multiset.c
+++ b/src/multiset.c
@@ -17,7 +17,7 @@
 #include "gc.h"
 #include "security.h"
 
-RCSID("$Id: multiset.c,v 1.38 2001/09/24 14:38:52 grubba Exp $");
+RCSID("$Id: multiset.c,v 1.39 2001/09/25 05:55:11 hubbe Exp $");
 
 struct multiset *first_multiset;
 
@@ -275,7 +275,7 @@ void describe_multiset(struct multiset *l,struct processing *p,int indent)
 
 node * make_node_from_multiset(struct multiset *l)
 {
-  if(check_that_array_is_constant(l->ind))
+  if(multiset_is_constant(l,0))
   {
     struct svalue s;
     s.type=T_MULTISET;
@@ -438,3 +438,10 @@ void count_memory_in_multisets(INT32 *num_, INT32 *size_)
   *size_=size;
 }
 
+int multiset_is_constant(struct multiset *m,
+			 struct processing *p)
+{
+  return array_is_constant(m->ind, p);
+}
+
+
diff --git a/src/multiset.h b/src/multiset.h
index 42ce9f6a82a6a0d64224ed691acc27820cb1afc0..48bdca8841cec242d9803f5fc530491f212018e9 100644
--- a/src/multiset.h
+++ b/src/multiset.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: multiset.h,v 1.18 2001/04/07 07:38:24 hubbe Exp $
+ * $Id: multiset.h,v 1.19 2001/09/25 05:55:12 hubbe Exp $
  */
 #ifndef MULTISET_H
 #define MULTISET_H
@@ -35,9 +35,9 @@ PMOD_EXPORT void do_free_multiset(struct multiset *l);
 PMOD_EXPORT void order_multiset(struct multiset *l);
 PMOD_EXPORT struct multiset *mkmultiset(struct array *ind);
 PMOD_EXPORT void multiset_insert(struct multiset *l,
-		 struct svalue *ind);
+				 struct svalue *v);
 struct array *multiset_indices(struct multiset *l);
-PMOD_EXPORT void multiset_delete(struct multiset *l,struct svalue *ind);
+PMOD_EXPORT void multiset_delete(struct multiset *l,struct svalue *v);
 PMOD_EXPORT void check_multiset_for_destruct(struct multiset *l);
 PMOD_EXPORT struct multiset *copy_multiset(struct multiset *tmp);
 PMOD_EXPORT struct multiset *merge_multisets(struct multiset *a,
@@ -51,13 +51,15 @@ PMOD_EXPORT void f_aggregate_multiset(INT32 args);
 struct multiset *copy_multiset_recursively(struct multiset *l,
 				   struct processing *p);
 void gc_mark_multiset_as_referenced(struct multiset *l);
+void real_gc_cycle_check_multiset(struct multiset *l, int weak);
 unsigned gc_touch_all_multisets(void);
 void gc_check_all_multisets(void);
 void gc_mark_all_multisets(void);
-void real_gc_cycle_check_multiset(struct multiset *l, int weak);
 void gc_cycle_check_all_multisets(void);
 void gc_free_all_unreferenced_multisets(void);
 void count_memory_in_multisets(INT32 *num_, INT32 *size_);
+int multiset_is_constant(struct multiset *m,
+			 struct processing *p);
 /* Prototypes end here */
 
 #define gc_cycle_check_multiset(X, WEAK) \
diff --git a/src/program.c b/src/program.c
index aff13e32b48f89638a6037d55e39baafc60e1fd7..78ab12a1624de592dba6ffc23657bfeb3733e366 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.372 2001/09/24 16:42:48 grubba Exp $");
+RCSID("$Id: program.c,v 1.373 2001/09/25 05:55:12 hubbe Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -3151,20 +3151,49 @@ PMOD_EXPORT int add_constant(struct pike_string *name,
     fatal("define_constant on nonshared string.\n");
 #endif
 
-  n = isidentifier(name);
+  do {
+    if(c &&
+       c->type == T_FUNCTION &&
+       c->subtype != FUNCTION_BUILTIN &&
+       c->u.object->prog)
+    {
+      struct identifier *id=ID_FROM_INT(c->u.object->prog, c->subtype);
+      if(c->u.object->prog == Pike_compiler->new_program)
+      {
+	if(id->identifier_flags & IDENTIFIER_FUNCTION)
+	{
+	  return define_function(name,
+				 id->type,
+				 flags,
+				 id->identifier_flags | IDENTIFIER_ALIAS,
+				 & id->func,
+				 id->opt_flags);
+	  
+	}
+	else if(id->identifier_flags & IDENTIFIER_CONSTANT &&
+		id->func.offset != -1)
+	{
+	  c=& Pike_compiler->new_program->constants[id->func.offset].sval;
+	}
+      }
+      else
+      {
+	if(id->identifier_flags & IDENTIFIER_CONSTANT)
+	{
+	  /* In this one case we allow fake objects to enter the
+	   * mainstream...
+	   */
+	  break;
+	}
+      }
+    }
+    
+    if(c && !svalues_are_constant(c,1,BIT_MIXED,0))
+      yyerror("Constant values may not references this_object()");
+    
+  }while(0);
 
-  /*
-   * FIXME:
-   * No constants should be allowed to contain
-   * any fake objects. (Fake objects can be
-   * detected thus: fake_ob->next == fake_ob
-   *
-   * I would prefer to find a way to detect
-   * this without recursing through arrays,
-   * mapping etc. etc.
-   *
-   * /Hubbe
-   */
+  n = isidentifier(name);
 
   if(Pike_compiler->new_program->flags & PROGRAM_PASS_1_DONE)
   {
diff --git a/src/svalue.c b/src/svalue.c
index 426b26d7ba3dd1f95461bcdf25f26b468951e3b0..c0fea0b7469b9c15582ea5df34f602ac22c90fec 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -62,7 +62,7 @@ static int pike_isnan(double x)
 #endif /* HAVE__ISNAN */
 #endif /* HAVE_ISNAN */
 
-RCSID("$Id: svalue.c,v 1.124 2001/09/24 16:49:20 grubba Exp $");
+RCSID("$Id: svalue.c,v 1.125 2001/09/25 05:55:13 hubbe Exp $");
 
 struct svalue dest_ob_zero = {
   T_INT, 0,
@@ -546,7 +546,7 @@ PMOD_EXPORT int svalue_is_true(const struct svalue *s)
     if(!s->u.object->prog) return 0;
     if (s->u.object->prog == pike_trampoline_program) {
       /* Trampoline */
-      struct pike_trampoline *tramp =
+      struct pike_trampoline *tramp = (struct pike_trampoline *)
 	get_storage(s->u.object, pike_trampoline_program);
       if (!tramp || !tramp->frame || !tramp->frame->current_object ||
 	  !tramp->frame->current_object->prog) {
@@ -1842,3 +1842,65 @@ PMOD_EXPORT INT32 pike_sizeof(const struct svalue *s)
     return 0; /* make apcc happy */
   }
 }
+
+int svalues_are_constant(struct svalue *s,
+			 INT32 num,
+			 TYPE_FIELD hint,
+			 struct processing *p)
+{
+  if(hint & ~(BIT_STRING | BIT_INT | BIT_FLOAT))
+  {
+    INT32 e;
+    for(e=0;e<num;e++)
+    {
+      switch(s->type)
+      {
+	case T_ARRAY:
+	case T_MAPPING:
+	case T_MULTISET:
+	{
+	  struct processing curr;
+	  curr.pointer_a = s->u.refs;
+	  curr.next = p;
+
+	  for( ;p ;p=p->next)
+	    if(p->pointer_a == (void *)s->u.refs)
+	      return 1;
+	  
+	  switch(s->type)
+	  {
+	    case T_ARRAY:
+	      if(!array_is_constant(s->u.array,&curr))
+		return 0;
+	      break;
+
+	    case T_MAPPING:
+	      if(!mapping_is_constant(s->u.mapping,&curr))
+		return 0;
+	      break;
+
+	    case T_MULTISET:
+	      if(!multiset_is_constant(s->u.multiset,&curr))
+		return 0;
+	      break;
+	  }
+	}
+	  
+	case T_FUNCTION:
+	  if(s->subtype == FUNCTION_BUILTIN) continue;
+	  /* Fall through */
+	  
+	case T_OBJECT:
+	  if(s->u.object -> next == s->u.object)
+	  {
+	    /* This is a fake object used during the
+	     * compilation!
+	     */
+	    return 0;
+	  }
+      }
+      s++;
+    }
+  }
+  return 1;
+}
diff --git a/src/svalue.h b/src/svalue.h
index 6e3fc143afc9394fc7b7ecba2536b47268746c4a..8f4d99198fbfd4ee4541c8033191166d0a0044a8 100644
--- a/src/svalue.h
+++ b/src/svalue.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: svalue.h,v 1.96 2001/08/20 18:06:55 mast Exp $
+ * $Id: svalue.h,v 1.97 2001/09/25 05:55:13 hubbe Exp $
  */
 #ifndef SVALUE_H
 #define SVALUE_H
@@ -468,6 +468,7 @@ PMOD_EXPORT void really_free_short_svalue(union anything *s, TYPE_T type);
 PMOD_EXPORT void really_free_svalue(struct svalue *s);
 PMOD_EXPORT void do_free_svalue(struct svalue *s);
 PMOD_EXPORT void debug_free_svalues(struct svalue *s, size_t num, INT32 type_hint DMALLOC_LINE_ARGS);
+PMOD_EXPORT void debug_free_mixed_svalues(struct svalue *s, size_t num, INT32 type_hint DMALLOC_LINE_ARGS);
 PMOD_EXPORT void assign_svalues_no_free(struct svalue *to,
 			    const struct svalue *from,
 			    size_t num,
@@ -527,13 +528,18 @@ PMOD_EXPORT TYPE_FIELD real_gc_cycle_check_svalues(struct svalue *s, size_t num)
 TYPE_FIELD gc_cycle_check_weak_svalues(struct svalue *s, size_t num);
 PMOD_EXPORT int real_gc_cycle_check_short_svalue(union anything *u, TYPE_T type);
 int gc_cycle_check_weak_short_svalue(union anything *u, TYPE_T type);
-#define gc_cycle_check_without_recurse gc_mark_without_recurse
-#define gc_cycle_check_weak_without_recurse gc_mark_without_recurse
 void real_gc_free_svalue(struct svalue *s);
 void real_gc_free_short_svalue(union anything *u, TYPE_T type);
 PMOD_EXPORT INT32 pike_sizeof(const struct svalue *s);
+int svalues_are_constant(struct svalue *s,
+			 INT32 num,
+			 TYPE_FIELD hint,
+			 struct processing *p);
 /* Prototypes end here */
 
+#define gc_cycle_check_without_recurse gc_mark_without_recurse
+#define gc_cycle_check_weak_without_recurse gc_mark_without_recurse
+
 #define gc_xmark_svalues(S,N) real_gc_xmark_svalues(dmalloc_check_svalue(S,DMALLOC_LOCATION()),N)
 #define gc_check_svalues(S,N) real_gc_check_svalues(dmalloc_check_svalue(S,DMALLOC_LOCATION()),N)
 #define gc_check_short_svalue(U,T) real_gc_check_short_svalue(dmalloc_check_union((U),(T),DMALLOC_LOCATION()),T)