Function: funcall

funcall is a function defined in eval.c.

Signature

(funcall FUNCTION &rest ARGUMENTS)

Documentation

Call first argument as a function, passing remaining arguments to it.

Return the value that function returns. Thus, (funcall 'cons 'x 'y) returns (x . y).

Probably introduced at or before Emacs version 15.

Aliases

smie--funcall

Source Code

// Defined in /usr/src/emacs/src/eval.c
{
  Lisp_Object fun, original_fun;
  Lisp_Object funcar;
  ptrdiff_t numargs = nargs - 1;
  Lisp_Object val;
  ptrdiff_t count;

  maybe_quit ();

  if (++lisp_eval_depth > max_lisp_eval_depth)
    {
      if (max_lisp_eval_depth < 100)
	max_lisp_eval_depth = 100;
      if (lisp_eval_depth > max_lisp_eval_depth)
	error ("Lisp nesting exceeds `max-lisp-eval-depth'");
    }

  count = record_in_backtrace (args[0], &args[1], nargs - 1);

  maybe_gc ();

  if (debug_on_next_call)
    do_debug_on_call (Qlambda, count);

  original_fun = args[0];

 retry:

  /* Optimize for no indirection.  */
  fun = original_fun;
  if (SYMBOLP (fun) && !NILP (fun)
      && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun)))
    fun = indirect_function (fun);

  if (SUBRP (fun) && !SUBR_NATIVE_COMPILED_DYNP (fun))
    val = funcall_subr (XSUBR (fun), numargs, args + 1);
  else if (COMPILEDP (fun)
	   || SUBR_NATIVE_COMPILED_DYNP (fun)
	   || MODULE_FUNCTIONP (fun))
    val = funcall_lambda (fun, numargs, args + 1);
  else
    {
      if (NILP (fun))
	xsignal1 (Qvoid_function, original_fun);
      if (!CONSP (fun))
	xsignal1 (Qinvalid_function, original_fun);
      funcar = XCAR (fun);
      if (!SYMBOLP (funcar))
	xsignal1 (Qinvalid_function, original_fun);
      if (EQ (funcar, Qlambda)
	  || EQ (funcar, Qclosure))
	val = funcall_lambda (fun, numargs, args + 1);
      else if (EQ (funcar, Qautoload))
	{
	  Fautoload_do_load (fun, original_fun, Qnil);
	  goto retry;
	}
      else
	xsignal1 (Qinvalid_function, original_fun);
    }
  lisp_eval_depth--;
  if (backtrace_debug_on_exit (specpdl + count))
    val = call_debugger (list2 (Qexit, val));
  specpdl_ptr--;
  return val;
}