From e5734bef9074fa8b1c80c35aa9bf528e31d966a4 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 27 Apr 2020 15:14:12 -0400 Subject: Experiment giving bytecode in traceback... This commit only changes the behavior when `(cdr)` when it is not given a `cons` node, in order to give some quick idea of how adding more traceback information might work. Here's how to see/use. Build this code. Byte-compile this buggy function in `/tmp/foo.el` with (byte-compile-file) ```lisp (defun foo() (setq x 5) (cdr 'b) ) ``` ``` (load-file "/tmp/foo.elc") (foo) ``` You should see: ``` Debugger entered--Lisp error: (wrong-type-argument listp b 3) this is the offset ^ foo() eval((foo) nil) elisp--eval-last-sexp(nil) eval-last-sexp(nil) funcall-interactively(eval-last-sexp nil) call-interactively(eval-last-sexp nil nil) command-execute(eval-last-sexp) ``` Compare against disassembly: ``` byte code for foo: args: nil 0 constant 5 1 varset x 2 constant b 3 cdr ^^^ offset from above 4 return ``` You can try with other offsets such as by removing the `(setq x 5)` and you'll see offset 1 instead. Right now, we just pass to `signal` bytecode offset. More elaborate would be to pass the code object and its offset. Even more elaborate schemes could be imagined. --- src/bytecode.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/bytecode.c') diff --git a/src/bytecode.c b/src/bytecode.c index 3c90544f3f2..8ef84682035 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -286,12 +286,13 @@ enum byte_code_op /* Fetch the next byte from the bytecode stream. */ -#define FETCH (*pc++) +#define FETCH (last_pc = pc, *pc++) +#define FETCH_NORECORD (*pc++) /* Fetch two bytes from the bytecode stream and make a 16-bit number out of them. */ -#define FETCH2 (op = FETCH, op + (FETCH << 8)) +#define FETCH2 (op = FETCH, op + (FETCH_NORECORD << 8)) /* Push X onto the execution stack. The expression X should not contain TOP, to avoid competing side effects. */ @@ -375,6 +376,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, bytestr_data = ptr_bounds_clip (bytestr_data + item_bytes, bytestr_length); memcpy (bytestr_data, SDATA (bytestr), bytestr_length); unsigned char const *pc = bytestr_data; + unsigned char const *last_pc = pc; ptrdiff_t count = SPECPDL_INDEX (); if (!NILP (args_template)) @@ -535,7 +537,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, if (CONSP (TOP)) TOP = XCDR (TOP); else if (!NILP (TOP)) - wrong_type_argument (Qlistp, TOP); + wrong_type_argument_new (Qlistp, TOP, last_pc - bytestr_data); NEXT; } -- cgit v1.2.1