summaryrefslogtreecommitdiff
path: root/src/bytecode.c
diff options
context:
space:
mode:
authorZach Shaftel <zshaftel@gmail.com>2020-06-18 01:09:31 -0400
committerZach Shaftel <zshaftel@gmail.com>2020-06-18 01:09:31 -0400
commite1aee0ffe8aa51a8963737f8a957cf19eabdb9d7 (patch)
treebe1ff734ed32fa702c4cd88adfabca389e1a1bc6 /src/bytecode.c
parent3d5ac37d36ecae90a634515b78608062fc9729be (diff)
downloademacs-feature/zach-soc-funcall-from-bytecode.tar.gz
Don't call Ffuncall directly from exec_byte_codefeature/zach-soc-funcall-from-bytecode
* src/bytecode.c (exec_byte_code): Do a good chunk of Ffuncall's work in the Bcall ops, so Ffuncall no longer needs to be called. As it stands, it's an ugly clone of the contents of Ffuncall (and some of funcall_lambda). Work in progress. * src/eval.c (record_in_backtrace_with_offset): New function. Like record_in_backtrace but accepts the bytecode offset and stores it in the pertinent backtrace frame. (record_in_backtrace): Don't record the offset. (funcall_lambda): Remove unnecessary SYMBOLP check. * src/lisp.h (funcall_lambda, do_debug_on_call) (record_in_backtrace_with_offset , backtrace_debug_on_exit): Declare.
Diffstat (limited to 'src/bytecode.c')
-rw-r--r--src/bytecode.c91
1 files changed, 86 insertions, 5 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index 29b76f88ef7..fe59cf6600b 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -311,8 +311,6 @@ enum byte_code_op
#define TOP (*top)
-#define UPDATE_OFFSET (backtrace_byte_offset = pc - bytestr_data);
-
DEFUN ("byte-code", Fbyte_code, Sbyte_code, 3, 3, 0,
doc: /* Function used internally in byte-compiled code.
The first argument, BYTESTR, is a string of byte code;
@@ -433,7 +431,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
/* NEXT is invoked at the end of an instruction to go to the
next instruction. It is either a computed goto, or a
plain break. */
-#define NEXT UPDATE_OFFSET goto *(targets[op = FETCH])
+#define NEXT goto *(targets[op = FETCH])
/* FIRST is like NEXT, but is only used at the start of the
interpreter body. In the switch-based interpreter it is the
switch, so the threaded definition must include a semicolon. */
@@ -635,7 +633,90 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
}
}
#endif
- TOP = Ffuncall (op + 1, &TOP);
+ Lisp_Object fun, original_fun;
+ Lisp_Object funcar;
+ Lisp_Object *fun_args;
+ ptrdiff_t numargs = op;
+ Lisp_Object val;
+ ptrdiff_t count_c;
+
+ 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'");
+ }
+
+ fun_args = &TOP + 1;
+
+ count_c = record_in_backtrace_with_offset (TOP, fun_args, numargs, pc - bytestr_data - 1);
+
+ maybe_gc ();
+
+ if (debug_on_next_call)
+ do_debug_on_call (Qlambda, count);
+
+ original_fun = TOP;
+
+ 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 (COMPILEDP (fun))
+ {
+ Lisp_Object syms_left = AREF (fun, COMPILED_ARGLIST);
+ if (FIXNUMP (syms_left))
+ {
+ if (CONSP (AREF (fun, COMPILED_BYTECODE)))
+ Ffetch_bytecode (fun);
+ val = exec_byte_code (AREF (fun, COMPILED_BYTECODE),
+ AREF (fun, COMPILED_CONSTANTS),
+ AREF (fun, COMPILED_STACK_DEPTH),
+ syms_left, numargs, fun_args);
+ }
+ else
+ {
+ /* The rest of funcall_lambda is very bulky */
+ val = funcall_lambda (fun, numargs, fun_args);
+ }
+ }
+ else if (SUBRP (fun))
+ val = funcall_subr (XSUBR (fun), numargs, fun_args);
+#ifdef HAVE_MODULES
+ else if (MODULE_FUNCTIONP (fun))
+ val = funcall_module (fun, numargs, fun_args);
+#endif
+ else
+ {
+ if (NILP (fun))
+ xsignal1 (Qvoid_function, original_fun);
+ if (!CONSP (fun)
+ || (funcar = XCAR (fun), !SYMBOLP(funcar)))
+ xsignal1 (Qinvalid_function, original_fun);
+ if (EQ (funcar, Qlambda)
+ || EQ (funcar, Qclosure))
+ val = funcall_lambda (fun, numargs, fun_args);
+ 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_c))
+ val = call_debugger (list2 (Qexit, val));
+ specpdl_ptr--;
+
+ TOP = val;
NEXT;
}
@@ -1451,7 +1532,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
unbind_to (count, Qnil);
error ("binding stack not balanced (serious byte compiler bug)");
}
- backtrace_byte_offset = -1;
+
Lisp_Object result = TOP;
SAFE_FREE ();
return result;