diff --git a/lib/master.pike.in b/lib/master.pike.in
index 7b8ddea6d59f0491c61b6bfbb2015a3ff9b416b7..2e6bbaaed8c7246e9c73d0dbf4b93c2fcc2ecd46 100644
--- a/lib/master.pike.in
+++ b/lib/master.pike.in
@@ -1,6 +1,6 @@
 /* -*- Pike -*-
  *	
- * $Id: master.pike.in,v 1.169 2001/09/02 01:36:13 marcus Exp $
+ * $Id: master.pike.in,v 1.170 2001/10/05 01:30:11 hubbe Exp $
  * 
  * Master-file for Pike.
  *
@@ -477,7 +477,7 @@ static program low_findprog(string pname,
 	      AUTORELOAD_CHECK_FILE(oname);
 	      return programs[fname] =
 		decode_value(master_read_file(oname),
-			     Codec());
+			     Codec(fname,mkobj));
 	    };
 	    if (handler) {
 	      handler->compile_warning(oname, 0,
@@ -532,6 +532,16 @@ static program low_findprog(string pname,
   return 0;
 }
 
+//
+// This function is called by the compiler
+// when a delayed compilation error occurs
+//
+void unregister(program p)
+{
+  if(string fname=search(programs,p))
+    m_delete(programs, fname);
+}
+
 static program findprog(string pname,
 			string ext,
 			object|void handler,
@@ -787,37 +797,78 @@ object cast_to_object(string oname, string current_file)
   return 0;
 }
 
-class dirnode(string dirname, object|void handler)
+class dirnode
 {
+  string dirname;
+  object|void handler;
   constant is_resolv_dirnode = 1;
   mixed module=module_checker();
   mapping(string:mixed) cache=([]);
   array(string) files;
 
+  void create(string d, object|void h)
+    {
+      dirname=d;
+      handler=h;
+      fc[dirname]=this_object();
+      if(dirname[sizeof(dirname)-5..]==".pmod")
+	fc[dirname[..sizeof(dirname)-6]]=this_object();
+#ifdef MODULE_TRACE
+      werror("%*ndirnode(%O,%O);\n",sizeof(backtrace())-1,dirname,h);
+//      werror(describe_backtrace( ({"HERE\n",backtrace()})));
+#endif
+    }
+
   class module_checker
   {
     int `!()
     {
-      module=0;
+#ifdef MODULE_TRACE
+      werror("%*ndirnode(%O)->module_checker()->`!()\n",sizeof(backtrace()),dirname);
+#endif
       if(module=findmodule(dirname+"/module", handler))
+      {
 	if(mixed tmp=module->_module_value)
 	  module=tmp;
+
+	/* This allows for `[] to have side effects first time
+	 * it is called. (Specifically, the Calendar module uses
+	 * this
+	 */
+	cache=([]);
+	_cache_full=0;
+      }
       return !module;
     }
 
-    mixed `[](string index) { if(module) return module[index]; }
+    mixed `[](string index)
+      { 
+#ifdef MODULE_TRACE
+	werror("%*ndirnode(%O)->module_checker()[%O]\n",sizeof(backtrace()),dirname,index);
+#endif
+	if(module) return module[index];
+      }
     array(string) _indices() { if(module) return indices(module); }
     array _values() { if(module) return values(module); }
   }
 
   static mixed ind(string index)
   {
+#ifdef MODULE_TRACE
+    werror("%*nDirnode(%O) ind[%O] -> ???\n",sizeof(backtrace()),dirname,index);
+#endif
     if(module) 
     {
+#ifdef MODULE_TRACE
+      werror("%*nDirnode(%O) module[%O] -> ???\n",sizeof(backtrace()),dirname,index);
+#endif
       object o;
+//      _describe(module);
       if(!zero_type(o=module[index]))
       {
-//	werror("Dirnode(%O) module[%O] -> %O\n",dirname,index, o);
+#ifdef MODULE_TRACE
+	werror("%*nDirnode(%O) module[%O] -> %O\n",sizeof(backtrace()),dirname,index, o);
+#endif
 	return o;
       }
     }
@@ -854,16 +905,25 @@ class dirnode(string dirname, object|void handler)
   mixed `[](string index)
   {
     mixed ret;
-//      werror("Dirnode(%O) cache[%O] ?????\n",dirname,index);
-      if(!zero_type(ret=cache[index]))
+#ifdef MODULE_TRACE
+    werror("%*nDirnode(%O) cache[%O] ?????\n",sizeof(backtrace()),dirname,index);
+#endif
+    if(!zero_type(ret=cache[index]))
     {
-//      werror("Dirnode(%O) cache[%O] -> %O\n",dirname,index, ret);
+#ifdef MODULE_TRACE
+      werror("%*nDirnode(%O) cache[%O] -> %O\n",sizeof(backtrace()),dirname,index, ret);
+#endif
       // The check below is to (hopefully) avoid calling any function
       // in ret (like `! or `==) in case it's an object.
       if(!intp (ret) || ret) return ret;
       return UNDEFINED;
     }
-    return cache[index]=ind(index);
+    ret=ind(index);
+
+    // Kluge!
+    if(ret == __placeholder_object) return ret;
+
+    return cache[index]=ret;
   }
 
   static int _cache_full;
@@ -1026,6 +1086,9 @@ mapping(string:mixed) fc=([]);
 object findmodule(string fullname, object|void handler)
 {
   object o;
+#ifdef MODULE_TRACE
+  werror("%*nfindmodule(%O)\n",sizeof(backtrace()),fullname);
+#endif
   if(!zero_type(o=fc[fullname]))
   {
 //    werror("fc[%O] -> %O\n",fullname, o);
@@ -1035,7 +1098,7 @@ object findmodule(string fullname, object|void handler)
   if(Stat stat=master_file_stat(fakeroot(fullname+".pmod")))
   {
     if(stat[1]==-2)
-      return fc[fullname]=dirnode(fullname+".pmod", handler);
+      return dirnode(fullname+".pmod", handler);
   }
 
   if(o = low_cast_to_object(fullname+".pmod", "/.", handler))
@@ -1062,7 +1125,8 @@ mixed handle_import(string what, string|void current_file, object|void handler)
   if (handler) {
     return dirnode(path, handler);
   }
-  return fc[path]=dirnode(path);
+  if(fc[path]) return fc[path];
+  return dirnode(path);
 }
 
 
@@ -1204,6 +1268,7 @@ class CompatResolver
   mixed resolv_base(string identifier, string|void current_file,
 		    object|void current_handler)
     {
+//      werror("Resolv_base(%O)\n",identifier);
       array(mixed) tmp = ({});
       string dir=current_file ? dirname(current_file) : "/";
 
@@ -1245,6 +1310,8 @@ class CompatResolver
   mixed resolv(string identifier, string|void current_file,
 	       object|void current_handler)
     {
+//      werror("Resolv(%O)\n",identifier);
+
       // FIXME: Support having the cache in the handler?
       if( no_resolv[ identifier ] )
 	return UNDEFINED;
@@ -1257,8 +1324,12 @@ class CompatResolver
 
       mixed ret;
       string id=identifier+":"+(current_file ? dirname(current_file) : "-");
-      if( !zero_type (ret = resolv_cache[id]) )
-	return ret == ZERO_TYPE ? UNDEFINED : resolv_cache[id];
+      if( zero_type (ret = resolv_cache[id]) != 1 )
+      {
+//	werror("Resolv cached(%O) => %O (%d)\n",id,resolv_cache[id],zero_type(resolv_cache[id]));
+	return ret == ZERO_TYPE ? UNDEFINED : ret;
+      }
+
       array(string) tmp=identifier/".";
       ret=resolv_base(tmp[0], current_file, current_handler);
       foreach(tmp[1..],string index) ret=ret[index];
@@ -2386,6 +2457,34 @@ string describe_error (mixed trace)
 
 class Codec
 {
+  string fname;
+  int mkobj;
+  program prog_to_mkobj;
+  void create(void|string f,void|int m)
+    {
+      fname=f;
+      mkobj=m;
+    }
+
+  void __register_new_program(program p)
+    {
+      if(fname)
+      {
+	programs[fname]=prog_to_mkobj=p;
+	fname=0;
+      }
+    }
+
+
+  void __register_new_object(program p)
+    {
+      if(prog_to_mkobj == p)
+      {
+	objects[p]=p();
+	prog_to_mkobj=0;
+      }
+    }
+
   mapping f=all_constants();
 
   string nameof(mixed x)
diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index e91792034355f3a8d3523237de79fc582e68f6cc..7e7a4016ea46236ad3a25ec0b9c52314daecf50a 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.407 2001/09/27 20:28:28 hubbe Exp $");
+RCSID("$Id: builtin_functions.c,v 1.408 2001/10/05 01:30:11 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -1060,17 +1060,18 @@ PMOD_EXPORT void f_zero_type(INT32 args)
   if(args < 1)
     SIMPLE_TOO_FEW_ARGS_ERROR("zero_type",1);
 
-  if(Pike_sp[-args].type != T_INT)
+  if((Pike_sp[-args].type==T_OBJECT || Pike_sp[-args].type==T_FUNCTION)
+     && !Pike_sp[-args].u.object->prog)
   {
     pop_n_elems(args);
-    push_int(0);
+    push_int(NUMBER_DESTRUCTED);
   }
-  else if((Pike_sp[-args].type==T_OBJECT || Pike_sp[-args].type==T_FUNCTION)
-	   && !Pike_sp[-args].u.object->prog)
+  else if(Pike_sp[-args].type != T_INT)
   {
     pop_n_elems(args);
-    push_int(NUMBER_DESTRUCTED);
+    push_int(0);
   }
+  else
   {
     pop_n_elems(args-1);
     Pike_sp[-1].u.integer=Pike_sp[-1].subtype;
@@ -3140,10 +3141,6 @@ PMOD_EXPORT void f_compile(INT32 args)
 
   p = compile(Pike_sp[-args].u.string, o, major, minor, p, placeholder);
 
-#ifdef PIKE_DEBUG
-  if(!(p->flags & PROGRAM_FINISHED))
-    fatal("Got unfinished program from internal compile().\n");
-#endif
   pop_n_elems(args);
   push_program(p);
 }
diff --git a/src/compilation.h b/src/compilation.h
index 52cf7eaeea16557ebf771e8e088cabdd2a88788b..15cda81736be91f0fcfd584f2cca37affffb2048 100644
--- a/src/compilation.h
+++ b/src/compilation.h
@@ -1,5 +1,5 @@
 /*
- * $Id: compilation.h,v 1.24 2001/10/02 09:08:18 hubbe Exp $
+ * $Id: compilation.h,v 1.25 2001/10/05 01:30:12 hubbe Exp $
  *
  * Compilator state push / pop operator construction file
  *
@@ -149,6 +149,8 @@
   IMEMBER(int, compat_major, PIKE_MAJOR_VERSION)
   IMEMBER(int, compat_minor, PIKE_MINOR_VERSION)
   ZMEMBER(int, check_final, 0)
+  ZMEMBER(struct program_state *,depends_on,0)
+  ZMEMBER(struct compilation *,compiler,0)
   SEND
 
 #undef PCODE
diff --git a/src/encode.c b/src/encode.c
index fe11e5e308ac0cb97ea0eebf1a1d1b5287d0b420..4bf50c3deea09278050347c876ff42696dba42b7 100644
--- a/src/encode.c
+++ b/src/encode.c
@@ -25,7 +25,7 @@
 #include "version.h"
 #include "bignum.h"
 
-RCSID("$Id: encode.c,v 1.129 2001/09/24 14:25:54 grubba Exp $");
+RCSID("$Id: encode.c,v 1.130 2001/10/05 01:30:12 hubbe Exp $");
 
 /* #define ENCODE_DEBUG */
 
@@ -2115,6 +2115,12 @@ static void decode_value2(struct decode_data *data)
 	  SET_ONERROR(err3, zap_unfinished_program, p);
 	  
 	  debug_malloc_touch(p);
+	  if(data->codec)
+	  {
+	    ref_push_program(p);
+	    apply(data->codec, "__register_new_program", 1);
+	    pop_stack();
+	  }
 	  tmp.type=T_PROGRAM;
 	  tmp.u.program=p;
 	  EDB(2,fprintf(stderr, "%*sDecoding a program to <%d>: ",
@@ -2390,6 +2396,13 @@ static void decode_value2(struct decode_data *data)
 	  debug_malloc_touch(dat);
 	  debug_malloc_touch(p);
 	  p->flags |= PROGRAM_PASS_1_DONE | PROGRAM_FIXED;
+	  if(data->codec)
+	  {
+	    ref_push_program(p);
+	    apply(data->codec, "__register_new_object", 1);
+	    pop_stack();
+	  }
+	  
 	  for(d=0;d<p->num_constants;d++)
 	  {
 	    decode_value2(data);
diff --git a/src/global.h b/src/global.h
index 744b9200eb92cf6844d4cf5a79600ef1cc8c36f5..90ac0d29ce98e01e3937ed920ce20b68104be07b 100644
--- a/src/global.h
+++ b/src/global.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: global.h,v 1.64 2001/08/30 23:09:57 mast Exp $
+ * $Id: global.h,v 1.65 2001/10/05 01:30:12 hubbe Exp $
  */
 #ifndef GLOBAL_H
 #define GLOBAL_H
@@ -232,9 +232,11 @@ void *alloca();
 
 #ifndef WITH_DOUBLE_PRECISION_SVALUE
 #define FLOAT_TYPE float
+#define SIZEOF_FLOAT_TYPE SIZEOF_FLOAT
 #else
 #ifdef WITH_LONG_DOUBLE_PRECISION_SVALUE
 #define FLOAT_TYPE long double
+#define SIZEOF_FLOAT_TYPE SIZEOF_LONG_DOUBLE
 #else
 #define FLOAT_TYPE double
 #endif /* long double */
@@ -242,15 +244,19 @@ void *alloca();
 
 #ifdef WITH_LONG_INT
 #define INT_TYPE long
+#define SIZEOF_INT_TYPE SIZEOF_LONG
 #else
 #ifdef WITH_LONG_LONG_INT
 #define INT_TYPE long long
+#define SIZEOF_INT_TYPE SIZEOF_LONG_LONG
 #else
 #ifdef WITH_SHORT_INT
 #define INT_TYPE short
+#define SIZEOF_INT_TYPE SIZEOF_SHORT
 #else
 #ifdef WITH_INT_INT
 #define INT_TYPE int
+#define SIZEOF_INT_TYPE SIZEOF_INT
 #else
 #if (SIZEOF_CHAR_P > 4) && 0
 /* This isn't a good idea on architectures where
@@ -261,6 +267,7 @@ void *alloca();
 #define INT_TYPE LONGEST
 #else /* !(sizeof(char *) > 4) */
 #define INT_TYPE INT32
+#define SIZEOF_INT_TYPE 4
 #endif /* sizeof(char *) > 4 */
 #endif /* WITH_INT_INT */
 #endif /* WITH_SHORT_INT */
diff --git a/src/interpret.c b/src/interpret.c
index 9e9e13e93d233dbf1b645e573aba97ea03155ed0..27afad4131df75c534dd544e6e7894991dcf1bf6 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: interpret.c,v 1.249 2001/09/24 14:14:46 grubba Exp $");
+RCSID("$Id: interpret.c,v 1.250 2001/10/05 01:30:12 hubbe Exp $");
 #include "interpret.h"
 #include "object.h"
 #include "program.h"
@@ -1456,6 +1456,7 @@ PMOD_EXPORT void f_call_function(INT32 args)
 
 PMOD_EXPORT void call_handle_error(void)
 {
+  dmalloc_touch_svalue(&throw_value);
   if (Pike_interpreter.svalue_stack_margin) {
     ONERROR tmp;
     int old_t_flag = t_flag;
diff --git a/src/interpret_functions.h b/src/interpret_functions.h
index 1e28ae25b075738bedb514dd9b8fd195b68e66fa..d9a61dd7892c53568e3c5167cefcebc15c553305 100644
--- a/src/interpret_functions.h
+++ b/src/interpret_functions.h
@@ -1,5 +1,5 @@
 /*
- * $Id: interpret_functions.h,v 1.96 2001/09/29 08:47:03 hubbe Exp $
+ * $Id: interpret_functions.h,v 1.97 2001/10/05 01:30:13 hubbe Exp $
  *
  * Opcode definitions for the interpreter.
  */
@@ -2210,8 +2210,15 @@ OPCODE0(F_THIS_OBJECT, "this_object", {
 OPCODE0(F_ZERO_TYPE, "zero_type", {
   if(Pike_sp[-1].type != T_INT)
   {
-    pop_stack();
-    push_int(0);
+    if((Pike_sp[-1].type==T_OBJECT || Pike_sp[-1].type==T_FUNCTION)
+       && !Pike_sp[-1].u.object->prog)
+    {
+      pop_stack();
+      push_int(NUMBER_DESTRUCTED);
+    }else{
+      pop_stack();
+      push_int(0);
+    }
   }else{
     Pike_sp[-1].u.integer=Pike_sp[-1].subtype;
     Pike_sp[-1].subtype=NUMBER_NUMBER;
diff --git a/src/las.c b/src/las.c
index c95135220668d9e6dcc92d01517db18e80f12da1..7ddb285ba365ee8e91a7f923fb740eab79375f93 100644
--- a/src/las.c
+++ b/src/las.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: las.c,v 1.270 2001/09/29 11:31:40 hubbe Exp $");
+RCSID("$Id: las.c,v 1.271 2001/10/05 01:30:13 hubbe Exp $");
 
 #include "language.h"
 #include "interpret.h"
@@ -1734,7 +1734,6 @@ node *recursive_add_call_arg(node *n, node *arg)
   return n;
 }
 
-
 node *index_node(node *n, char *node_name, struct pike_string *id)
 {
   node *ret;
@@ -1789,6 +1788,29 @@ node *index_node(node *n, char *node_name, struct pike_string *id)
       push_int(0);
       break;
 
+    case T_OBJECT:
+    case T_PROGRAM:
+#if 1
+      if(!(Pike_compiler->new_program->flags & PROGRAM_PASS_1_DONE))
+      {
+	struct program *p;
+	if(Pike_sp[-1].type == T_OBJECT)
+	  p=Pike_sp[-1].u.object->prog;
+	else
+	  p=Pike_sp[-1].u.program;
+	
+	if(p && !(p->flags & PROGRAM_PASS_1_DONE))
+	{
+	  if(report_compiler_dependency(p))
+	  {
+	    pop_stack();
+	    ref_push_object(placeholder_object);
+	    break;
+	  }
+	}
+      }
+#endif
+
     default:
     {
       ptrdiff_t c;
@@ -1831,19 +1853,26 @@ node *index_node(node *n, char *node_name, struct pike_string *id)
 	   !Pike_sp[-1].u.integer &&
 	   Pike_sp[-1].subtype==NUMBER_UNDEFINED)
 	{
-	  if (node_name) {
-	    my_yyerror("Index '%s' not present in module '%s'.",
-		       id->str, node_name);
-	  } else {
-	    my_yyerror("Index '%s' not present in module.", id->str);
-	  }
-
-	  if (thrown.type != PIKE_T_UNKNOWN) {
-	    push_svalue(&thrown);
-	    low_safe_apply_handler("compile_exception", error_handler, compat_handler, 1);
-	    if (IS_ZERO(sp-1)) yy_describe_exception(&thrown);
+	  if(Pike_compiler->new_program->flags & PROGRAM_PASS_1_DONE)
+	  {
+	    if (node_name) {
+	      my_yyerror("Index '%s' not present in module '%s'.",
+			 id->str, node_name);
+	    } else {
+	      my_yyerror("Index '%s' not present in module.", id->str);
+	    }
+	    
+	    if (thrown.type != PIKE_T_UNKNOWN) {
+	      push_svalue(&thrown);
+	      low_safe_apply_handler("compile_exception", error_handler, compat_handler, 1);
+	      if (IS_ZERO(sp-1)) yy_describe_exception(&thrown);
+	      pop_stack();
+	      free_svalue(&thrown);
+	    }
+	  }else{
+	    /* Hope it's there in pass 2 */
 	    pop_stack();
-	    free_svalue(&thrown);
+	    ref_push_object(placeholder_object);
 	  }
 	}
       }
diff --git a/src/object.c b/src/object.c
index dc6853eb5b3ec5b886f97fa8beb9a52844b1f9f6..ced4af41f184763bc0569b37cd1c74c5434e81ed 100644
--- a/src/object.c
+++ b/src/object.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: object.c,v 1.185 2001/09/24 14:47:53 grubba Exp $");
+RCSID("$Id: object.c,v 1.186 2001/10/05 01:30:13 hubbe Exp $");
 #include "object.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
@@ -909,12 +909,14 @@ PMOD_EXPORT void low_object_index_no_free(struct svalue *to,
   switch(i->identifier_flags & (IDENTIFIER_FUNCTION | IDENTIFIER_CONSTANT))
   {
   case IDENTIFIER_PIKE_FUNCTION:
+#if 0
     if (i->func.offset == -1) {	/* prototype */
       to->type=T_INT;
       to->subtype=NUMBER_UNDEFINED;
       to->u.integer=0;
       break;
     }
+#endif
   case IDENTIFIER_FUNCTION:
   case IDENTIFIER_C_FUNCTION:
     to->type=T_FUNCTION;
@@ -1030,7 +1032,7 @@ PMOD_EXPORT void object_index_no_free(struct svalue *to,
 			   struct svalue *index)
 {
   struct program *p = NULL;
-  int lfun;
+  int lfun,l;
 
   if(!o || !(p=o->prog))
   {
@@ -1039,7 +1041,23 @@ PMOD_EXPORT void object_index_no_free(struct svalue *to,
   }
   lfun=ARROW_INDEX_P(index) ? LFUN_ARROW : LFUN_INDEX;
 
-  if(FIND_LFUN(p, lfun) != -1)
+  if(p->flags & PROGRAM_FIXED)
+  {
+    l=p->lfuns[lfun];
+  }else{
+    if(!(p->flags & PROGRAM_PASS_1_DONE))
+    {
+      if(report_compiler_dependency(p))
+      {
+/*	fprintf(stderr,"PLACEHOLDER DEPLOYED\n"); */
+	add_ref(to->u.object=placeholder_object);
+	to->type=T_OBJECT;
+	return;
+      }
+    }
+    l=low_find_lfun(p, lfun);
+  }
+  if(l != -1)
   {
     push_svalue(index);
     apply_lfun(o,lfun,1);
diff --git a/src/pike_types.c b/src/pike_types.c
index c632205d8058d3f29cb30ba3a440217c221abe8f..5f36be8b253cb6d03c94552d65096712ec2482ba 100644
--- a/src/pike_types.c
+++ b/src/pike_types.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: pike_types.c,v 1.181 2001/08/20 18:08:50 mast Exp $");
+RCSID("$Id: pike_types.c,v 1.182 2001/10/05 01:30:13 hubbe Exp $");
 #include <ctype.h>
 #include "svalue.h"
 #include "pike_types.h"
@@ -29,7 +29,7 @@ RCSID("$Id: pike_types.c,v 1.181 2001/08/20 18:08:50 mast Exp $");
 #include "block_alloc.h"
 
 #ifdef PIKE_DEBUG
-#define PIKE_TYPE_DEBUG
+/* #define PIKE_TYPE_DEBUG */
 #endif /* PIKE_DEBUG */
 
 /*
diff --git a/src/program.c b/src/program.c
index 0749beaaefc501648d1963629e249b6052dbc64c..b645df89930ecb4c1df9a0c2908b1e2c7e454049 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.380 2001/10/02 09:08:19 hubbe Exp $");
+RCSID("$Id: program.c,v 1.381 2001/10/05 01:30:14 hubbe Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -2002,7 +2002,6 @@ struct program *end_first_pass(int finish)
 
     Pike_compiler->new_program->flags |= PROGRAM_PASS_1_DONE;
 
-
     if(finish)
     {
       if(Pike_compiler->new_program->flags & PROGRAM_USES_PARENT)
@@ -4419,134 +4418,219 @@ void yy_describe_exception(struct svalue *thrown)
   }
 }
 
-struct program *compile(struct pike_string *prog,
-			struct object *handler,/* error handler */
-			int major, int minor,
-			struct program *target,
-			struct object *placeholder)
-{
+extern void yyparse(void);
+
 #ifdef PIKE_DEBUG
-  ONERROR tmp;
+#define do_yyparse() do {				\
+  struct svalue *save_sp=Pike_sp;			\
+  yyparse();  /* Parse da program */			\
+  if(save_sp != Pike_sp)				\
+    fatal("yyparse() left droppings on the stack!\n");	\
+}while(0)
+#else
+#define do_yyparse() yyparse()
 #endif
+
+struct compilation
+{
+  struct pike_string *prog;
+  struct object *handler;
+  int major, minor;
+  struct program *target;
+  struct object *placeholder;
+  
   struct program *p;
   struct lex save_lex;
-  int save_depth=compilation_depth;
+  int save_depth;
   int saved_threads_disabled;
-  struct object *saved_handler = error_handler;
-  struct object *saved_compat_handler = compat_handler;
-  dynamic_buffer used_modules_save = used_modules;
-  INT32 num_used_modules_save = Pike_compiler->num_used_modules;
-  extern void yyparse(void);
-  struct mapping *resolve_cache_save = resolve_cache;
-  resolve_cache = 0;
-
-  CDFPRINTF((stderr, "th(%ld) compile() starting compilation_depth=%d\n",
-	     (long)th_self(),compilation_depth));
-
-  if(placeholder && placeholder->prog != null_program)
-    Pike_error("Placeholder object is not a null_program clone!\n");
+  struct object *saved_handler;
+  struct object *saved_compat_handler;
+  dynamic_buffer used_modules_save;
+  INT32 num_used_modules_save;
+  struct mapping *resolve_cache_save;
 
-  if(target && !(target->flags & PROGRAM_VIRGIN))
-    Pike_error("Placeholder program is not virgin!\n");
+  struct svalue default_module;
 
-  low_init_threads_disable();
-  saved_threads_disabled = threads_disabled;
+  struct compilation *dependants;
+  struct compilation *next_dependant;
+};
 
-  CDFPRINTF((stderr,
-	     "th(%ld) compile() Start: threads_disabled:%d, compilation_depth:%d\n",
-	     (long)th_self(), threads_disabled, compilation_depth));
+static void free_compilation(struct compilation *c)
+{
+  debug_malloc_touch(c);
+  free_string(c->prog);
+  if(c->handler) free_object(c->handler);
+  if(c->target) free_program(c->target);
+  if(c->placeholder) free_object(c->placeholder);
+  free_svalue(& c->default_module);
+  free((char *)c);
+}
 
+static void run_init(struct compilation *c)
+{
+  debug_malloc_touch(c);
+  c->save_depth=compilation_depth;
+  compilation_depth=-1;
 
-#ifdef PIKE_DEBUG
-  SET_ONERROR(tmp, fatal_on_error,"Compiler exited with longjump!\n");
-#endif
+  c->saved_handler = error_handler;
+  if((error_handler = c->handler))
+    add_ref(error_handler);
 
-  error_handler = handler;
+  c->saved_compat_handler = compat_handler;
   compat_handler=0;
-  
-  if(error_handler)
-  {
-    add_ref(error_handler);
-    safe_apply(error_handler,"get_default_module",0);
-    if(IS_ZERO(Pike_sp-1))
-    {
-      pop_stack();
-      ref_push_mapping(get_builtin_constants());
-    }
-  }else{
-    ref_push_mapping(get_builtin_constants());
-  }
 
+  c->used_modules_save = used_modules;
+  c->num_used_modules_save = Pike_compiler->num_used_modules;
   Pike_compiler->num_used_modules=0;
 
-  save_lex=lex;
+  c->resolve_cache_save = resolve_cache;
+  resolve_cache = 0;
 
-  lex.end = prog->str + (prog->len << prog->size_shift);
-
-  switch(prog->size_shift) {
-  case 0:
-    lex.current_lexer = yylex0;
-    break;
-  case 1:
-    lex.current_lexer = yylex1;
-    break;
-  case 2:
-    lex.current_lexer = yylex2;
-    break;
-  default:
-    fatal("Program has bad shift %d!\n", prog->size_shift);
-    break;
-  }
+  c->save_lex=lex;
 
   lex.current_line=1;
   lex.current_file=make_shared_string("-");
-  if (runtime_options & RUNTIME_STRICT_TYPES) {
+
+  if (runtime_options & RUNTIME_STRICT_TYPES)
+  {
     lex.pragmas = ID_STRICT_TYPES;
   } else {
     lex.pragmas = 0;
   }
 
-  compilation_depth=-1;
-  low_start_new_program(target,0,0,0);
+  lex.end = c->prog->str + (c->prog->len << c->prog->size_shift);
+
+  switch(c->prog->size_shift)
+  {
+    case 0: lex.current_lexer = yylex0; break;
+    case 1: lex.current_lexer = yylex1; break;
+    case 2: lex.current_lexer = yylex2; break;
+    default:
+      fatal("Program has bad shift %d!\n", c->prog->size_shift);
+      break;
+  }
+
+  lex.pos=c->prog->str;
+}
+
+static void run_init2(struct compilation *c)
+{
+  debug_malloc_touch(c);
+  Pike_compiler->compiler = c;
 
   initialize_buf(&used_modules);
-  use_module(Pike_sp-1);
+  use_module(& c->default_module);
+
+  Pike_compiler->compat_major=PIKE_MAJOR_VERSION;
+  Pike_compiler->compat_minor=PIKE_MINOR_VERSION;
+
+  if(c->major>=0)
+    change_compiler_compatibility(c->major, c->minor);
+}
+
+static void run_exit(struct compilation *c)
+{
+  debug_malloc_touch(c);
+  toss_buffer(&used_modules);
+  used_modules = c->used_modules_save;
+
+#ifdef PIKE_DEBUG
+  if(Pike_compiler->num_used_modules)
+    fatal("Failed to pop modules properly.\n");
+#endif
+  Pike_compiler->num_used_modules = c->num_used_modules_save ;
+
+#ifdef PIKE_DEBUG
+  if (compilation_depth != -1) {
+    fprintf(stderr, "compile(): compilation_depth is %d\n",
+	    compilation_depth);
+  }
+#endif /* PIKE_DEBUG */
+  compilation_depth=c->save_depth;
+
+#ifdef PIKE_DEBUG
+  if (resolve_cache)
+    free_mapping(resolve_cache);
+#endif
+  resolve_cache = c->resolve_cache_save;
+
+  if (error_handler) free_object(error_handler);
+  error_handler = c->saved_handler;
+
+  if (compat_handler)  free_object(compat_handler);
+  compat_handler = c->saved_compat_handler;
+
+  free_string(lex.current_file);
+  lex=c->save_lex;
+}
+
+static void zap_placeholder(struct compilation *c)
+{
+  /* fprintf(stderr, "Destructing placeholder.\n"); */
+  if (c->placeholder->storage) {
+    yyerror("Placeholder already has storage!");
+    /* fprintf(stderr, "Placeholder already has storage!\n"
+       "placeholder: %p, storage: %p, prog: %p, p: %p\n",
+       placeholder, placeholder->storage, placeholder->prog, p); */
+    debug_malloc_touch(c->placeholder);
+    destruct(c->placeholder);
+  } else {
+    /* FIXME: Is this correct? */
+    /* It would probably be nicer if it was possible to just call
+     * destruct on the object, but this works too. -Hubbe
+     */
+    free_program(c->placeholder->prog);
+    c->placeholder->prog = NULL;
+    debug_malloc_touch(c->placeholder);
+  }
+  free_object(c->placeholder);
+  c->placeholder=0;
+}
+
+static int run_pass1(struct compilation *c)
+{
+  int ret=0;
+
+  debug_malloc_touch(c);
+  run_init(c);
+
+  CDFPRINTF((stderr, "th(%ld) compile() starting compilation_depth=%d\n",
+	     (long)th_self(),compilation_depth));
+
+  if(c->placeholder && c->placeholder->prog != null_program)
+    Pike_error("Placeholder object is not a null_program clone!\n");
+
+  if(c->target && !(c->target->flags & PROGRAM_VIRGIN))
+    Pike_error("Placeholder program is not virgin!\n");
+
+  CDFPRINTF((stderr,
+	     "th(%ld) compile() Start: threads_disabled:%d, compilation_depth:%d\n",
+	     (long)th_self(), threads_disabled, compilation_depth));
+
+
+  low_start_new_program(c->target,0,0,0);
+  Pike_compiler->compiler_pass=1;
+  run_init2(c);
 
-  if(placeholder)
+  if(c->placeholder)
   {
-    if(placeholder->prog != null_program)
+    if(c->placeholder->prog != null_program)
     {
       yyerror("Placeholder argument is not a null_program clone!");
-      placeholder=0;
+      c->placeholder=0;
+      debug_malloc_touch(c->placeholder);
     }else{
-      free_program(placeholder->prog);
-      add_ref(placeholder->prog=Pike_compiler->new_program);
+      free_program(c->placeholder->prog);
+      add_ref(c->placeholder->prog=Pike_compiler->new_program);
+      debug_malloc_touch(c->placeholder);
     }
   }
 
-/*  start_line_numbering(); */
-
-  Pike_compiler->compat_major=PIKE_MAJOR_VERSION;
-  Pike_compiler->compat_minor=PIKE_MINOR_VERSION;
-  Pike_compiler->compiler_pass=1;
-  lex.pos=prog->str;
-
-  if(major>=0)
-    change_compiler_compatibility(major, minor);
 
   CDFPRINTF((stderr, "th(%ld)   compile(): First pass\n",
 	     (long)th_self()));
 
-#ifdef PIKE_DEBUG
-  {
-    struct svalue *save_sp=Pike_sp;
-    yyparse();  /* Parse da program */
-    if(save_sp != Pike_sp)
-      fatal("yyparse() left droppings on the stack!\n");
-  }
-#else  
-  yyparse();  /* Parse da program */
-#endif
+  do_yyparse();  /* Parse da program */
 
   if (!Pike_compiler->new_program->num_linenumbers) {
     /* The lexer didn't write an initial entry. */
@@ -4560,163 +4644,229 @@ struct program *compile(struct pike_string *prog,
   CDFPRINTF((stderr, "th(%ld)   compile(): First pass done\n",
 	     (long)th_self()));
 
-  p=end_first_pass(0);
+  if(Pike_compiler->depends_on)
+  {
+    ret++;
+    c->next_dependant=Pike_compiler->depends_on->compiler->dependants;
+    Pike_compiler->depends_on->compiler->dependants=c;
+#if 0
+    fprintf(stderr,"We (%p) should link ourself to %p\n",
+	    c,
+	    Pike_compiler->depends_on->compiler);
+#endif
+  }
+
+  c->p=end_first_pass(0);
 
-  if(placeholder)
+  run_exit(c);
+
+  if(c->placeholder)
   {
-    if(!p || (placeholder->storage))
+    if(!c->p || (c->placeholder->storage))
     {
-      /* fprintf(stderr, "Destructing placeholder.\n"); */
-      if (placeholder->storage) {
-	yyerror("Placeholder already has storage!");
-	/* fprintf(stderr, "Placeholder already has storage!\n"
-	   "placeholder: %p, storage: %p, prog: %p, p: %p\n",
-	   placeholder, placeholder->storage, placeholder->prog, p); */
-	debug_malloc_touch(placeholder);
-	destruct(placeholder);
-      } else {
-	/* FIXME: Is this correct? */
-	/* It would probably be nicer if it was possible to just call
-	 * destruct on the object, but this works too. -Hubbe
-	 */
-	free_program(placeholder->prog);
-	placeholder->prog = NULL;
-      }
-      placeholder=0;
+      zap_placeholder(c);
     } else {
-      placeholder->storage=p->storage_needed ?
-	(char *)xalloc(p->storage_needed) :
+      c->placeholder->storage=c->p->storage_needed ?
+	(char *)xalloc(c->p->storage_needed) :
 	(char *)0;
-      call_c_initializers(placeholder);
+      call_c_initializers(c->placeholder);
     }
   }
 
-#ifdef PIKE_DEBUG
-  if (compilation_depth != -1) {
-    fprintf(stderr, "compile(): compilation_depth is %d at end of pass 1.\n",
-	    compilation_depth);
-  }
-#endif /* PIKE_DEBUG */
+  return ret;
+}
 
-  if(p)
-  {
-    low_start_new_program(p,0,0,0);
-    free_program(p);
-    p=0;
-    Pike_compiler->compiler_pass=2;
-    lex.pos=prog->str;
-    lex.current_line=1;
-    free_string(lex.current_file);
-    lex.current_file=make_shared_string("-");
+void run_pass2(struct compilation *c)
+{
+  debug_malloc_touch(c);
+  run_init(c);
+  low_start_new_program(c->p,0,0,0);
+  free_program(c->p);
+  c->p=0;
+  Pike_compiler->compiler_pass=2;
+  run_init2(c);
+  
+  CDFPRINTF((stderr, "th(%ld)   compile(): Second pass\n",
+	     (long)th_self()));
+  
+  do_yyparse();  /* Parse da program */
+  
+  CDFPRINTF((stderr, "th(%ld)   compile(): Second pass done\n",
+	     (long)th_self()));
+  
+  c->p=end_program();
+  run_exit(c);
+}
 
-    use_module(Pike_sp-1);
+static void run_cleanup(struct compilation *c, int delayed)
+{
+  debug_malloc_touch(c);
+#if 0 /* FIXME */
+  if (threads_disabled != c->saved_threads_disabled) {
+    fatal("compile(): threads_disabled:%d saved_threads_disabled:%d\n",
+	  threads_disabled, c->saved_threads_disabled);
+  }
+#endif /* PIKE_DEBUG */
 
-    if(major>=0)
-      change_compiler_compatibility(major, minor);
+  exit_threads_disable(NULL);
 
-    CDFPRINTF((stderr, "th(%ld)   compile(): Second pass\n",
-	       (long)th_self()));
+  CDFPRINTF((stderr,
+	     "th(%ld) compile() Leave: threads_disabled:%d, compilation_depth:%d\n",
+	     (long)th_self(),threads_disabled, compilation_depth));
+  if (!c->p)
+  {
+    /* fprintf(stderr, "Destructing placeholder.\n"); */
+    if(c->placeholder)
+      zap_placeholder(c);
 
-#ifdef PIKE_DEBUG
+    if(delayed && c->target)
     {
-      struct svalue *save_sp=Pike_sp;
-      yyparse();  /* Parse da program */
-      if(save_sp != Pike_sp)
-	fatal("yyparse() left droppings on the stack!\n");
+      /* We have to notify the master object that
+       * a previous compile() actually failed, even
+       * if we did not know it at the time
+       */
+      push_program(c->target);
+      SAFE_APPLY_MASTER("unregister",1);
     }
-#else  
-    yyparse();  /* Parse da program */
-#endif
-
-    CDFPRINTF((stderr, "th(%ld)   compile(): Second pass done\n",
-	       (long)th_self()));
-
-    p=end_program();
-
-#ifdef PIKE_DEBUG
-    if (compilation_depth != -1) {
-      fprintf(stderr, "compile(): compilation_depth is %d at end of pass 2.\n",
-	      compilation_depth);
+  }
+  else
+  {
+    if (c->placeholder)
+    {
+      JMP_BUF rec;
+      /* Initialize the placeholder. */
+      if(SETJMP(rec))
+      {
+	dmalloc_touch_svalue(&throw_value);
+	call_handle_error();
+	zap_placeholder(c);
+      }else{
+	call_pike_initializers(c->placeholder,0);
+      }
+      UNSETJMP(rec);
     }
-#endif /* PIKE_DEBUG */
   }
+}
 
+struct program *compile(struct pike_string *aprog,
+			struct object *ahandler,/* error handler */
+			int amajor, int aminor,
+			struct program *atarget,
+			struct object *aplaceholder)
+{
+  int delay;
+  struct program *ret;
 #ifdef PIKE_DEBUG
-  if (threads_disabled != saved_threads_disabled) {
-    fatal("compile(): threads_disabled:%d saved_threads_disabled:%d\n",
-	  threads_disabled, saved_threads_disabled);
+  ONERROR tmp;
+#endif
+  struct compilation *c=ALLOC_STRUCT(compilation);
+
+  debug_malloc_touch(c);
+  add_ref(c->prog=aprog);
+  if((c->handler=ahandler)) add_ref(ahandler);
+  c->major=amajor;
+  c->minor=aminor;
+  if((c->target=atarget)) add_ref(atarget);
+  if((c->placeholder=aplaceholder)) add_ref(aplaceholder);
+  c->default_module.type=T_INT;
+  c->dependants=0;
+  c->next_dependant=0;
+
+  if(c->handler)
+  {
+    safe_apply(c->handler,"get_default_module",0);
+    if(IS_ZERO(Pike_sp-1))
+    {
+      pop_stack();
+      ref_push_mapping(get_builtin_constants());
+    }
+  }else{
+    ref_push_mapping(get_builtin_constants());
   }
-#endif /* PIKE_DEBUG */
+  free_svalue(& c->default_module);
+  c->default_module=Pike_sp[-1];
+  Pike_sp--;
 
-  free_string(lex.current_file);
-  lex=save_lex;
-
-/*  unuse_modules(1); */
 #ifdef PIKE_DEBUG
-  if(Pike_compiler->num_used_modules)
-    fatal("Failed to pop modules properly.\n");
+  SET_ONERROR(tmp, fatal_on_error,"Compiler exited with longjump!\n");
 #endif
 
-  toss_buffer(&used_modules);
-  compilation_depth=save_depth;
-  used_modules = used_modules_save;
-  Pike_compiler->num_used_modules = num_used_modules_save ;
-  if (error_handler) {
-    free_object(error_handler);
-  }
-  error_handler = saved_handler;
-  if (compat_handler) {
-    free_object(compat_handler);
-  }
-  compat_handler = saved_compat_handler;
+  low_init_threads_disable();
+  c->saved_threads_disabled = threads_disabled;
+
+  
+  delay=run_pass1(c) && c->p;
+
+  while(c->dependants)
+  {
+    struct compilation *cc=c->dependants;
+
 #ifdef PIKE_DEBUG
-  if (resolve_cache) fatal("resolve_cache not freed at end of compilation.\n");
+    if(c == cc)
+      fatal("Depending on myself???\n");
 #endif
-  resolve_cache = resolve_cache_save;
 
-/*  threads_disabled = saved_threads_disabled + 1;   /Hubbe: UGGA! */
+    c->dependants=cc->next_dependant;
+    cc->next_dependant=0;
+    debug_malloc_touch(cc);
 
-  CDFPRINTF((stderr,
-	     "th(%ld) compile() Leave: threads_disabled:%d, compilation_depth:%d\n",
-	     (long)th_self(),threads_disabled, compilation_depth));
+    if(cc->p) run_pass2(cc);
+    run_cleanup(cc,1);
 
-  exit_threads_disable(NULL);
+    debug_malloc_touch(cc);
+
+#ifdef PIKE_DEBUG
+    if(cc->dependants)
+      fatal("Que???\n");
+#endif
+
+    free_compilation(cc);
+  }
 
 #ifdef PIKE_DEBUG
+  /* FIXME */
   UNSET_ONERROR(tmp);
 #endif
-  pop_stack(); /* pop the 'default' module */
 
-  if (!p) {
-    /* fprintf(stderr, "Destructing placeholder.\n"); */
-    if(placeholder)
-    {
-      if (placeholder->storage) {
-	/* fprintf(stderr, "Placeholder already has storage!\n"
-	   "placeholder: %p, storage: %p, prog: %p, p: %p\n",
-	   placeholder, placeholder->storage, placeholder->prog, p); */
-	debug_malloc_touch(placeholder);
-	destruct(placeholder);
-      } else {
-	/* FIXME: Is this correct? */
-	/* It would probably be nicer if it was possible to just call
-	 * destruct on the object, but this works too. -Hubbe
-	 */
-	free_program(placeholder->prog);
-	placeholder->prog = NULL;
-      }
-      placeholder=0;
-    }
+  if(delay)
+  {
+    /* finish later */
+    return c->p;
+  }else{
+    /* finish now */
+    if(c->p) run_pass2(c);
+    debug_malloc_touch(c);
+    run_cleanup(c,0);
+    
+    ret=c->p;
 
-    throw_error_object(low_clone(compilation_error_program), 0, 0, 0,
-		       "Compilation failed.\n");
+    debug_malloc_touch(c);
+    free_compilation(c);
+    if(!ret)
+      throw_error_object(low_clone(compilation_error_program), 0, 0, 0,
+			 "Compilation failed.\n");
+    return ret;
   }
+}
 
-  if (placeholder) {
-    /* Initialize the placeholder. */
-    call_pike_initializers(placeholder,0);
+int report_compiler_dependency(struct program *p)
+{
+  if(Pike_compiler && Pike_compiler->new_program && 
+     !(Pike_compiler->new_program->flags & PROGRAM_PASS_1_DONE))
+  {
+    struct program_state *c;
+    c=Pike_compiler->depends_on;
+    if(!c) c=Pike_compiler->previous;
+    for(;c;c=c->previous)
+    {
+      if(c->new_program == p)
+      {
+	Pike_compiler->depends_on=c;
+	return 1; /* dependency registred */
+      }
+    }
   }
-  return p;
+  return 0; /* dependency not registred */
 }
 
 PMOD_EXPORT int pike_add_function2(char *name, void (*cfun)(INT32),
@@ -4902,6 +5052,19 @@ static void gc_recurse_trampoline(struct object *o)
 }
 
 
+/* This placeholder should is used
+ * in the first compiler pass to take the place
+ * of unknown things
+ */
+struct program *placeholder_program;
+struct object *placeholder_object;
+
+void placeholder_index(INT32 args)
+{
+  pop_n_elems(args);
+  ref_push_object(Pike_fp->current_object);
+}
+
 void init_program(void)
 {
   int i;
@@ -4910,7 +5073,6 @@ void init_program(void)
   struct svalue id;
   init_program_blocks();
 
-
   MAKE_CONSTANT_SHARED_STRING(this_program_string,"this_program");
 
   lfun_ids = allocate_mapping(NUM_LFUNS);
@@ -4952,6 +5114,20 @@ void init_program(void)
     low_add_constant("__null_program",&s);
     debug_malloc_touch(null_program);
   }
+
+  {
+    struct svalue s;
+    start_new_program();
+    add_function("`()",placeholder_index,"function(mixed...:object)",0);
+    add_function("`[]",placeholder_index,"function(mixed:object)",0);
+    placeholder_program=end_program();
+    placeholder_object=fast_clone_object(placeholder_program,0);
+
+    s.type=T_OBJECT;
+    s.u.object=placeholder_object;
+    low_add_constant("__placeholder_object",&s);
+    debug_malloc_touch(placeholder_object);
+  }
 }
 
 void cleanup_program(void)
@@ -4994,6 +5170,18 @@ void cleanup_program(void)
     free_program(null_program);
     null_program=0;
   }
+
+  if(placeholder_object)
+  {
+    free_object(placeholder_object);
+    placeholder_object=0;
+  }
+
+  if(placeholder_program)
+  {
+    free_program(placeholder_program);
+    placeholder_program=0;
+  }
 #endif
 }
 
diff --git a/src/program.h b/src/program.h
index 1950555c8460fc73280b31469ecee85974013546..36c3fac993b48201f6841ffeaa059ddcc7735232 100644
--- a/src/program.h
+++ b/src/program.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: program.h,v 1.144 2001/09/10 20:47:35 hubbe Exp $
+ * $Id: program.h,v 1.145 2001/10/05 01:30:14 hubbe Exp $
  */
 #ifndef PROGRAM_H
 #define PROGRAM_H
@@ -345,6 +345,8 @@ extern struct object *compat_handler;
 extern struct program *first_program;
 extern struct program *pike_trampoline_program;
 extern struct program *gc_internal_program;
+extern struct program *placeholder_program;
+extern struct object *placeholder_object;
 
 extern int compilation_depth;
 
@@ -380,7 +382,6 @@ void low_start_new_program(struct program *p,
 			   int flags,
 			   int *idp);
 PMOD_EXPORT void debug_start_new_program(PROGRAM_LINE_ARGS);
-PMOD_EXPORT void really_free_program(struct program *p);
 void dump_program_desc(struct program *p);
 int sizeof_variable(int run_time_type);
 void check_program(struct program *p);
@@ -393,7 +394,7 @@ PMOD_EXPORT void set_exit_callback(void (*exit)(struct object *));
 PMOD_EXPORT void set_gc_recurse_callback(void (*m)(struct object *));
 PMOD_EXPORT void set_gc_check_callback(void (*m)(struct object *));
 void pike_set_prog_event_callback(void (*cb)(int));
-void pike_set_prog_optimize_callback(struct node_s *(*opt)(struct node_s *));
+void pike_set_prog_optimize_callback(node *(*opt)(node *));
 int low_reference_inherited_identifier(struct program_state *q,
 				       int e,
 				       struct pike_string *name,
@@ -440,35 +441,34 @@ int define_variable(struct pike_string *name,
 		    struct pike_type *type,
 		    INT32 flags);
 PMOD_EXPORT int simple_add_variable(char *name,
-				    char *type,
-				    INT32 flags);
+			char *type,
+			INT32 flags);
 PMOD_EXPORT int add_constant(struct pike_string *name,
-			     struct svalue *c,
-			     INT32 flags);
+		 struct svalue *c,
+		 INT32 flags);
 PMOD_EXPORT int simple_add_constant(char *name,
-				    struct svalue *c,
-				    INT32 flags);
+			struct svalue *c,
+			INT32 flags);
 PMOD_EXPORT int add_integer_constant(char *name,
-				     INT32 i,
-				     INT32 flags);
+			 INT32 i,
+			 INT32 flags);
 PMOD_EXPORT int quick_add_integer_constant(char *name,
-					   int name_length,
-					   INT32 i,
-					   INT32 flags);
+			       int name_length,
+			       INT32 i,
+			       INT32 flags);
 PMOD_EXPORT int add_float_constant(char *name,
-				   double f,
-				   INT32 flags);
+			 double f,
+			 INT32 flags);
 PMOD_EXPORT int add_string_constant(char *name,
-				    char *str,
-				    INT32 flags);
+			char *str,
+			INT32 flags);
 PMOD_EXPORT int add_program_constant(char *name,
-				     struct program *p,
-				     INT32 flags);
+			 struct program *p,
+			 INT32 flags);
 PMOD_EXPORT int add_object_constant(char *name,
-				    struct object *o,
-				    INT32 flags);
-PMOD_EXPORT int add_function_constant(char *name, void (*cfun)(INT32),
-				      char * type, INT16 flags);
+			struct object *o,
+			INT32 flags);
+PMOD_EXPORT int add_function_constant(char *name, void (*cfun)(INT32), char * type, INT16 flags);
 PMOD_EXPORT int debug_end_class(char *name, ptrdiff_t namelen, INT32 flags);
 INT32 define_function(struct pike_string *name,
 		      struct pike_type *type,
@@ -498,21 +498,22 @@ void program_index_no_free(struct svalue *to, struct program *p,
 int get_small_number(char **q);
 void start_line_numbering(void);
 void store_linenumber(INT32 current_line, struct pike_string *current_file);
-char *debug_get_program_line(struct program *prog,
-			     INT32 *linep);
 PMOD_EXPORT struct pike_string *get_program_line(struct program *prog,
 						 INT32 *linep);
+char *debug_get_program_line(struct program *prog,
+		       INT32 *linep);
 PMOD_EXPORT struct pike_string *get_line(PIKE_OPCODE_T *pc,
-					 struct program *prog,
-					 INT32 *linep);
+					 struct program *prog, INT32 *linep);
 void my_yyerror(char *fmt,...)  ATTRIBUTE((format(printf,1,2)));
 void yy_describe_exception(struct svalue *thrown);
-struct program *compile(struct pike_string *prog,
-			struct object *handler,
-			int major,
-			int minor,
-			struct program *target,
-			struct object *placeholder);
+struct compilation;
+void run_pass2(struct compilation *c);
+struct program *compile(struct pike_string *aprog,
+			struct object *ahandler,
+			int amajor, int aminor,
+			struct program *atarget,
+			struct object *aplaceholder);
+int report_compiler_dependency(struct program *p);
 PMOD_EXPORT int pike_add_function2(char *name, void (*cfun)(INT32),
 				   char *type, unsigned INT8 flags,
 				   unsigned INT16 opt_flags);
@@ -524,6 +525,7 @@ PMOD_EXPORT int quick_add_function(char *name,
 				   unsigned INT8 flags,
 				   unsigned INT16 opt_flags);
 void check_all_programs(void);
+void placeholder_index(INT32 args);
 void init_program(void);
 void cleanup_program(void);
 void gc_mark_program_as_referenced(struct program *p);
@@ -534,8 +536,8 @@ void gc_mark_all_programs(void);
 void gc_cycle_check_all_programs(void);
 void gc_zap_ext_weak_refs_in_programs(void);
 void gc_free_all_unreferenced_programs(void);
-void count_memory_in_programs(INT32 *num_, INT32 *size_);
 void push_compiler_frame(int lexical_scope);
+void low_pop_local_variables(int level);
 void pop_local_variables(int level);
 void pop_compiler_frame(void);
 ptrdiff_t low_get_storage(struct program *o, struct program *p);
@@ -556,6 +558,9 @@ PMOD_EXPORT void change_compiler_compatibility(int major, int minor);
 void make_program_executable(struct program *p);
 /* Prototypes end here */
 
+void really_free_program(struct program *);
+void count_memory_in_programs(INT32*,INT32*);
+
 #ifndef PIKE_USE_MACHINE_CODE
 #define make_program_executable(X)
 #endif
diff --git a/src/threads.c b/src/threads.c
index e05114471019e426bd7e7e17a6dc5135b8538f06..ffc70a8a419c65aa23d6f0622508f7527132a8ed 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -1,5 +1,5 @@
 #include "global.h"
-RCSID("$Id: threads.c,v 1.168 2001/09/25 14:17:47 grubba Exp $");
+RCSID("$Id: threads.c,v 1.169 2001/10/05 01:30:14 hubbe Exp $");
 
 PMOD_EXPORT int num_threads = 1;
 PMOD_EXPORT int threads_disabled = 0;
@@ -922,7 +922,7 @@ void f_mutex_lock(INT32 args)
   /* Needs to be cloned here, since create()
    * might use threads.
    */
-  o=clone_object(mutex_key,0);
+  o=fast_clone_object(mutex_key,0);
 
   DO_IF_DEBUG( if(thread_for_id(th_self()) != Pike_interpreter.thread_id)
 	       fatal("thread_for_id() (or Pike_interpreter.thread_id) failed! %p != %p\n",thread_for_id(th_self()),Pike_interpreter.thread_id) ; )