}
}
#endif
- TOP = Ffuncall (op + 1, &TOP);
+ 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'");
+ }
+
+ ptrdiff_t numargs = op;
+ Lisp_Object fun = TOP;
+ Lisp_Object *args = &TOP + 1;
+
+ ptrdiff_t count1 = record_in_backtrace (fun, args, numargs);
+ maybe_gc ();
+ if (debug_on_next_call)
+ do_debug_on_call (Qlambda, count1);
+
+ Lisp_Object original_fun = fun;
+ if (SYMBOLP (fun))
+ fun = XSYMBOL (fun)->u.s.function;
+ Lisp_Object template;
+ Lisp_Object bytecode;
+ Lisp_Object val;
+ if (COMPILEDP (fun)
+ // Lexical binding only.
+ && (template = AREF (fun, COMPILED_ARGLIST),
+ FIXNUMP (template))
+ // No autoloads.
+ && (bytecode = AREF (fun, COMPILED_BYTECODE),
+ !CONSP (bytecode)))
+ val = exec_byte_code (bytecode,
+ AREF (fun, COMPILED_CONSTANTS),
+ AREF (fun, COMPILED_STACK_DEPTH),
+ template, numargs, args);
+ else if (SUBRP (fun) && !SUBR_NATIVE_COMPILED_DYNP (fun))
+ val = funcall_subr (XSUBR (fun), numargs, args);
+ else
+ val = funcall_general (original_fun, numargs, args);
+
+ lisp_eval_depth--;
+ if (backtrace_debug_on_exit (specpdl + count1))
+ val = call_debugger (list2 (Qexit, val));
+ specpdl_ptr--;
+
+ TOP = val;
NEXT;
}
return pdl->bt.args;
}
-static bool
-backtrace_debug_on_exit (union specbinding *pdl)
-{
- eassert (pdl->kind == SPECPDL_BACKTRACE);
- return pdl->bt.debug_on_exit;
-}
-
/* Functions to modify slots of backtrace records. */
static void
return unbind_to (count, val);
}
-static void
+void
do_debug_on_call (Lisp_Object code, ptrdiff_t count)
{
debug_on_next_call = 0;
return false;
}
+Lisp_Object
+funcall_general (Lisp_Object fun, ptrdiff_t numargs, Lisp_Object *args)
+{
+ Lisp_Object original_fun = 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))
+ return funcall_subr (XSUBR (fun), numargs, args);
+ else if (COMPILEDP (fun)
+ || SUBR_NATIVE_COMPILED_DYNP (fun)
+ || MODULE_FUNCTIONP (fun))
+ return funcall_lambda (fun, numargs, args);
+ else
+ {
+ if (NILP (fun))
+ xsignal1 (Qvoid_function, original_fun);
+ if (!CONSP (fun))
+ xsignal1 (Qinvalid_function, original_fun);
+ Lisp_Object funcar = XCAR (fun);
+ if (!SYMBOLP (funcar))
+ xsignal1 (Qinvalid_function, original_fun);
+ if (EQ (funcar, Qlambda)
+ || EQ (funcar, Qclosure))
+ return funcall_lambda (fun, numargs, args);
+ else if (EQ (funcar, Qautoload))
+ {
+ Fautoload_do_load (fun, original_fun, Qnil);
+ return funcall_general (original_fun, numargs, args);
+ }
+ else
+ xsignal1 (Qinvalid_function, original_fun);
+ }
+}
+
DEFUN ("funcall", Ffuncall, Sfuncall, 1, MANY, 0,
doc: /* Call first argument as a function, passing remaining arguments to it.
Return the value that function returns.
return specpdl_ptr - specpdl;
}
+INLINE bool
+backtrace_debug_on_exit (union specbinding *pdl)
+{
+ eassert (pdl->kind == SPECPDL_BACKTRACE);
+ return pdl->bt.debug_on_exit;
+}
+
/* This structure helps implement the `catch/throw' and `condition-case/signal'
control structures. A struct handler contains all the information needed to
restore the state of the interpreter after a non-local jump.
extern void get_backtrace (Lisp_Object array);
Lisp_Object backtrace_top_function (void);
extern bool let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol);
+void do_debug_on_call (Lisp_Object code, ptrdiff_t count);
+Lisp_Object funcall_general (Lisp_Object fun,
+ ptrdiff_t numargs, Lisp_Object *args);
/* Defined in unexmacosx.c. */
#if defined DARWIN_OS && defined HAVE_UNEXEC