diff --git a/src/interpret.c b/src/interpret.c
index 225e5fa49fafc7d795f0438401d93c7579d4b4d8..e71d1e38fdf03b469537b39822635ebf809f4b4e 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: interpret.c,v 1.192 2001/04/25 21:26:45 hubbe Exp $");
+RCSID("$Id: interpret.c,v 1.193 2001/05/10 22:14:36 hubbe Exp $");
 #include "interpret.h"
 #include "object.h"
 #include "program.h"
@@ -765,6 +765,7 @@ struct light_frame_info
   struct pike_frame *saved_fp;
   struct svalue *expendible;
   struct svalue *locals;
+  unsigned INT16 flags;
 };
 
 static void restore_light_frame_info(struct light_frame_info *info)
@@ -772,6 +773,7 @@ static void restore_light_frame_info(struct light_frame_info *info)
   if (Pike_fp == info->saved_fp) {
     Pike_fp->expendible = info->expendible;
     Pike_fp->locals = info->locals;
+    Pike_fp->flags=info->flags;
   }
 }
 
@@ -863,7 +865,7 @@ static void do_trace_call(INT32 args)
 
 
 #undef INIT_BLOCK
-#define INIT_BLOCK(X) do { X->refs=1; X->malloced_locals=0; X->scope=0; }while(0)
+#define INIT_BLOCK(X) do { X->refs=1; X->flags=0; X->scope=0; }while(0)
 
 #undef EXIT_BLOCK
 #define EXIT_BLOCK(X) do {				\
@@ -871,7 +873,7 @@ static void do_trace_call(INT32 args)
   if(X->context.prog) free_program(X->context.prog);	\
   if(X->context.parent) free_object(X->context.parent);	\
   if(X->scope) free_pike_frame(X->scope);		\
-  if(X->malloced_locals)				\
+  if(X->flags & PIKE_FRAME_MALLOCED_LOCALS)		\
   {							\
     free_svalues(X->locals,X->num_locals,BIT_MIXED);	\
     free((char *)(X->locals));				\
@@ -882,7 +884,7 @@ static void do_trace_call(INT32 args)
     X->context.name=0;					\
     X->scope=0;						\
     X->current_object=0;				\
-    X->malloced_locals=0;				\
+    X->flags=0;						\
     X->expendible=0;					\
     X->locals=0;					\
  )							\
@@ -891,6 +893,569 @@ static void do_trace_call(INT32 args)
 BLOCK_ALLOC(pike_frame,128)
 
 
+int low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2)
+{
+  struct object *o;
+  struct pike_frame *scope=0;
+  ptrdiff_t fun;
+  struct svalue *save_sp=Pike_sp-args;
+  int tailrecurse=-1;
+
+
+#if defined(PIKE_DEBUG) && defined(_REENTRANT)
+  if(d_flag)
+    {
+      THREAD_T self = th_self();
+
+      CHECK_INTERPRETER_LOCK();
+
+      if( Pike_interpreter.thread_id && !th_equal( OBJ2THREAD(Pike_interpreter.thread_id)->id, self) )
+	fatal("Current thread is wrong.\n");
+	
+      if(thread_for_id(th_self()) != Pike_interpreter.thread_id)
+	fatal("thread_for_id() (or Pike_interpreter.thread_id) failed in mega_apply! "
+	      "%p != %p\n", thread_for_id(self), Pike_interpreter.thread_id);
+    }
+#endif
+
+  switch(type)
+  {
+  case APPLY_STACK:
+  apply_stack:
+    if(!args)
+      PIKE_ERROR("`()", "Too few arguments (apply stack).\n", Pike_sp, 0);
+    args--;
+    if(Pike_sp-save_sp-args > (args<<2) + 32)
+    {
+      /* The test above assures these two areas
+       * are not overlapping
+       */
+      assign_svalues(save_sp, Pike_sp-args-1, args+1, BIT_MIXED);
+      pop_n_elems(Pike_sp-save_sp-args-1);
+    }
+    arg1=(void *)(Pike_sp-args-1);
+
+  case APPLY_SVALUE:
+  apply_svalue:
+  {
+    struct svalue *s=(struct svalue *)arg1;
+    switch(s->type)
+    {
+    case T_INT:
+      if (!s->u.integer) {
+	PIKE_ERROR("0", "Attempt to call the NULL-value\n", Pike_sp, args);
+      } else {
+	Pike_error("Attempt to call the value %"PRINTPIKEINT"d\n", 
+		   s->u.integer);
+      }
+
+    case T_STRING:
+      if (s->u.string->len > 20) {
+	Pike_error("Attempt to call the string \"%20s\"...\n", s->u.string->str);
+      } else {
+	Pike_error("Attempt to call the string \"%s\"\n", s->u.string->str);
+      }
+    case T_MAPPING:
+      Pike_error("Attempt to call a mapping\n");
+    default:
+      Pike_error("Call to non-function value type:%s.\n",
+	    get_name_of_type(s->type));
+      
+    case T_FUNCTION:
+      if(s->subtype == FUNCTION_BUILTIN)
+      {
+#ifdef PIKE_DEBUG
+	struct svalue *expected_stack = Pike_sp-args;
+	if(t_flag>1)
+	{
+	  init_buf();
+	  describe_svalue(s,0,0);
+	  do_trace_call(args);
+	}
+#endif
+	(*(s->u.efun->function))(args);
+
+#ifdef PIKE_DEBUG
+	if(Pike_sp != expected_stack + !s->u.efun->may_return_void)
+	{
+	  if(Pike_sp < expected_stack)
+	    fatal("Function popped too many arguments: %s\n",
+		  s->u.efun->name->str);
+	  if(Pike_sp>expected_stack+1)
+	    fatal("Function left droppings on stack: %s\n",
+		  s->u.efun->name->str);
+	  if(Pike_sp == expected_stack && !s->u.efun->may_return_void)
+	    fatal("Non-void function returned without return value on stack: %s %d\n",
+		  s->u.efun->name->str,s->u.efun->may_return_void);
+	  if(Pike_sp==expected_stack+1 && s->u.efun->may_return_void)
+	    fatal("Void function returned with a value on the stack: %s %d\n",
+		  s->u.efun->name->str, s->u.efun->may_return_void);
+	}
+#endif
+
+	break;
+      }else{
+	o=s->u.object;
+	if(o->prog == pike_trampoline_program)
+	{
+	  fun=((struct pike_trampoline *)(o->storage))->func;
+	  scope=((struct pike_trampoline *)(o->storage))->frame;
+	  o=scope->current_object;
+	  goto apply_low_with_scope;
+	}
+	fun=s->subtype;
+	goto apply_low;
+      }
+      break;
+
+    case T_ARRAY:
+#ifdef PIKE_DEBUG
+      if(t_flag>1)
+      {
+	init_buf();
+	describe_svalue(s,0,0);
+	do_trace_call(args);
+      }
+#endif
+      apply_array(s->u.array,args);
+      break;
+
+    case T_PROGRAM:
+#ifdef PIKE_DEBUG
+      if(t_flag>1)
+      {
+	init_buf();
+	describe_svalue(s,0,0);
+	do_trace_call(args);
+      }
+#endif
+      push_object(clone_object(s->u.program,args));
+      break;
+
+    case T_OBJECT:
+      o=s->u.object;
+      if(o->prog == pike_trampoline_program)
+      {
+	fun=((struct pike_trampoline *)(o->storage))->func;
+	scope=((struct pike_trampoline *)(o->storage))->frame;
+	o=scope->current_object;
+	goto apply_low_with_scope;
+      }
+      fun=LFUN_CALL;
+      goto call_lfun;
+    }
+    break;
+  }
+
+  call_lfun:
+#ifdef PIKE_DEBUG
+    if(fun < 0 || fun >= NUM_LFUNS)
+      fatal("Apply lfun on illegal value!\n");
+#endif
+    if(!o->prog)
+      PIKE_ERROR("destructed object", "Apply on destructed object.\n", Pike_sp, args);
+    fun = FIND_LFUN(o->prog, fun);
+    goto apply_low;
+  
+
+  case APPLY_LOW:
+    o = (struct object *)arg1;
+    fun = (ptrdiff_t)arg2;
+
+  apply_low:
+    scope=0;
+  apply_low_with_scope:
+    {
+      struct program *p;
+      struct reference *ref;
+      struct pike_frame *new_frame;
+      struct identifier *function;
+      
+      if(fun<0)
+      {
+	pop_n_elems(Pike_sp-save_sp);
+	push_int(0);
+	return 0;
+      }
+
+      check_stack(256);
+      check_mark_stack(256);
+      check_c_stack(8192);
+
+
+#ifdef PIKE_DEBUG
+      if(d_flag>2) do_debug();
+#endif
+
+      p=o->prog;
+      if(!p)
+	PIKE_ERROR("destructed object->function",
+	      "Cannot call functions in destructed objects.\n", Pike_sp, args);
+
+#ifdef PIKE_SECURITY
+      CHECK_DATA_SECURITY_OR_ERROR(o, SECURITY_BIT_CALL,
+				   ("Function call permission denied.\n"));
+
+      if(!CHECK_DATA_SECURITY(o, SECURITY_BIT_NOT_SETUID))
+	SET_CURRENT_CREDS(o->prot);
+#endif
+
+
+#ifdef PIKE_DEBUG
+      if(fun>=(int)p->num_identifier_references)
+      {
+	fprintf(stderr, "Function index out of range. %ld >= %d\n",
+		DO_NOT_WARN((long)fun),
+		(int)p->num_identifier_references);
+	fprintf(stderr,"########Program is:\n");
+	describe(p);
+	fprintf(stderr,"########Object is:\n");
+	describe(o);
+	fatal("Function index out of range.\n");
+      }
+#endif
+
+      ref = p->identifier_references + fun;
+#ifdef PIKE_DEBUG
+      if(ref->inherit_offset>=p->num_inherits)
+	fatal("Inherit offset out of range in program.\n");
+#endif
+
+      /* init a new evaluation pike_frame */
+      new_frame=alloc_pike_frame();
+#ifdef PROFILING
+#ifdef HAVE_GETHRTIME
+      new_frame->>children_base = Pike_interpreter.accounted_time;
+      new_frame->start_time = gethrtime() - Pike_interpreter.time_base;
+#endif
+#endif
+      debug_malloc_touch(new_frame);
+
+      new_frame->next = Pike_fp;
+      new_frame->current_object = o;
+      new_frame->context = p->inherits[ ref->inherit_offset ];
+
+      function = new_frame->context.prog->identifiers + ref->identifier_offset;
+
+      
+#ifdef PIKE_DEBUG
+	if(t_flag > 9)
+	{
+	  fprintf(stderr,"-- ref: inoff=%d idoff=%d flags=%d\n",
+		  ref->inherit_offset,
+		  ref->identifier_offset,
+		  ref->id_flags);
+
+	  fprintf(stderr,"-- context: prog->id=%d inlev=%d idlev=%d pi=%d po=%d so=%ld name=%s\n",
+		  new_frame->context.prog->id,
+		  new_frame->context.inherit_level,
+		  new_frame->context.identifier_level,
+		  new_frame->context.parent_identifier,
+		  new_frame->context.parent_offset,
+		  DO_NOT_WARN((long)new_frame->context.storage_offset),
+		  new_frame->context.name ? new_frame->context.name->str  : "NULL");
+	  if(t_flag>19)
+	  {
+	    describe(new_frame->context.prog);
+	  }
+	}
+#endif
+
+
+      new_frame->locals = Pike_sp - args;
+      new_frame->expendible = new_frame->locals;
+      new_frame->args = args;
+      new_frame->fun = DO_NOT_WARN((unsigned INT16)fun);
+      new_frame->current_storage = o->storage+new_frame->context.storage_offset;
+      new_frame->pc = 0;
+      new_frame->scope=scope;
+      new_frame->save_sp=save_sp;
+      
+      add_ref(new_frame->current_object);
+      add_ref(new_frame->context.prog);
+      if(new_frame->context.parent) add_ref(new_frame->context.parent);
+      if(new_frame->scope) add_ref(new_frame->scope);
+
+      if(t_flag)
+      {
+	char buf[50];
+
+	init_buf();
+	sprintf(buf, "%lx->",
+		DO_NOT_WARN((long)o));
+	my_strcat(buf);
+	my_strcat(function->name->str);
+	do_trace_call(args);
+      }
+      
+      Pike_fp = new_frame;
+      
+#ifdef PROFILING
+      function->num_calls++;
+#endif
+  
+      if(function->func.offset == -1)
+	generic_error(NULL, Pike_sp, args,
+		      "Calling undefined function.\n");
+      
+#ifdef PROFILING
+#ifdef HAVE_GETHRTIME
+      new_frame->self_time_base=function->total_time;
+#endif
+#endif
+
+      tailrecurse=-1;
+      switch(function->identifier_flags & (IDENTIFIER_FUNCTION | IDENTIFIER_CONSTANT))
+      {
+      case IDENTIFIER_C_FUNCTION:
+	debug_malloc_touch(Pike_fp);
+	Pike_fp->num_args=args;
+	new_frame->num_locals=args;
+	check_threads_etc();
+	(*function->func.c_fun)(args);
+	break;
+	
+      case IDENTIFIER_CONSTANT:
+      {
+	struct svalue *s=&(Pike_fp->context.prog->
+			   constants[function->func.offset].sval);
+	debug_malloc_touch(Pike_fp);
+	if(s->type == T_PROGRAM)
+	{
+	  struct object *tmp;
+	  check_threads_etc();
+	  tmp=parent_clone_object(s->u.program,
+				  o,
+				  fun,
+				  args);
+	  push_object(tmp);
+	  break;
+	}
+	/* Fall through */
+      }
+      
+      case 0:
+      {
+	/* FIXME:
+	 * Use new-style tail-recursion instead
+	 */
+	debug_malloc_touch(Pike_fp);
+	debug_malloc_touch(o);
+	if(Pike_sp-save_sp-args<=0)
+	{
+	  /* Create an extra svalue for tail recursion style call */
+	  Pike_sp++;
+	  MEMMOVE(Pike_sp-args,Pike_sp-args-1,sizeof(struct svalue)*args);
+	  Pike_sp[-args-1].type=T_INT;
+	}else{
+	  free_svalue(Pike_sp-args-1);
+	  Pike_sp[-args-1].type=T_INT;
+	}
+	low_object_index_no_free(Pike_sp-args-1,o,fun);
+	tailrecurse=args+1;
+	break;
+      }
+
+      case IDENTIFIER_PIKE_FUNCTION:
+      {
+	int num_args;
+	int num_locals;
+	unsigned char *pc;
+
+#ifdef PIKE_DEBUG
+	if (Pike_in_gc > GC_PASS_PREPARE && Pike_in_gc < GC_PASS_KILL)
+	  fatal("Pike code called within gc.\n");
+#endif
+
+	debug_malloc_touch(Pike_fp);
+	pc=new_frame->context.prog->program + function->func.offset;
+	
+	num_locals=EXTRACT_UCHAR(pc++);
+	num_args=EXTRACT_UCHAR(pc++);
+
+	if(function->identifier_flags & IDENTIFIER_SCOPE_USED)
+	  new_frame->expendible+=num_locals;
+	
+	/* adjust arguments on stack */
+	if(args < num_args) /* push zeros */
+	{
+	  clear_svalues_undefined(Pike_sp, num_args-args);
+	  Pike_sp += num_args-args;
+	  args += num_args-args;
+	}
+	
+	if(function->identifier_flags & IDENTIFIER_VARARGS)
+	{
+	  f_aggregate(args - num_args); /* make array */
+	  args = num_args+1;
+	}else{
+	  if(args > num_args)
+	  {
+	    /* pop excessive */
+	    pop_n_elems(args - num_args);
+	    args=num_args;
+	  }
+	}
+
+	if(num_locals > args)
+	  clear_svalues(Pike_sp, num_locals - args);
+	Pike_sp += num_locals - args;
+#ifdef PIKE_DEBUG
+	if(num_locals < num_args)
+	  fatal("Wrong number of arguments or locals in function def.\n");
+#endif
+	new_frame->num_locals=num_locals;
+	new_frame->num_args=num_args;
+	new_frame->save_mark_sp=Pike_mark_sp;
+	check_threads_etc();
+	new_frame->pc=pc;
+	return 1;
+      }
+      }
+#ifdef PROFILING
+#ifdef HAVE_GETHRTIME
+  {
+    long long time_passed, time_in_children, self_time;
+    time_in_children=  Pike_interpreter.accounted_time - Pike_fp->children_base;
+    time_passed = gethrtime() - Pike_interpreter.time_base - Pike_fp->start_time;
+    self_time=time_passed - time_in_children;
+    Pike_interpreter.accounted_time+=self_time;
+    function->total_time=Pike_fp->self_time_base + (INT32)(time_passed /1000);
+    function->self_time+=(INT32)( self_time /1000);
+  }
+#endif
+#endif
+
+#if 0
+#ifdef PIKE_DEBUG
+      if(Pike_fp!=new_frame)
+	fatal("Frame stack out of whack!\n");
+#endif
+#endif
+      
+      POP_PIKE_FRAME();
+
+      if(tailrecurse>=0)
+      {
+	args=tailrecurse;
+	goto apply_stack;
+      }
+    }
+  }
+
+  if(save_sp+1 < Pike_sp)
+  {
+    assign_svalue(save_sp,Pike_sp-1);
+    pop_n_elems(Pike_sp-save_sp-1);
+
+    destruct_objects_to_destruct(); /* consider using a flag for immediate destruct instead... */
+  }
+
+  if(save_sp+1 > Pike_sp)
+  {
+    if(type != APPLY_SVALUE)
+      push_int(0);
+  }else{
+    if(t_flag>1) trace_return_value();
+  }
+  return 0;
+}
+
+
+void low_return(void)
+{
+  struct svalue *save_sp=Pike_fp->save_sp;
+#ifdef PIKE_DEBUG
+  if(Pike_mark_sp < Pike_fp->save_mark_sp)
+    fatal("Popped below save_mark_sp!\n");
+  if(Pike_sp<Pike_interpreter.evaluator_stack)
+    fatal("Stack error (also simple).\n");
+#endif
+  Pike_mark_sp=Pike_fp->save_mark_sp;
+
+#ifdef PROFILING
+#ifdef HAVE_GETHRTIME
+  {
+    long long time_passed, time_in_children, self_time;
+    time_in_children=  Pike_interpreter.accounted_time - Pike_fp->children_base;
+    time_passed = gethrtime() - Pike_interpreter.time_base - Pike_fp->start_time;
+    self_time=time_passed - time_in_children;
+    Pike_interpreter.accounted_time+=self_time;
+    function->total_time=Pike_fp->self_time_base + (INT32)(time_passed /1000);
+    function->self_time+=(INT32)( self_time /1000);
+  }
+#endif
+#endif
+
+  POP_PIKE_FRAME();
+
+  if(save_sp+1 < Pike_sp)
+  {
+    assign_svalue(save_sp,Pike_sp-1);
+    pop_n_elems(Pike_sp-save_sp-1);
+
+    destruct_objects_to_destruct(); /* consider using a flag for immediate destruct instead... */
+  }
+
+  if(save_sp+1 > Pike_sp)
+  {
+    push_int(0);
+  }else{
+    if(t_flag>1) trace_return_value();
+  }
+}
+
+void unlink_previous_frame(void)
+{
+  struct pike_frame *current, *prev;
+  struct svalue *target, **smsp;
+  int freespace;
+  current=Pike_interpreter.frame_pointer;
+  prev=Pike_interpreter.frame_pointer=current->next;
+
+  target=prev->save_sp;
+  smsp=prev->save_mark_sp;
+  current->flags=prev->flags;
+  POP_PIKE_FRAME();
+  
+  prev=current->next=Pike_interpreter.frame_pointer;
+  Pike_interpreter.frame_pointer=current;
+
+  current->save_sp=target;
+  current->save_mark_sp=smsp;
+
+#if 1
+  /* Move svalues down */
+  freespace=fp->locals - target;
+  if(freespace > ((Pike_sp - fp->locals)<<2) + 32)
+  {
+    assign_svalues(target,
+		   fp->locals,
+		   Pike_sp - fp->locals,
+		   BIT_MIXED);
+    
+    fp->locals-=freespace;
+    fp->expendible-=freespace;
+  }
+
+  /* Move pointers down */
+  freespace=fp->mark_sp_base - smsp;
+  if(freespace > ((Pike_mark_sp - fp->mark_sp_base)<<2)+32)
+  {
+    MEMMOVE(smsp,
+	    fp->save_mark_sp,
+	    sizeof(struct svalue **)*(Pike_mark_sp - fp->mark_sp_base));
+    fp->mark_sp_base-=freespace;
+  }
+#endif
+}
+
+void gdb_stop_here(void)
+{
+  ;
+}
+
+
 
 #ifdef PIKE_SECURITY
 /* Magic trick */
@@ -900,8 +1465,17 @@ static
 #define mega_apply2 mega_apply
 #endif
 
+void mega_apply2(enum apply_type type, INT32 args, void *arg1, void *arg2)
+{
+  if(low_mega_apply(type, args, arg1, arg2))
+  {
+    eval_instruction(Pike_fp->pc);
+    low_return();
+  }
+}
 
-PMOD_EXPORT void mega_apply2(enum apply_type type, INT32 args, void *arg1, void *arg2)
+#if 0 /* old mega_apply */
+void mega_apply2(enum apply_type type, INT32 args, void *arg1, void *arg2)
 {
   struct object *o;
   struct pike_frame *scope=0;
@@ -909,24 +1483,6 @@ PMOD_EXPORT void mega_apply2(enum apply_type type, INT32 args, void *arg1, void
   ptrdiff_t fun;
   struct svalue *save_sp=Pike_sp-args;
 
-#ifdef PROFILING
-#ifdef HAVE_GETHRTIME
-  long long children_base = Pike_interpreter.accounted_time;
-  long long start_time = gethrtime() - Pike_interpreter.time_base;
-  unsigned INT32 self_time_base;
-#if 0
-#ifdef PIKE_DEBUG
-  if(start_time < 0)
-  {
-    fatal("gethrtime() shrunk\n start_time=%ld\n gethrtime()=%ld\n Pike_interpreter.time_base=%ld\n",
-	  (long)(start_time/100000), 
-	  (long)(gethrtime()/100000), 
-	  (long)(Pike_interpreter.time_base/100000));
-  }
-#endif
-#endif
-#endif
-#endif
 
 #if defined(PIKE_DEBUG) && defined(_REENTRANT)
   if(d_flag)
@@ -1092,6 +1648,13 @@ PMOD_EXPORT void mega_apply2(enum apply_type type, INT32 args, void *arg1, void
     scope=0;
   apply_low_with_scope:
     {
+#ifdef PROFILING
+#ifdef HAVE_GETHRTIME
+      long long children_base = Pike_interpreter.accounted_time;
+      long long start_time = gethrtime() - Pike_interpreter.time_base;
+      unsigned INT32 self_time_base;
+#endif
+#endif
       struct program *p;
       struct reference *ref;
       struct pike_frame *new_frame;
@@ -1323,26 +1886,21 @@ PMOD_EXPORT void mega_apply2(enum apply_type type, INT32 args, void *arg1, void
 #endif
 	new_frame->num_locals=num_locals;
 	new_frame->num_args=num_args;
-
+	new_frame->save_mark_sp=Pike_mark_sp;
+	new_frame->mark_sp_base=Pike_mark_sp;
 	check_threads_etc();
 
-	{
-	  struct svalue **save_mark_sp=Pike_mark_sp;
-	  tailrecurse=eval_instruction(pc);
-	  EVAL_INSTR_RET_CHECK(tailrecurse);
-	  Pike_mark_sp=save_mark_sp;
-#ifdef PIKE_DEBUG
-	  if(Pike_mark_sp < save_mark_sp)
-	    fatal("Popped below save_mark_sp!\n");
-#endif
-	}
+	tailrecurse=eval_instruction(pc);
+	EVAL_INSTR_RET_CHECK(tailrecurse);
+	Pike_mark_sp=new_frame->save_mark_sp;
 #ifdef PIKE_DEBUG
+	if(Pike_mark_sp < save_mark_sp)
+	  fatal("Popped below save_mark_sp!\n");
 	if(Pike_sp<Pike_interpreter.evaluator_stack)
 	  fatal("Stack error (also simple).\n");
 #endif
 	break;
       }
-      
       }
 #ifdef PROFILING
 #ifdef HAVE_GETHRTIME
@@ -1352,41 +1910,12 @@ PMOD_EXPORT void mega_apply2(enum apply_type type, INT32 args, void *arg1, void
 	time_passed = gethrtime() - Pike_interpreter.time_base - start_time;
 	self_time=time_passed - time_in_children;
 	Pike_interpreter.accounted_time+=self_time;
-#if 0
-#ifdef PIKE_DEBUG
-	if(self_time < 0 || children_base <0 || Pike_interpreter.accounted_time <0)
-	  fatal("Time is negative\n  self_time=%ld\n  time_passed=%ld\n  time_in_children=%ld\n  children_base=%ld\n  Pike_interpreter.accounted_time=%ld!\n  Pike_interpreter.time_base=%ld\n  start_time=%ld\n",
-		(long)(self_time/100000),
-		(long)(time_passed/100000),
-		(long)(time_in_children/100000),
-		(long)(children_base/100000),
-		(long)(Pike_interpreter.accounted_time/100000),
-		(long)(Pike_interpreter.time_base/100000),
-		(long)(start_time/100000)
-		);
-#endif
-#endif
 	function->total_time=self_time_base + (INT32)(time_passed /1000);
 	function->self_time+=(INT32)( self_time /1000);
       }
 #endif
 #endif
 
-#if 0
-      if(Pike_sp - new_frame->locals > 1)
-      {
-	pop_n_elems(Pike_sp - new_frame->locals -1);
-      }else if(Pike_sp - new_frame->locals < 1){
-#ifdef PIKE_DEBUG
-	if(Pike_sp - new_frame->locals<0) fatal("Frame underflow.\n");
-#endif
-	Pike_sp->u.integer = 0;
-	Pike_sp->subtype=NUMBER_NUMBER;
-	Pike_sp->type = T_INT;
-	Pike_sp++;
-      }
-#endif
-
 #ifdef PIKE_DEBUG
       if(Pike_fp!=new_frame)
 	fatal("Frame stack out of whack!\n");
@@ -1399,7 +1928,6 @@ PMOD_EXPORT void mega_apply2(enum apply_type type, INT32 args, void *arg1, void
 	args=tailrecurse;
 	goto apply_stack;
       }
-
     }
   }
 
@@ -1419,6 +1947,7 @@ PMOD_EXPORT void mega_apply2(enum apply_type type, INT32 args, void *arg1, void
     if(t_flag>1) trace_return_value();
   }
 }
+#endif /* OLD mega_apply */
 
 #ifdef PIKE_SECURITY
 static void restore_creds(struct object *creds)
@@ -1449,6 +1978,8 @@ static int o_catch(unsigned char *pc)
 {
   JMP_BUF tmp;
   struct svalue *expendible=Pike_fp->expendible;
+  int flags=Pike_fp->flags;
+
   debug_malloc_touch(Pike_fp);
   if(SETJMP(tmp))
   {
@@ -1457,11 +1988,15 @@ static int o_catch(unsigned char *pc)
     Pike_sp++;
     UNSETJMP(tmp);
     Pike_fp->expendible=expendible;
+    Pike_fp->flags=flags;
     return 0;
   }else{
     struct svalue **save_mark_sp=Pike_mark_sp;
     int x;
     Pike_fp->expendible=Pike_fp->locals + Pike_fp->num_locals;
+
+    Pike_fp->flags&=~PIKE_FRAME_RETURN_INTERNAL;
+
     x=eval_instruction(pc);
 #ifdef PIKE_DEBUG
     if(Pike_mark_sp < save_mark_sp)
@@ -1469,6 +2004,7 @@ static int o_catch(unsigned char *pc)
 #endif
     Pike_mark_sp=save_mark_sp;
     Pike_fp->expendible=expendible;
+    Pike_fp->flags=flags;
     if(x>=0) mega_apply(APPLY_STACK, x, 0,0);
     UNSETJMP(tmp);
     return x == -2 ? 2 : 1;
diff --git a/src/interpret.h b/src/interpret.h
index 084b3dcc80fde5d197d59a5820071c1d8ec8b227..1d5a02f0d482bfda604e9c055e8560835863043b 100644
--- a/src/interpret.h
+++ b/src/interpret.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: interpret.h,v 1.80 2001/04/28 19:39:20 mast Exp $
+ * $Id: interpret.h,v 1.81 2001/05/10 22:14:37 hubbe Exp $
  */
 #ifndef INTERPRET_H
 #define INTERPRET_H
@@ -55,17 +55,39 @@ struct pike_frame
   unsigned INT16 fun;
   INT16 num_locals;
   INT16 num_args;
-  INT16 malloced_locals;
+  unsigned INT16 flags;
   struct pike_frame *next;
   struct pike_frame *scope;
   unsigned char *pc;
   struct svalue *locals;
+
+  /*  This is <= locals, and this is where the
+   * return value should go.
+   */
+  struct svalue *save_sp;
+
+  /* This tells us the current level of
+   * svalues on the stack that can be discarded once the
+   * current function is done with them
+   */
   struct svalue *expendible;
+  struct svalue **save_mark_sp;
+  struct svalue **mark_sp_base;
   struct object *current_object;
+
+#if defined(PROFILING) && defined(HAVE_GETHRTIME)
+  long long children_base;
+  long long start_time;
+  INT32 self_time_base;
+#endif
   struct inherit context;
   char *current_storage;
 };
 
+#define PIKE_FRAME_RETURN_INTERNAL 1
+#define PIKE_FRAME_RETURN_POP 2
+#define PIKE_FRAME_MALLOCED_LOCALS 0x8000
+
 struct external_variable_context
 {
   struct object *o;
@@ -196,7 +218,7 @@ PMOD_EXPORT const char *Pike_check_c_stack_errmsg;
 					       Pike_fp->num_locals);		\
       assign_svalues_no_free(s,Pike_fp->locals,Pike_fp->num_locals,BIT_MIXED);	\
       Pike_fp->locals=s;							\
-      Pike_fp->malloced_locals=1;						\
+      Pike_fp->flags|=PIKE_FRAME_MALLOCED_LOCALS;				\
     }else{								\
       Pike_fp->locals=0;							\
     }									\
@@ -265,7 +287,10 @@ BLOCK_ALLOC(pike_frame,128)
 
 PMOD_EXPORT void find_external_context(struct external_variable_context *loc,
 				       int arg2);
-PMOD_EXPORT void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2);
+int low_mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2);
+void low_return(void);
+void unlink_previous_frame(void);
+void mega_apply(enum apply_type type, INT32 args, void *arg1, void *arg2);
 PMOD_EXPORT void f_call_function(INT32 args);
 PMOD_EXPORT void call_handle_error(void);
 PMOD_EXPORT int apply_low_safe_and_stupid(struct object *o, INT32 offset);
diff --git a/src/interpret_functions.h b/src/interpret_functions.h
index 86d472db670a9223040007d82a24c7346db8f325..3656e6490161b6b41ced6d0fe64d654fcd902938 100644
--- a/src/interpret_functions.h
+++ b/src/interpret_functions.h
@@ -1,5 +1,5 @@
 /*
- * $Id: interpret_functions.h,v 1.51 2001/04/25 21:26:46 hubbe Exp $
+ * $Id: interpret_functions.h,v 1.52 2001/05/10 22:14:37 hubbe Exp $
  *
  * Opcode definitions for the interpreter.
  */
@@ -903,7 +903,8 @@ BREAK;
       CASE(F_CATCH);
       switch (o_catch(pc+sizeof(INT32))) {
 	case 1:
-	  return -1; /* There was a return inside the evaluated code */
+          /* There was a return inside the evaluated code */
+	  goto do_dumb_return;
 	case 2:
 	  pc = Pike_fp->pc;
 	  break;
@@ -1052,47 +1053,6 @@ BREAK;
 	break;
       }
 
-      CASE(F_APPLY_AND_RETURN);
-      {
-	INT32 args = DO_NOT_WARN(Pike_sp - *--Pike_mark_sp);
-/*	fprintf(stderr,"%p >= %p\n",Pike_fp->expendible,Pike_sp-args); */
-	if(Pike_fp->expendible >= Pike_sp-args)
-	{
-/*	  fprintf(stderr,"NOT EXPENDIBLE!\n"); */
-	  MEMMOVE(Pike_sp-args+1,Pike_sp-args,args*sizeof(struct svalue));
-	  Pike_sp++;
-	  Pike_sp[-args-1].type=PIKE_T_INT;
-	}
-	/* We sabotage the stack here */
-	assign_svalue(Pike_sp-args-1,&Pike_fp->context.prog->constants[GET_ARG()].sval);
-	return args+1;
-      }
-
-OPCODE1(F_CALL_LFUN_AND_RETURN,"call lfun & return")
-{
-  INT32 args = DO_NOT_WARN(Pike_sp - *--Pike_mark_sp);
-
-  if(Pike_fp->expendible >= Pike_sp-args)
-  {
-    MEMMOVE(Pike_sp-args+1,Pike_sp-args,args*sizeof(struct svalue));
-    Pike_sp++;
-    Pike_sp[-args-1].type=PIKE_T_INT;
-  }else{
-    free_svalue(Pike_sp-args-1);
-  }
-  /* More stack sabotage */
-  Pike_sp[-args-1].u.object=Pike_fp->current_object;
-  Pike_sp[-args-1].subtype=arg1+Pike_fp->context.identifier_level;
-#ifdef PIKE_DEBUG
-  if(t_flag > 9)
-    fprintf(stderr,"-    IDENTIFIER_LEVEL: %d\n",Pike_fp->context.identifier_level);
-#endif
-  Pike_sp[-args-1].type=PIKE_T_FUNCTION;
-  add_ref(Pike_fp->current_object);
-  
-  return args+1;
-}
-BREAK
 
       CASE(F_RETURN_LOCAL);
       instr=GET_ARG();
@@ -1112,7 +1072,7 @@ BREAK
 	push_svalue(Pike_fp->locals+instr);
       }
       print_return_value();
-      return -1;
+      goto do_dumb_return;
 
       CASE(F_RETURN_IF_TRUE);
       if(!IS_ZERO(Pike_sp-1)) goto do_return;
@@ -1138,6 +1098,17 @@ BREAK
       /* fall through */
 
       CASE(F_DUMB_RETURN);
+    do_dumb_return:
+      if(Pike_fp -> flags & PIKE_FRAME_RETURN_INTERNAL)
+      {
+	int f=Pike_fp->flags;
+	gdb_stop_here();
+	low_return();
+        if(f & PIKE_FRAME_RETURN_POP)
+          pop_stack();
+	pc=Pike_fp->pc;
+	break;
+      }
       return -1;
 
 OPCODE0(F_NEGATE, "unary minus")
@@ -1533,71 +1504,178 @@ OPCODE1(F_SSCANF, "sscanf")
 BREAK;
 
 OPCODE1(F_CALL_LFUN,"call lfun")
+#if 0
   apply_low(Pike_fp->current_object,
 	    arg1+Pike_fp->context.identifier_level,
 	    DO_NOT_WARN(Pike_sp - *--Pike_mark_sp));
+#else
+  if(low_mega_apply(APPLY_LOW,
+		    DO_NOT_WARN(Pike_sp - *--Pike_mark_sp),
+		    Pike_fp->current_object,
+		    (void *)(arg1+Pike_fp->context.identifier_level)))
+  {
+    Pike_fp->next->pc=pc;
+    gdb_stop_here();
+    Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL;
+    pc=Pike_fp->pc;
+  }
+#endif
 BREAK;
 
 OPCODE1(F_CALL_LFUN_AND_POP,"call lfun & pop")
+#if 1
   apply_low(Pike_fp->current_object,
-            arg1+Pike_fp->context.identifier_level,
-            DO_NOT_WARN(Pike_sp - *--Pike_mark_sp));
+	    arg1+Pike_fp->context.identifier_level,
+	    DO_NOT_WARN(Pike_sp - *--Pike_mark_sp));
   pop_stack();
+#else
+  if(low_mega_apply(APPLY_LOW,
+		    DO_NOT_WARN(Pike_sp - *--Pike_mark_sp),
+		    Pike_fp->current_object,
+		    (void *)(arg1+Pike_fp->context.identifier_level)))
+  {
+    Pike_fp->next->pc=pc;
+    gdb_stop_here();
+    Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL | PIKE_FRAME_RETURN_POP;
+    pc=Pike_fp->pc;
+  }else{
+    pop_stack();
+  }
+#endif
 BREAK;
 
 OPCODE1(F_MARK_APPLY,"mark apply")
- strict_apply_svalue(&((Pike_fp->context.prog->constants + arg1)->sval), 0);
+  if(low_mega_apply(APPLY_SVALUE,
+		    0,
+		    &((Pike_fp->context.prog->constants + arg1)->sval),0))
+  {
+    Pike_fp->next->pc=pc;
+    gdb_stop_here();
+    Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL;
+    pc=Pike_fp->pc;
+  }
 BREAK;
 
 OPCODE1(F_MARK_APPLY_POP,"mark, apply & pop")
-  strict_apply_svalue(&((Pike_fp->context.prog->constants + arg1)->sval), 0);
-  pop_stack();
+  if(low_mega_apply(APPLY_SVALUE,
+		    0,
+		    &((Pike_fp->context.prog->constants + arg1)->sval),0))
+  {
+    Pike_fp->next->pc=pc;
+    gdb_stop_here();
+    Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL | PIKE_FRAME_RETURN_POP;
+    pc=Pike_fp->pc;
+  }else{
+    pop_stack();
+  }
 BREAK;
 
-    CASE(F_APPLY);
-      strict_apply_svalue(&((Pike_fp->context.prog->constants + GET_ARG())->sval),
-			  DO_NOT_WARN(Pike_sp - *--Pike_mark_sp ));
-      break;
+OPCODE1(F_APPLY,"apply")
+  if(low_mega_apply(APPLY_SVALUE,
+		    DO_NOT_WARN(Pike_sp - *--Pike_mark_sp ),
+		    &((Pike_fp->context.prog->constants + arg1)->sval),0))
+  {
+    Pike_fp->next->pc=pc;
+    gdb_stop_here();
+    Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL;
+    pc=Pike_fp->pc;
+  }
+BREAK;
 
-    CASE(F_APPLY_AND_POP);
-      strict_apply_svalue(&((Pike_fp->context.prog->constants + GET_ARG())->sval),
-			  DO_NOT_WARN(Pike_sp - *--Pike_mark_sp ));
-      pop_stack();
-      break;
 
-OPCODE0(F_CALL_FUNCTION, "call function")
-  mega_apply(APPLY_STACK,
-	     DO_NOT_WARN(Pike_sp - *--Pike_mark_sp),
-	     0,0);
+OPCODE1(F_APPLY_AND_POP,"apply")
+  if(low_mega_apply(APPLY_SVALUE,
+		    DO_NOT_WARN(Pike_sp - *--Pike_mark_sp ),
+		    &((Pike_fp->context.prog->constants + arg1)->sval),0))
+  {
+    Pike_fp->next->pc=pc;
+    gdb_stop_here();
+    Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL | PIKE_FRAME_RETURN_POP;
+    pc=Pike_fp->pc;
+  }else{
+    pop_stack();
+  }
+BREAK;
+
+
+OPCODE0(F_CALL_FUNCTION,"call function")
+  if(low_mega_apply(APPLY_STACK,
+		    DO_NOT_WARN(Pike_sp - *--Pike_mark_sp ),
+		    0,0))
+  {
+    Pike_fp->next->pc=pc;
+    gdb_stop_here();
+    Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL;
+    pc=Pike_fp->pc;
+  }
 BREAK;
 
-OPCODE0(F_CALL_FUNCTION_AND_POP, "call function & pop")
-  mega_apply(APPLY_STACK,
-	     DO_NOT_WARN(Pike_sp - *--Pike_mark_sp),
-	     0,0);
-  pop_stack();
+
+OPCODE0(F_CALL_FUNCTION_AND_POP,"call function & pop")
+  if(low_mega_apply(APPLY_STACK,
+		    DO_NOT_WARN(Pike_sp - *--Pike_mark_sp ),
+		    0,0))
+  {
+    Pike_fp->next->pc=pc;
+    gdb_stop_here();
+    Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL | PIKE_FRAME_RETURN_POP;
+    pc=Pike_fp->pc;
+  }else{
+    pop_stack();
+  }
 BREAK;
 
+OPCODE1(F_APPLY_AND_RETURN,"apply & return")
+{
+  if(low_mega_apply(APPLY_SVALUE,
+		    DO_NOT_WARN(Pike_sp - *--Pike_mark_sp ),
+		    &((Pike_fp->context.prog->constants + arg1)->sval),0))
+  {
+#ifdef PIKE_DEBUG
+    Pike_fp->next->pc=0;
+#endif
+    pc=Pike_fp->pc;
+    unlink_previous_frame();
+  }else{
+    goto do_dumb_return;
+  }
+}
+BREAK;
+
+OPCODE1(F_CALL_LFUN_AND_RETURN,"call lfun & return")
+{
+  if(low_mega_apply(APPLY_LOW,
+		    DO_NOT_WARN(Pike_sp - *--Pike_mark_sp),
+		    Pike_fp->current_object,
+		    (void *)(arg1+Pike_fp->context.identifier_level)))
+  {
+#ifdef PIKE_DEBUG
+    Pike_fp->next->pc=0;
+#endif
+    gdb_stop_here();
+    pc=Pike_fp->pc;
+    unlink_previous_frame();
+  }else{
+    goto do_dumb_return;
+  }
+}
+BREAK
+
 OPCODE0(F_CALL_FUNCTION_AND_RETURN, "call function & return")
 {
-  INT32 args = DO_NOT_WARN(Pike_sp - *--Pike_mark_sp);
-  if(!args)
-    PIKE_ERROR("`()", "Too few arguments (call&return).\n", Pike_sp, 0);
-  switch(Pike_sp[-args].type)
+  if(low_mega_apply(APPLY_STACK,
+		    DO_NOT_WARN(Pike_sp - *--Pike_mark_sp ),
+		    0,0))
   {
-    case PIKE_T_INT:
-      if (!Pike_sp[-args].u.integer) {
-	PIKE_ERROR("`()", "Attempt to call the NULL-value\n",
-		   Pike_sp, args);
-      }
-    case PIKE_T_STRING:
-    case PIKE_T_FLOAT:
-    case PIKE_T_MAPPING:
-    case PIKE_T_MULTISET:
-      PIKE_ERROR("`()", "Attempt to call a non-function value.\n",
-		 Pike_sp, args);
+#ifdef PIKE_DEBUG
+    Pike_fp->next->pc=0;
+#endif
+    gdb_stop_here();
+    pc=Pike_fp->pc;
+    unlink_previous_frame();
+  }else{
+    goto do_dumb_return;
   }
-  return args;
 }
 BREAK;
 
@@ -1621,9 +1699,58 @@ OPCODE1_JUMP(F_COND_RECUR,"recur if not overloaded")
 /* FALL THROUGH */
 
 /* Assume that the number of arguments is correct */
+/* FIXME: Use new recursion stuff */
 OPCODE0_TAILJUMP(F_RECUR,"recur")
 OPCODE0_TAILJUMP(F_RECUR_AND_POP,"recur & pop")
 {
+#if 1
+  int opcode = instr;
+  char *addr;
+  struct pike_frame *new_frame;
+
+  fast_check_threads_etc(6);
+  check_c_stack(8192);
+  check_stack(256);
+
+  new_frame=alloc_pike_frame();
+  new_frame[0]=Pike_fp[0];
+
+  new_frame->refs=1;
+  new_frame->next=Pike_fp;
+
+  new_frame->save_sp = new_frame->expendible = new_frame->locals = *--Pike_mark_sp;
+  new_frame->num_args = new_frame->args = DO_NOT_WARN(Pike_sp - new_frame->locals);
+  new_frame->save_mark_sp = Pike_mark_sp;
+  new_frame->mark_sp_base = Pike_mark_sp;
+
+  addr=pc+GET_JUMP();
+  new_frame->num_locals=EXTRACT_UCHAR(addr-2);
+
+#ifdef PIKE_DEBUG
+  if(new_frame->num_args != EXTRACT_UCHAR(addr-1))
+    fatal("Wrong number of arguments in F_RECUR %d!=%d\n",
+	  new_frame->num_args, EXTRACT_UCHAR(addr-1));
+
+  if(t_flag > 3)
+    fprintf(stderr,"-    Allocating %d extra locals.\n",
+	    new_frame->num_locals - new_frame->num_args);
+#endif
+
+  clear_svalues(Pike_sp, new_frame->num_locals - new_frame->num_args);
+  Pike_sp += new_frame->num_locals - new_frame->args;
+
+  if(new_frame->scope) add_ref(new_frame->scope);
+  add_ref(new_frame->current_object);
+  add_ref(new_frame->context.prog);
+  if(new_frame->context.parent)
+    add_ref(new_frame->context.parent);
+  Pike_fp->pc=pc+sizeof(INT32);
+  Pike_fp=new_frame;
+  pc=addr;
+  new_frame->flags=PIKE_FRAME_RETURN_INTERNAL;
+  if (opcode == F_RECUR_AND_POP-F_OFFSET)
+    new_frame->flags|=PIKE_FRAME_RETURN_POP;
+#else /* 0 */
   int x, opcode = instr;
   INT32 num_locals, args;
   char *addr;
@@ -1638,6 +1765,7 @@ OPCODE0_TAILJUMP(F_RECUR_AND_POP,"recur & pop")
   info.saved_fp = Pike_fp;
   info.expendible = Pike_fp->expendible;
   info.locals = Pike_fp->locals;
+  info.flags=Pike_fp->flags;
   SET_ONERROR(uwp, restore_light_frame_info, &info);
 
   save_sp = Pike_fp->expendible = Pike_fp->locals = *--Pike_mark_sp;
@@ -1652,7 +1780,6 @@ OPCODE0_TAILJUMP(F_RECUR_AND_POP,"recur & pop")
     fatal("Wrong number of arguments in F_RECUR %d!=%d\n",
 	  args, EXTRACT_UCHAR(addr-1));
 #endif
-
   clear_svalues(Pike_sp, num_locals - args);
   Pike_sp += num_locals - args;
 
@@ -1677,6 +1804,7 @@ OPCODE0_TAILJUMP(F_RECUR_AND_POP,"recur & pop")
     fatal("Stack whack in F_RECUR Pike_sp=%p, expected=%p\n",Pike_sp,save_sp+1);
 #endif
   if (opcode == F_RECUR_AND_POP-F_OFFSET) pop_stack();
+#endif /* 0 */
 }
 BREAK
 
diff --git a/src/lex.c b/src/lex.c
index 20c84e7bf3b25ff3931b27511925e5ad3f611cc6..fa302a053b19eb7cae44d90cfc2e49885ff92e2d 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: lex.c,v 1.87 2001/02/24 02:38:32 hubbe Exp $");
+RCSID("$Id: lex.c,v 1.88 2001/05/10 22:14:37 hubbe Exp $");
 #include "language.h"
 #include "array.h"
 #include "lex.h"
@@ -167,13 +167,10 @@ struct keyword instr_names[]=
 { "return if true",	F_RETURN_IF_TRUE, 0 },
 { "label",		F_LABEL,I_HASARG },
 { "align",		F_ALIGN, I_HASARG },
-{ "call",		F_APPLY, I_HASARG },
 { "int index",          F_POS_INT_INDEX, I_HASARG },
 { "-int index",         F_NEG_INT_INDEX, I_HASARG },
-{ "apply and pop",      F_APPLY_AND_POP, I_HASARG },
 { "nop",                F_NOP,0 },
 { "function start",     F_START_FUNCTION,0 },
-{ "apply and return",   F_APPLY_AND_RETURN, I_HASARG },
 { "notreached!",        F_NOTREACHED, 0 },
 };
 
diff --git a/src/opcodes.h b/src/opcodes.h
index 688288aa2e185e5a58be3f215376e974d8264b31..7b28a7b141e1f3a0605d7df9bf10175e5bd5c35d 100644
--- a/src/opcodes.h
+++ b/src/opcodes.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: opcodes.h,v 1.13 2001/02/24 02:38:33 hubbe Exp $
+ * $Id: opcodes.h,v 1.14 2001/05/10 22:14:38 hubbe Exp $
  */
 #ifndef OPCODES_H
 #define OPCODES_H
@@ -46,9 +46,6 @@ enum Pike_opcodes
   F_PREFIX2_CHARX256,
   F_PREFIX2_WORDX256,
   F_PREFIX2_24BITX256,
-  F_APPLY,
-  F_APPLY_AND_POP,
-  F_APPLY_AND_RETURN,
 
   F_BRANCH_AND_POP_WHEN_ZERO,
   F_BRANCH_AND_POP_WHEN_NON_ZERO,
diff --git a/src/program.c b/src/program.c
index 8af1f9481f599cc8e03b58c253ed74111f1503b4..43bda9f2c8edcaf15225f032e6281d4ed4ae0ff3 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.319 2001/05/05 21:00:17 grubba Exp $");
+RCSID("$Id: program.c,v 1.320 2001/05/10 22:14:38 hubbe Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -4238,12 +4238,13 @@ static void exit_trampoline(struct object *o)
 static void gc_check_frame(struct pike_frame *f)
 {
   if(!f) return;
-  if(!debug_gc_check(f,PIKE_T_UNKNOWN,f) && f->malloced_locals)
+  if(!debug_gc_check(f,PIKE_T_UNKNOWN,f) && (f->flags & PIKE_FRAME_MALLOCED_LOCALS))
   {
     if(f->current_object) gc_check(f->current_object);
     if(f->context.prog)   gc_check(f->context.prog);
     if(f->context.parent) gc_check(f->context.parent);
-    if(f->malloced_locals)gc_check_svalues(f->locals,f->num_locals);
+    if(f->flags & PIKE_FRAME_MALLOCED_LOCALS)
+      gc_check_svalues(f->locals,f->num_locals);
     if(f->scope)          gc_check_frame(f->scope);
   }
 }
@@ -4259,7 +4260,8 @@ static void gc_recurse_frame(struct pike_frame *f)
   if(f->current_object) gc_recurse_object(f->current_object);
   if(f->context.prog)   gc_recurse_program(f->context.prog);
   if(f->context.parent) gc_recurse_object(f->context.parent);
-  if(f->malloced_locals)gc_recurse_svalues(f->locals,f->num_locals);
+  if(f->flags & PIKE_FRAME_MALLOCED_LOCALS)
+    gc_recurse_svalues(f->locals,f->num_locals);
   if(f->scope)          gc_recurse_frame(f->scope);
 }
 
diff --git a/src/testsuite.in b/src/testsuite.in
index 3eab469fbc3352f089376583da164c29340ade49..689b3ed694495777cf7f594ac8601b02f535ed24 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,4 +1,4 @@
-test_true([["$Id: testsuite.in,v 1.406 2001/05/07 21:45:07 grubba Exp $"]]);
+test_true([["$Id: testsuite.in,v 1.407 2001/05/10 22:14:38 hubbe Exp $"]]);
 
 cond([[all_constants()->_verify_internals]],
 [[
@@ -842,7 +842,8 @@ test_any([[string gurk="bozo"; string b(int x) { return (x?b(x-1)+gurk:""); }; r
 dnl this should really work...
 dnl test_compile_any([[void foo(int,string,...);]])
 
-test_eval_error([[class X { int create() { create(); } }();]])
+dnl This test doesn't run out of stack anymore, freaky
+dnl test_eval_error([[class X { int create() { create(); } }();]])
 test_compile_error([[ int float; ]])
 test_compile_error([[ int array; ]])
 test_compile_error([[ int function; ]])