diff --git a/src/docode.c b/src/docode.c
index 6e8c3683e9156185b12963562596c77437de7efc..1fb916e5906f2d3f1421335b3f943a20581519ba 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.50 1999/09/16 23:56:09 hubbe Exp $");
+RCSID("$Id: docode.c,v 1.51 1999/09/18 09:21:17 hubbe Exp $");
 #include "las.h"
 #include "program.h"
 #include "language.h"
@@ -710,7 +710,8 @@ static int do_docode2(node *n,int flags)
 	    emit2(F_MARK);
 	    do_docode(CDR(n),0);
 	    tmp1=store_constant(& CAR(n)->u.sval,
-				!(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND));
+				!(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND),
+				CAR(n)->name);
 	    emit(F_APPLY,tmp1);
 	  }
 	  if(n->type == void_type_string)
@@ -731,7 +732,8 @@ static int do_docode2(node *n,int flags)
       emit2(F_MARK);
       do_docode(CDR(n),0);
       tmp1=store_constant(& CAR(n)->u.sval,
-			  !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND));
+			  !(CAR(n)->tree_info & OPT_EXTERNAL_DEPEND),
+			  CAR(n)->name);
       emit(F_APPLY,tmp1);
       
       return 1;
@@ -767,7 +769,8 @@ static int do_docode2(node *n,int flags)
 	{
 	  emit2(F_CALL_FUNCTION);
 	}else{
-	  tmp1=store_constant(& foo->u.sval, 1);
+	  /* We might want to put "predef::"+foo->name here /Hubbe */
+	  tmp1=store_constant(& foo->u.sval, 1, foo->name);
 	  emit(F_APPLY, tmp1);
 	}
       }
@@ -872,7 +875,7 @@ static int do_docode2(node *n,int flags)
     for(e=1; e<cases*2+2; e++)
       update_arg(jumptable[e], current_switch_jumptable[e]);
 
-    update_arg(tmp1, store_constant(sp-1,1));
+    update_arg(tmp1, store_constant(sp-1,1,0));
 
     pop_stack();
     free((char *)jumptable);
@@ -1138,14 +1141,18 @@ static int do_docode2(node *n,int flags)
 #endif
 
     default:
-      tmp1=store_constant(&(n->u.sval),!(n->tree_info & OPT_EXTERNAL_DEPEND));
+      tmp1=store_constant(&(n->u.sval),
+			  !(n->tree_info & OPT_EXTERNAL_DEPEND),
+			  n->name);
       emit(F_CONSTANT,tmp1);
       return 1;
 
     case T_ARRAY:
     case T_MAPPING:
     case T_MULTISET:
-      tmp1=store_constant(&(n->u.sval),!(n->tree_info & OPT_EXTERNAL_DEPEND));
+      tmp1=store_constant(&(n->u.sval),
+			  !(n->tree_info & OPT_EXTERNAL_DEPEND),
+			  n->name);
       emit(F_CONSTANT,tmp1);
       
       /* copy now or later ? */
diff --git a/src/interpreter.h b/src/interpreter.h
index ad1bc3fbc5625498e0ace8e5bc4ccdfcab353713..bbc153de5427aac4f6156a2b3b0d9455681e71fb 100644
--- a/src/interpreter.h
+++ b/src/interpreter.h
@@ -158,7 +158,7 @@ static int eval_instruction(unsigned char *pc)
       break;
 
       CASE(F_CONSTANT);
-      assign_svalue_no_free(sp++,fp->context.prog->constants+GET_ARG());
+      assign_svalue_no_free(sp++,& fp->context.prog->constants[GET_ARG()].sval);
       print_return_value();
       break;
 
@@ -933,7 +933,7 @@ static int eval_instruction(unsigned char *pc)
       {
 	INT32 tmp;
 	tmp=switch_lookup(fp->context.prog->
-			  constants[GET_ARG()].u.array,sp-1);
+			  constants[GET_ARG()].sval.u.array,sp-1);
 	pc=(unsigned char *)DO_ALIGN(pc,sizeof(INT32));
 	pc+=(tmp>=0 ? 1+tmp*2 : 2*~tmp) * sizeof(INT32);
 	if(*(INT32*)pc < 0) fast_check_threads_etc(7);
@@ -979,7 +979,7 @@ static int eval_instruction(unsigned char *pc)
 	  sp[-args-1].type=T_INT;
 	}
 	/* We sabotage the stack here */
-	assign_svalue(sp-args-1,fp->context.prog->constants+GET_ARG());
+	assign_svalue(sp-args-1,&fp->context.prog->constants[GET_ARG()].sval);
 	return args+1;
       }
 
diff --git a/src/language.yacc b/src/language.yacc
index 06065263363b45baa0af9936b9ed8a72f91881e3..d50aba6895534f1e438106453b67016814ed9436 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -182,7 +182,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.122 1999/08/20 05:08:24 hubbe Exp $");
+RCSID("$Id: language.yacc,v 1.123 1999/09/18 09:21:20 hubbe Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
@@ -423,6 +423,7 @@ low_program_ref: string_constant
 		 $1->u.sval.u.string->str);
     free_node($1);
     $$=mksvaluenode(sp-1);
+    add_ref( $$->name=sp[-2].u.string );
     pop_stack();
   }
   | idents
diff --git a/src/las.c b/src/las.c
index 40156ef252d0188ecf7a5c881168cbfce3251c0d..b699000e1931d7ce9f1a53e429e2ee7cfac8c2df 100644
--- a/src/las.c
+++ b/src/las.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: las.c,v 1.87 1999/09/16 23:56:10 hubbe Exp $");
+RCSID("$Id: las.c,v 1.88 1999/09/18 09:21:21 hubbe Exp $");
 
 #include "language.h"
 #include "interpret.h"
@@ -297,6 +297,7 @@ void free_node(node *n)
   }
   n->token=USHRT_MAX;
   if(n->type) free_string(n->type);
+  if(n->name) free_string(n->name);
 #ifdef PIKE_DEBUG
   if(n->current_file) free_string(n->current_file);
 #endif
@@ -329,6 +330,7 @@ static node *mkemptynode(void)
   copy_shared_string(res->current_file, lex.current_file);
 #endif
   res->type=0;
+  res->name=0;
   res->node_info=0;
   res->tree_info=0;
   res->parent=0;
@@ -1036,6 +1038,7 @@ node *copy_node(node *n)
     else
       b->type=0;
   }
+  if(n->name) add_ref(b->name=n->name);
   b->line_number = n->line_number;
   b->node_info = n->node_info;
   b->tree_info = n->tree_info;
diff --git a/src/lex.c b/src/lex.c
index 5ffa2ce90db6e55ad2af52f4deddc26a8f9725f5..2177305bef1385ff00bdbe8d70dee67af947659b 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: lex.c,v 1.65 1999/08/03 00:45:13 hubbe Exp $");
+RCSID("$Id: lex.c,v 1.66 1999/09/18 09:21:22 hubbe Exp $");
 #include "language.h"
 #include "array.h"
 #include "lex.h"
@@ -285,11 +285,11 @@ char *low_get_f_name(int n,struct program *p)
   }else if(n >= F_MAX_OPCODE) {
     if(p &&
        (int)p->num_constants > (int)(n-F_MAX_OPCODE) &&
-       p->constants[n-F_MAX_OPCODE].type==T_FUNCTION &&
-       (p->constants[n-F_MAX_OPCODE].subtype == FUNCTION_BUILTIN) &&
-       p->constants[n-F_MAX_OPCODE].u.efun)
+       p->constants[n-F_MAX_OPCODE].sval.type==T_FUNCTION &&
+       (p->constants[n-F_MAX_OPCODE].sval.subtype == FUNCTION_BUILTIN) &&
+       p->constants[n-F_MAX_OPCODE].sval.u.efun)
     {
-      return p->constants[n-F_MAX_OPCODE].u.efun->name->str;
+      return p->constants[n-F_MAX_OPCODE].sval.u.efun->name->str;
     }else{
       sprintf(buf, "Call efun %d", n - F_MAX_OPCODE);
       return buf;
@@ -309,11 +309,11 @@ char *get_f_name(int n)
   }else if(n >= F_MAX_OPCODE) {
     if(fp && fp->context.prog &&
        (int)fp->context.prog->num_constants > (int)(n-F_MAX_OPCODE) &&
-       fp->context.prog->constants[n-F_MAX_OPCODE].type==T_FUNCTION &&
-       fp->context.prog->constants[n-F_MAX_OPCODE].subtype == FUNCTION_BUILTIN &&
-       fp->context.prog->constants[n-F_MAX_OPCODE].u.efun)
+       fp->context.prog->constants[n-F_MAX_OPCODE].sval.type==T_FUNCTION &&
+       fp->context.prog->constants[n-F_MAX_OPCODE].sval.subtype == FUNCTION_BUILTIN &&
+       fp->context.prog->constants[n-F_MAX_OPCODE].sval.u.efun)
     {
-      return fp->context.prog->constants[n-F_MAX_OPCODE].u.efun->name->str;
+      return fp->context.prog->constants[n-F_MAX_OPCODE].sval.u.efun->name->str;
     }else{
       sprintf(buf, "Call efun %d", n - F_MAX_OPCODE);
       return buf;
diff --git a/src/object.c b/src/object.c
index a5c173aff6772cd9a29e49f4515236f4a2db0fdb..7e3f37f2771c71847d35de904d7d680679b57daf 100644
--- a/src/object.c
+++ b/src/object.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: object.c,v 1.81 1999/09/16 05:14:33 hubbe Exp $");
+RCSID("$Id: object.c,v 1.82 1999/09/18 09:21:23 hubbe Exp $");
 #include "object.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
@@ -596,7 +596,7 @@ void low_object_index_no_free(struct svalue *to,
   case IDENTIFIER_CONSTANT:
     {
       struct svalue *s;
-      s=PROG_FROM_INT(p,f)->constants + i->func.offset;
+      s=& PROG_FROM_INT(p,f)->constants[i->func.offset].sval;
       if(s->type==T_PROGRAM)
       {
 	to->type=T_FUNCTION;
diff --git a/src/object.h b/src/object.h
index c33bc9b3e68fe5d0929b30ccd019fe263df9d754..ee8b2619e78b2f100179d1aec703a544f3791805 100644
--- a/src/object.h
+++ b/src/object.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: object.h,v 1.28 1999/09/14 22:51:05 hubbe Exp $
+ * $Id: object.h,v 1.29 1999/09/18 09:21:24 hubbe Exp $
  */
 #ifndef OBJECT_H
 #define OBJECT_H
@@ -97,7 +97,7 @@ void init_object(void);
 void exit_object(void);
 void check_object(struct object *o);
 void check_all_objects(void);
-void check_context(struct object *o, struct program *p, char *storage);
+void check_object_context(struct object *o, struct program *p, char *storage);
 /* Prototypes end here */
 
 #ifdef MALLOC_DEBUG
diff --git a/src/pike_types.h b/src/pike_types.h
index 6ba0dd38c63ba092d89f20e59302b81d20d3b3a9..70ff6a286d15e9e2152bb7b18ca95e61734dc255 100644
--- a/src/pike_types.h
+++ b/src/pike_types.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: pike_types.h,v 1.20 1999/06/03 01:39:37 hubbe Exp $
+ * $Id: pike_types.h,v 1.21 1999/09/18 09:21:25 hubbe Exp $
  */
 #ifndef PIKE_TYPES_H
 #define PIKE_TYPES_H
@@ -22,6 +22,7 @@ struct node_s
   struct pike_string *current_file;
 #endif
   struct pike_string *type;
+  struct pike_string *name;
   struct node_s *parent;
   union 
   {
diff --git a/src/program.c b/src/program.c
index 4b61fc5b1ee8d97f5feb1bec4574e7c01eed066b..462673afd7e990ac03ac5163e3ddfafad7d97122 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.150 1999/09/16 20:30:34 hubbe Exp $");
+RCSID("$Id: program.c,v 1.151 1999/09/18 09:21:26 hubbe Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -687,7 +687,8 @@ void really_free_program(struct program *p)
   }
 
   if(p->constants)
-    free_svalues(p->constants, p->num_constants, BIT_MIXED);
+    for(e=0;e<p->num_constants;e++)
+      free_svalue(& p->constants[e].sval);
 
   if(p->inherits)
     for(e=0; e<p->num_inherits; e++)
@@ -863,7 +864,10 @@ void check_program(struct program *p)
     fatal("Too many identifier index entries in program!\n");
 
   for(e=0;e<(int)p->num_constants;e++)
-    check_svalue(p->constants + e);
+  {
+    check_svalue(& p->constants[e].sval);
+    if(p->constants[e].name) check_string(p->constants[e].name);
+  }
 
   for(e=0;e<(int)p->num_strings;e++)
     check_string(p->strings[e]);
@@ -1102,11 +1106,11 @@ SIZE_T low_add_storage(SIZE_T size, SIZE_T alignment, int modulo_orig)
     fatal("add_storage failed horribly!\n");
 
   if( (offset + OFFSETOF(object,storage) - modulo_orig ) % alignment )
-    fatal("add_storage failed horribly(2) %d %d %d %d!\n",
-	  offset,
-	  OFFSETOF(object,storage),
-	  modulo_orig,
-	  alignment
+    fatal("add_storage failed horribly(2) %ld %ld %ld %ld!\n",
+	  (long)offset,
+	  (long)OFFSETOF(object,storage),
+	  (long)modulo_orig,
+	  (long)alignment
 	  );
     
 #endif
@@ -1508,7 +1512,8 @@ void compiler_do_inherit(node *n,
     
       if(IDENTIFIER_IS_CONSTANT(i->identifier_flags))
       {
-	struct svalue *s=PROG_FROM_INT(p, numid)->constants + i->func.offset;
+	struct svalue *s=&PROG_FROM_INT(p, numid)->
+	  constants[i->func.offset].sval;
 	if(s->type != T_PROGRAM)
 	{
 	  do_inherit(s,flags,name);
@@ -1760,8 +1765,8 @@ int add_constant(struct pike_string *name,
       if(id->func.offset>=0)
       {
 	struct pike_string *s;
-	struct svalue *c=PROG_FROM_INT(new_program,n)->constants+
-	  id->func.offset;
+	struct svalue *c=&PROG_FROM_INT(new_program,n)->
+	  constants[id->func.offset].sval;
 	s=get_type_of_svalue(c);
 	free_string(id->type);
 	id->type=s;
@@ -1785,7 +1790,7 @@ int add_constant(struct pike_string *name,
   dummy.identifier_flags = IDENTIFIER_CONSTANT;
   dummy.run_time_type=c->type;
   
-  dummy.func.offset=store_constant(c, 0);
+  dummy.func.offset=store_constant(c, 0, 0);
 
   ref.id_flags=flags;
   ref.identifier_offset=new_program->num_identifiers;
@@ -2255,19 +2260,24 @@ int store_prog_string(struct pike_string *str)
   return i;
 }
 
-int store_constant(struct svalue *foo, int equal)
+int store_constant(struct svalue *foo,
+		   int equal,
+		   struct pike_string *constant_name)
 {
-  struct svalue tmp;
+  struct program_constant tmp;
   unsigned int e;
 
   for(e=0;e<new_program->num_constants;e++)
   {
-    struct svalue *s=new_program->constants + e;
-    if(equal ? is_equal(s,foo) : is_eq(s,foo))
+    struct program_constant *c= new_program->constants+e;
+    if((equal ? is_equal(& c->sval,foo) : is_eq(& c->sval,foo)) &&
+       c->name == constant_name)
       return e;
   }
 
-  assign_svalue_no_free(&tmp,foo);
+  assign_svalue_no_free(&tmp.sval,foo);
+  if((tmp.name=constant_name)) add_ref(constant_name);
+
   add_to_constants(tmp);
   return e;
 }
@@ -2312,7 +2322,7 @@ struct array *program_values(struct program *p)
     id = ID_FROM_INT(p, e);
     if (IDENTIFIER_IS_CONSTANT(id->identifier_flags)) {
       struct program *p2 = PROG_FROM_INT(p, e);
-      push_svalue(p2->constants + id->func.offset);
+      push_svalue( & p2->constants[id->func.offset].sval);
       n++;
     }
   }
@@ -2354,7 +2364,7 @@ void program_index_no_free(struct svalue *to, struct program *p,
 #endif
     if (IDENTIFIER_IS_CONSTANT(id->identifier_flags)) {
       struct program *p2 = PROG_FROM_INT(p, e);
-      assign_svalue_no_free(to, (p2->constants + id->func.offset));
+      assign_svalue_no_free(to, ( & p2->constants[id->func.offset].sval));
       return;
     } else {
       if (s->len < 1024) {
@@ -2853,7 +2863,8 @@ void gc_mark_program_as_referenced(struct program *p)
   if(gc_mark(p))
   {
     int e;
-    gc_mark_svalues(p->constants, p->num_constants);
+    for(e=0;e<p->num_constants;e++)
+      gc_mark_svalues(& p->constants[e].sval, 1);
 
     for(e=0;e<p->num_inherits;e++)
     {
@@ -2873,7 +2884,8 @@ void gc_check_all_programs(void)
   for(p=first_program;p;p=p->next)
   {
     int e;
-    debug_gc_check_svalues(p->constants, p->num_constants, T_PROGRAM, p);
+    for(e=0;e<p->num_constants;e++)
+      debug_gc_check_svalues(& p->constants[e].sval, 1, T_PROGRAM, p);
 
     for(e=0;e<p->num_inherits;e++)
     {
@@ -2931,7 +2943,9 @@ void gc_free_all_unreferenced_programs(void)
     {
       int e;
       add_ref(p);
-      free_svalues(p->constants, p->num_constants, -1);
+      for(e=0;e<p->num_constants;e++)
+	free_svalue(& p->constants[e].sval);
+
       for(e=0;e<p->num_inherits;e++)
       {
 	if(p->inherits[e].parent)
@@ -3068,7 +3082,7 @@ struct program *low_program_from_function(struct program *p,
   struct identifier *id=ID_FROM_INT(p, i);
   if(!IDENTIFIER_IS_CONSTANT(id->identifier_flags)) return 0;
   if(id->func.offset==-1) return 0;
-  f=PROG_FROM_INT(p,i)->constants + id->func.offset;
+  f=& PROG_FROM_INT(p,i)->constants[id->func.offset].sval;
   if(f->type!=T_PROGRAM) return 0;
   return f->u.program;
 }
diff --git a/src/program.h b/src/program.h
index 79244ad16783d83e5496a9e18edee318d10cc535..85ca4d1f0199566fa6b556a9c58c3616bd48bfd1 100644
--- a/src/program.h
+++ b/src/program.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: program.h,v 1.58 1999/09/16 20:30:36 hubbe Exp $
+ * $Id: program.h,v 1.59 1999/09/18 09:21:28 hubbe Exp $
  */
 #ifndef PROGRAM_H
 #define PROGRAM_H
@@ -138,6 +138,12 @@ struct identifier
   union idptr func;
 };
 
+struct program_constant
+{
+  struct svalue sval;
+  struct pike_string *name;
+};
+
 /*
  * in the bytecode, a function starts with:
  * char num_args
@@ -174,6 +180,13 @@ struct inherit
   struct pike_string *name;
 };
 
+struct pike_trampoline
+{
+  struct pike_frame *frame;
+  INT32 func;
+};
+
+
 /* program parts have been realloced into one block */
 #define PROGRAM_OPTIMIZED 1
 
@@ -255,13 +268,6 @@ struct program
 #define free_program(p) do{ struct program *_=(p); debug_malloc_touch(_); if(!--_->refs) really_free_program(_); }while(0)
 
 
-struct pike_trampoline
-{
-  struct pike_frame *frame;
-  INT32 func;
-};
-
-
 extern struct object *fake_object;
 extern struct program *new_program;
 extern struct program *first_program;
@@ -391,7 +397,7 @@ int find_shared_string_identifier(struct pike_string *name,
 				  struct program *prog);
 int find_identifier(char *name,struct program *prog);
 int store_prog_string(struct pike_string *str);
-int store_constant(struct svalue *foo, int equal);
+int store_constant(struct svalue *foo, int equal, struct pike_string *name);
 struct array *program_indices(struct program *p);
 struct array *program_values(struct program *p);
 void program_index_no_free(struct svalue *to, struct program *p,
diff --git a/src/program_areas.h b/src/program_areas.h
index 0cb01707e9d4ea512e88f88f4205df7a5987fb65..ef1e7ad2470195117027e9833a07ab28839bca3c 100644
--- a/src/program_areas.h
+++ b/src/program_areas.h
@@ -1,4 +1,4 @@
-/* $Id: program_areas.h,v 1.5 1998/04/24 00:32:10 hubbe Exp $ */
+/* $Id: program_areas.h,v 1.6 1999/09/18 09:21:29 hubbe Exp $ */
 /* Who needs templates anyway? / Hubbe */
 
 /* Program *must* be first! */
@@ -10,6 +10,6 @@ FOO(unsigned INT16,struct reference,identifier_references)
 FOO(unsigned INT16,struct pike_string *,strings)
 FOO(unsigned INT16,struct inherit,inherits)
 FOO(unsigned INT16,struct identifier,identifiers)
-FOO(unsigned INT16,struct svalue, constants)
+FOO(unsigned INT16,struct program_constant, constants)
 #undef FOO
 
diff --git a/src/testsuite.in b/src/testsuite.in
index 4ea253d7dd90fad59e5724ccc3261f723d6afa4c..b251a4743bb3e8a8d8ecbc5bbde4406ecc8b0a8b 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,4 +1,4 @@
-test_true([["$Id: testsuite.in,v 1.196 1999/09/16 23:56:12 hubbe Exp $"]])
+test_true([["$Id: testsuite.in,v 1.197 1999/09/18 09:21:30 hubbe Exp $"]])
 cond([[all_constants()->_verify_internals]],
 [[
   test_do(_verify_internals())
@@ -689,6 +689,14 @@ test_encode(({}))
 test_encode(([]))
 test_encode("foobar")
 test_encode((<>))
+test_encode("\7")
+test_encode("\77")
+test_encode("\777")
+test_encode("\7777")
+test_encode("\77777")
+test_encode("\777777")
+test_encode("\7777777")
+test_encode("\77777777")
 test_eq(decode_value("\210\201"),1)
 test_eq(decode_value("\210\011\001"),-1)
 test_eq(decode_value("\206\200"),""))