diff --git a/src/docode.c b/src/docode.c
index 17dae960e0359be78645859e19af894da538bec3..dcb35d3652cd989a93c52b5fb7bc0ba8d1d2f0f9 100644
--- a/src/docode.c
+++ b/src/docode.c
@@ -458,9 +458,21 @@ static int do_lfun_call(int id, node *args)
   struct reference *ref =
     Pike_compiler->new_program->identifier_references + id;
 
-  emit0(F_MARK);
-  PUSH_CLEANUP_FRAME(do_pop_mark, 0);
-  do_docode(args,0);
+  if((Pike_compiler->compiler_frame->current_function_number >= 0) &&
+     ((id == Pike_compiler->compiler_frame->current_function_number) ||
+      ((!ref->inherit_offset) &&
+       (ref->identifier_offset ==
+	Pike_compiler->new_program->
+	identifier_references[Pike_compiler->compiler_frame->
+			      current_function_number].identifier_offset))) &&
+     !(Pike_compiler->new_program->
+       identifiers[ref->identifier_offset].identifier_flags &
+       (IDENTIFIER_VARARGS|IDENTIFIER_SCOPE_USED)) &&
+     !(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPE_USED))
+  {
+    PUSH_CLEANUP_FRAME(do_pop_mark, 0);
+    emit0(F_MARK);
+    do_docode(args,0);
 
   /* Test description:
    *
@@ -474,24 +486,12 @@ static int do_lfun_call(int id, node *args)
    *
    * * Check that the current function doesn't contain scoped functions.
    */
-  if((Pike_compiler->compiler_frame->current_function_number >= 0) &&
-     ((id == Pike_compiler->compiler_frame->current_function_number) ||
-      ((!ref->inherit_offset) &&
-       (ref->identifier_offset ==
-	Pike_compiler->new_program->
-	identifier_references[Pike_compiler->compiler_frame->
-			      current_function_number].identifier_offset))) &&
-     !(Pike_compiler->new_program->
-       identifiers[ref->identifier_offset].identifier_flags &
-       (IDENTIFIER_VARARGS|IDENTIFIER_SCOPE_USED)) &&
-     !(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPE_USED))
-  {
-    if(Pike_compiler->compiler_frame->is_inline || (ref->id_flags & ID_INLINE))
+    if(Pike_compiler->compiler_frame->is_inline || (ref->id_flags & (ID_INLINE|ID_PRIVATE)))
     {
       /* Identifier is declared inline/local
        * or in inlining pass.
        */
-      if ((ref->id_flags & ID_INLINE) &&
+      if ((ref->id_flags & (ID_INLINE|ID_PRIVATE)) &&
 	  (!Pike_compiler->compiler_frame->is_inline)) {
 	/* Explicit local:: reference in first pass.
 	 *
@@ -511,10 +511,30 @@ static int do_lfun_call(int id, node *args)
       Pike_compiler->compiler_frame->recur_label =
 	do_jump(F_POINTER, Pike_compiler->compiler_frame->recur_label);
     }
-  } else {
-    emit1(F_CALL_LFUN, id);
+    POP_AND_DONT_CLEANUP;
+    return 1;
+  }
+ else {
+#ifdef USE_APPLY_N
+   int nargs = count_args(args);
+    if( nargs == -1 )
+    {
+#endif
+     PUSH_CLEANUP_FRAME(do_pop_mark, 0);
+      emit0(F_MARK);
+      do_docode(args,0);
+      emit1(F_CALL_LFUN, id);
+    POP_AND_DONT_CLEANUP;
+    return 1;
+#ifdef USE_APPLY_N
+    }
+    else
+    {
+      do_docode(args,0);
+      emit2(F_CALL_LFUN_N, id, nargs);
+    }
+#endif
   }
-  POP_AND_DONT_CLEANUP;
   return 1;
 }
 
@@ -956,7 +976,7 @@ static int do_docode2(node *n, int flags)
 	   * prototype. */
 	  emit1(F_LFUN, n->u.integer.b);
 	} else if (IDENTIFIER_IS_CONSTANT(id->identifier_flags) &&
-		   (ref->id_flags & ID_INLINE) && !ref->inherit_offset &&
+		   (ref->id_flags & (ID_INLINE|ID_PRIVATE)) && !ref->inherit_offset &&
 		   (id->func.const_info.offset >= 0)) {
 	  /* An inline, local or final constant identifier.
 	   * No need for vtable traversal during runtime.
@@ -1384,14 +1404,22 @@ static int do_docode2(node *n, int flags)
 	      } else if (!level) {
 		f += inh->identifier_level;
 		if (flags & DO_POP) {
+#ifndef USE_APPLY_N
 		  emit0(F_MARK);
+#endif
 		  code_expression(CAR(n), 0, "RHS");
 		} else {
 		  code_expression(CAR(n), 0, "RHS");
+#ifndef USE_APPLY_N
 		  emit0(F_MARK);
+#endif
 		  emit0(F_DUP);
 		}
+#ifdef USE_APPLY_N
+		emit2(F_CALL_LFUN_N, f, 1);
+#else
 		emit1(F_CALL_LFUN, f);
+#endif
 		emit0(F_POP_VALUE);
 		return !(flags & DO_POP);
 	      }
diff --git a/src/interpret_functions.h b/src/interpret_functions.h
index 42fbc6825af83ff7ceb1354d1efadfae337bd206..45d5234b20afc62fa87c33ff1596d06dde43fd98 100644
--- a/src/interpret_functions.h
+++ b/src/interpret_functions.h
@@ -2127,6 +2127,22 @@ OPCODE1_JUMP(F_CALL_LFUN , "call lfun", I_UPDATE_ALL, {
         }
     });
 
+OPCODE2_JUMP(F_CALL_LFUN_N , "call lfun <n>", I_UPDATE_ALL, {
+        LOCAL_VAR(PIKE_OPCODE_T *addr);
+        JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);
+        if((addr = lower_mega_apply(arg2,
+                                    Pike_fp->current_object,
+                                    (arg1+Pike_fp->context->identifier_level) )))
+        {
+            Pike_fp->flags |= PIKE_FRAME_RETURN_INTERNAL;
+            DO_JUMP_TO(addr);
+        }
+        else
+        {
+            DO_JUMP_TO_NEXT;
+        }
+    });
+
 OPCODE1_JUMP(F_CALL_LFUN_AND_POP, "call lfun & pop", I_UPDATE_ALL, {
         LOCAL_VAR(PIKE_OPCODE_T *addr);
         JUMP_SET_TO_PC_AT_NEXT (Pike_fp->return_addr);