diff --git a/src/apply_low.h b/src/apply_low.h
index ba757a648a48495a6742a6b51866d348aa4c2e7e..b6b362dd8b07a53b8e849cea5d8010cc55be3b9f 100644
--- a/src/apply_low.h
+++ b/src/apply_low.h
@@ -129,6 +129,12 @@
       new_frame->pc = 0;
 #ifdef SCOPE
       new_frame->scope=scope;
+#ifdef PIKE_DEBUG
+      if(new_frame->fun == scope->fun)
+      {
+	fatal("Que? A function cannot be parented by itself!\n");
+      }
+#endif
 #else
       new_frame->scope=0;
 #endif
diff --git a/src/docode.c b/src/docode.c
index 3861ffc228476a5ca0c243200a5c8e45ea812060..840b7b041dae5353c0208b58967b205a58c71745 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: docode.c,v 1.133 2001/09/28 00:01:44 hubbe Exp $");
+RCSID("$Id: docode.c,v 1.134 2001/09/29 06:19:26 hubbe Exp $");
 #include "las.h"
 #include "program.h"
 #include "pike_types.h"
@@ -2013,8 +2013,16 @@ static int do_docode2(node *n, INT16 flags)
     }
 
     case F_TRAMPOLINE:
-      emit1(F_TRAMPOLINE,n->u.id.number);
+    {
+      struct compiler_frame *f;
+      int depth=0;
+      for(f=Pike_compiler->compiler_frame;
+	  f!=n->u.trampoline.frame;f=f->previous)
+	depth++;
+
+      emit2(F_TRAMPOLINE,n->u.trampoline.ident,depth);
       return 1;
+    }
 
   case F_IDENTIFIER:
     if(IDENTIFIER_IS_FUNCTION(ID_FROM_INT(Pike_compiler->new_program, n->u.id.number)->identifier_flags))
diff --git a/src/interpret_functions.h b/src/interpret_functions.h
index a64bb0bab424cf0c471d6732aa2d202fd6a85a3c..3ac1ad6904da01b1f1e5b10187ef26acdc8898e4 100644
--- a/src/interpret_functions.h
+++ b/src/interpret_functions.h
@@ -1,5 +1,5 @@
 /*
- * $Id: interpret_functions.h,v 1.94 2001/09/28 00:01:44 hubbe Exp $
+ * $Id: interpret_functions.h,v 1.95 2001/09/29 06:19:27 hubbe Exp $
  *
  * Opcode definitions for the interpreter.
  */
@@ -274,9 +274,11 @@ OPCODE1(F_LFUN, "local function", {
   print_return_value();
 });
 
-OPCODE1(F_TRAMPOLINE, "trampoline", {
+OPCODE2(F_TRAMPOLINE, "trampoline", {
   struct object *o=low_clone(pike_trampoline_program);
-  add_ref( ((struct pike_trampoline *)(o->storage))->frame=Pike_fp );
+  struct pike_frame *f=Pike_fp;
+  while(arg2--) f=f->scope;
+  add_ref( ((struct pike_trampoline *)(o->storage))->frame=f );
   ((struct pike_trampoline *)(o->storage))->func=arg1+Pike_fp->context.identifier_level;
   push_object(o);
   /* Make it look like a function. */
diff --git a/src/language.yacc b/src/language.yacc
index fa3b24c59fa93ea72cb3afb1cfe653a819a649ff..6228eff5c4f0b461e5d6adcb41257663ecb6edf8 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -112,7 +112,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.261 2001/09/28 00:01:45 hubbe Exp $");
+RCSID("$Id: language.yacc,v 1.262 2001/09/29 06:19:27 hubbe Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
@@ -1872,7 +1872,7 @@ lambda: TOK_LAMBDA push_compiler_frame1
 		ID_STATIC | ID_PRIVATE | ID_INLINE);
 
     if(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPED) {
-      $$ = mktrampolinenode(f);
+      $$ = mktrampolinenode(f, Pike_compiler->compiler_frame->previous);
     } else {
       $$ = mkidentifiernode(f);
     }
@@ -1943,19 +1943,26 @@ local_function: TOK_IDENTIFIER push_compiler_frame1 func_args
 
     name=make_shared_string(buf);
 
-    id=define_function(name,
-		       type,
-		       0,
-		       IDENTIFIER_PIKE_FUNCTION,
-		       0,
-		       OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND);
+    if(Pike_compiler->compiler_pass > 1)
+    {
+      id=isidentifier(name);
+    }else{
+      id=define_function(name,
+			 type,
+			 0,
+			 IDENTIFIER_PIKE_FUNCTION,
+			 0,
+			 OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND);
+    }
     n=0;
-#if 0
     if(Pike_compiler->compiler_pass > 1 &&
        (i=ID_FROM_INT(Pike_compiler->new_program, id)))
-      if(!(i->identifier_flags & IDENTIFIER_SCOPED))
+    {
+      if(i->identifier_flags & IDENTIFIER_SCOPED)
+	n = mktrampolinenode(id, Pike_compiler->compiler_frame->previous);
+      else
 	n = mkidentifiernode(id);
-#endif
+    }
 
     low_add_local_name(Pike_compiler->compiler_frame->previous,
 		       $1->u.sval.u.string, type, n);
@@ -2004,11 +2011,9 @@ local_function: TOK_IDENTIFIER push_compiler_frame1 func_args
       if(Pike_compiler->compiler_frame->lexical_scope & 
 	 (SCOPE_SCOPE_USED | SCOPE_SCOPED))
       {
-	$$ = mknode(F_ASSIGN, mktrampolinenode($<number>3),
-		    mklocalnode(localid,0));
+	$$ = mktrampolinenode($<number>3,Pike_compiler->compiler_frame);
       }else{
-	$$ = mknode(F_ASSIGN, mkidentifiernode($<number>3),
-		    mklocalnode(localid,0));
+	$$ = mkidentifiernode($<number>3);
       }
     }
   }
@@ -2081,20 +2086,26 @@ local_function2: optional_stars TOK_IDENTIFIER push_compiler_frame1 func_args
 
     name=make_shared_string(buf);
 
-
-    id=define_function(name,
-		       type,
-		       0,
-		       IDENTIFIER_PIKE_FUNCTION,
-		       0,
-		       OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND);
+    if(Pike_compiler->compiler_pass > 1)
+    {
+      id=isidentifier(name);
+    }else{
+      id=define_function(name,
+			 type,
+			 0,
+			 IDENTIFIER_PIKE_FUNCTION,
+			 0,
+			 OPT_SIDE_EFFECT|OPT_EXTERNAL_DEPEND);
+    }
     n=0;
-#if 0
     if(Pike_compiler->compiler_pass > 1 &&
        (i=ID_FROM_INT(Pike_compiler->new_program, id)))
-      if(!(i->identifier_flags & IDENTIFIER_SCOPED))
+    {
+      if(i->identifier_flags & IDENTIFIER_SCOPED)
+	n = mktrampolinenode(id, Pike_compiler->compiler_frame->previous);
+      else
 	n = mkidentifiernode(id);
-#endif
+    }
 
     low_add_local_name(Pike_compiler->compiler_frame->previous,
 		       $2->u.sval.u.string, type, n);
@@ -2144,11 +2155,9 @@ local_function2: optional_stars TOK_IDENTIFIER push_compiler_frame1 func_args
       if(Pike_compiler->compiler_frame->lexical_scope & 
 	 (SCOPE_SCOPE_USED | SCOPE_SCOPED))
       {
-        $$ = mknode(F_ASSIGN, mktrampolinenode($<number>5),
-	  mklocalnode(localid,0));
+        $$ = mktrampolinenode($<number>5,Pike_compiler->compiler_frame);
       }else{
-        $$ = mknode(F_ASSIGN, mkidentifiernode($<number>5),
-	  mklocalnode(localid,0));
+        $$ = mkidentifiernode($<number>5);
       }
     }
   }
@@ -3015,7 +3024,7 @@ optional_block: ';' /* EMPTY */ { $$=0; }
 		ID_STATIC | ID_PRIVATE | ID_INLINE);
 
     if(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPED) {
-      $$ = mktrampolinenode(f);
+      $$ = mktrampolinenode(f,Pike_compiler->compiler_frame->previous);
     } else {
       $$ = mkidentifiernode(f);
     }
diff --git a/src/las.c b/src/las.c
index 55a756ded31efc19b5d21bea4beaf80023adf192..34946b5ada498611e021aeeefe83e3a6443f3f57 100644
--- a/src/las.c
+++ b/src/las.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: las.c,v 1.268 2001/09/28 00:01:45 hubbe Exp $");
+RCSID("$Id: las.c,v 1.269 2001/09/29 06:19:27 hubbe Exp $");
 
 #include "language.h"
 #include "interpret.h"
@@ -1301,9 +1301,11 @@ node *debug_mkidentifiernode(int i)
 #endif
 }
 
-node *debug_mktrampolinenode(int i)
+node *debug_mktrampolinenode(int i, struct compiler_frame *frame)
 {
+  struct compiler_frame *f;
   node *res = mkemptynode();
+
   res->token = F_TRAMPOLINE;
   copy_pike_type(res->type, ID_FROM_INT(Pike_compiler->new_program, i)->type);
 
@@ -1319,9 +1321,15 @@ node *debug_mktrampolinenode(int i)
 #ifdef __CHECKER__
   _CDR(res) = 0;
 #endif
-  res->u.id.number = i;
+  res->u.trampoline.ident=i;
+  res->u.trampoline.frame=frame;
+  
+  for(f=Pike_compiler->compiler_frame;f != frame;f=f->previous)
+    f->lexical_scope|=SCOPE_SCOPED;
+  f->lexical_scope|=SCOPE_SCOPE_USED;
+
 #ifdef SHARED_NODES
-  res->u.id.prog = Pike_compiler->new_program;
+  res->u.trampoline.prog = Pike_compiler->new_program;
 #endif /* SHARED_NODES */
 
   res = freeze_node(res);
@@ -1864,13 +1872,20 @@ int node_is_eq(node *a,node *b)
 
   switch(a->token)
   {
+  case F_TRAMPOLINE: /* FIXME, the context has to be the same! */
+#ifdef SHARED_NODES
+    if(a->u.trampoline.prog != b->u.trampoline.prog)
+      return 0;
+#endif
+    return a->u.trampoline.ident == b->u.trampoline.ident &&
+      a->u.trampoline.frame == b->u.trampoline.frame;
+      
   case F_EXTERNAL:
   case F_LOCAL:
     return a->u.integer.a == b->u.integer.a &&
       a->u.integer.b == b->u.integer.b;
       
   case F_IDENTIFIER:
-  case F_TRAMPOLINE: /* FIXME, the context has to be the same! */
     return a->u.id.number == b->u.id.number;
 
   case F_CAST:
@@ -2370,7 +2385,7 @@ static void low_print_tree(node *foo,int needlval)
   case F_TRAMPOLINE:
     if (Pike_compiler->new_program) {
       fprintf(stderr, "trampoline<%s>",
-	      ID_FROM_INT(Pike_compiler->new_program, foo->u.id.number)->name->str);
+	      ID_FROM_INT(Pike_compiler->new_program, foo->u.trampoline.ident)->name->str);
     } else {
       fprintf(stderr, "trampoline<unknown identifier>");
     }
@@ -3355,7 +3370,7 @@ void fix_type_field(node *n)
       copy_pike_type(n->type, zero_type_string);
     } else {
       type_a=CAR(n)->type;
-      if(!check_indexing(type_a, int_type_string, n))
+      if(!match_types(type_a, array_type_string))
 	if(!Pike_compiler->catch_level)
 	  my_yyerror("[*] on non-array.");
       n->type=index_type(type_a, int_type_string, n);
diff --git a/src/las.h b/src/las.h
index a2567aea14ffab2383a0c3ce57511fb0e7805dd6..871c6393023e55a5ddf7f840a0958d04f2d4fb81 100644
--- a/src/las.h
+++ b/src/las.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: las.h,v 1.52 2001/08/13 23:15:58 mast Exp $
+ * $Id: las.h,v 1.53 2001/09/29 06:19:27 hubbe Exp $
  */
 #ifndef LAS_H
 #define LAS_H
@@ -137,7 +137,7 @@ node *debug_mkefuncallnode(char *function, node *args);
 node *debug_mkopernode(char *oper_id, node *arg1, node *arg2);
 node *debug_mklocalnode(int var, int depth);
 node *debug_mkidentifiernode(int i);
-node *debug_mktrampolinenode(int i);
+node *debug_mktrampolinenode(int i, struct compiler_frame *depth);
 node *debug_mkexternalnode(struct program *prog, int i);
 node *debug_mkcastnode(struct pike_type *type, node *n);
 node *debug_mksoftcastnode(struct pike_type *type, node *n);
@@ -188,7 +188,7 @@ void resolv_program(node *n);
 #define mkopernode(oper_id, arg1, arg2) dmalloc_touch(node *, debug_mkopernode(oper_id, dmalloc_touch(node *, arg1), dmalloc_touch(node *, arg2)))
 #define mklocalnode(var, depth) dmalloc_touch(node *, debug_mklocalnode(var, depth))
 #define mkidentifiernode(i) dmalloc_touch(node *, debug_mkidentifiernode(i))
-#define mktrampolinenode(i) dmalloc_touch(node *, debug_mktrampolinenode(i))
+#define mktrampolinenode(i,f) dmalloc_touch(node *, debug_mktrampolinenode(i, f))
 #define mkexternalnode(parent_prog, i) dmalloc_touch(node *, debug_mkexternalnode(parent_prog, i))
 #define mkcastnode(type, n) dmalloc_touch(node *, debug_mkcastnode(type, dmalloc_touch(node *, n)))
 #define mksoftcastnode(type, n) dmalloc_touch(node *, debug_mksoftcastnode(type, dmalloc_touch(node *, n)))
diff --git a/src/pike_types.h b/src/pike_types.h
index d5b1dca53c558a101b7d5677e3ccc57aefaf7dda..9aa0dd01ba3834cc8219fa9a099b3e38819b33b5 100644
--- a/src/pike_types.h
+++ b/src/pike_types.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: pike_types.h,v 1.72 2001/08/30 23:32:16 mast Exp $
+ * $Id: pike_types.h,v 1.73 2001/09/29 06:19:28 hubbe Exp $
  */
 #ifndef PIKE_TYPES_H
 #define PIKE_TYPES_H
@@ -81,6 +81,8 @@ extern unsigned char *pike_type_mark_stack[PIKE_TYPE_STACK_SIZE/4];
 
 #endif /* USE_PIKE_TYPE */
 
+struct compiler_frame;
+
 /* Also used in struct node_identifier */
 union node_data
 {
@@ -89,6 +91,14 @@ union node_data
     int number;
     struct program *prog;
   } id;
+  struct
+  {
+    int ident;
+    struct compiler_frame *frame;
+#ifdef SHARED_NODES
+    struct program *prog;
+#endif
+  } trampoline;
   struct svalue sval;
   struct
   {
diff --git a/src/program.c b/src/program.c
index db48582bdbc987da25f2b0dcc2c36965cd3968f8..68e05628a3e4ff557fe12ec5a41882c5bbfb8c8c 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.377 2001/09/27 15:17:47 grubba Exp $");
+RCSID("$Id: program.c,v 1.378 2001/09/29 06:19:28 hubbe Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -3216,21 +3216,18 @@ PMOD_EXPORT int add_constant(struct pike_string *name,
 				 id->opt_flags);
 	  
 	}
-	else if(id->identifier_flags & IDENTIFIER_CONSTANT &&
+	else if((id->identifier_flags & IDENTIFIER_CONSTANT) &&
 		id->func.offset != -1)
 	{
 	  c=& Pike_compiler->new_program->constants[id->func.offset].sval;
 	}
       }
-#if 0
       else
       {
-	/* Actually, we do not allow fake objects to enter
-	 * the mainstream, but it would be possible to do so.
-	 * I will leave this code here just in case someone wants
-	 * to use it in the future
-	 */
-	if(id->identifier_flags & IDENTIFIER_CONSTANT)
+	if((id->identifier_flags & IDENTIFIER_CONSTANT) &&
+	   id->func.offset != -1 &&
+	   INHERIT_FROM_INT(c->u.object->prog, c->subtype)->prog->
+	   constants[id->func.offset].sval.type == T_PROGRAM)
 	{
 	  /* In this one case we allow fake objects to enter the
 	   * mainstream...
@@ -3238,7 +3235,6 @@ PMOD_EXPORT int add_constant(struct pike_string *name,
 	  break;
 	}
       }
-#endif
     }
     
     if(c && !svalues_are_constant(c,1,BIT_MIXED,0))