diff options
| author | rocky | 2020-04-27 15:14:12 -0400 |
|---|---|---|
| committer | rocky | 2020-04-27 15:14:12 -0400 |
| commit | e5734bef9074fa8b1c80c35aa9bf528e31d966a4 (patch) | |
| tree | 696212727a9f058b434a11c3881e2d52cbc0716f /src/bytecode.c | |
| parent | 08408b13faa911b586ac0c181159ada452a942cc (diff) | |
| download | emacs-e5734bef9074fa8b1c80c35aa9bf528e31d966a4.tar.gz emacs-e5734bef9074fa8b1c80c35aa9bf528e31d966a4.zip | |
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.
Diffstat (limited to 'src/bytecode.c')
| -rw-r--r-- | src/bytecode.c | 8 |
1 files changed, 5 insertions, 3 deletions
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 | |||
| 286 | 286 | ||
| 287 | /* Fetch the next byte from the bytecode stream. */ | 287 | /* Fetch the next byte from the bytecode stream. */ |
| 288 | 288 | ||
| 289 | #define FETCH (*pc++) | 289 | #define FETCH (last_pc = pc, *pc++) |
| 290 | #define FETCH_NORECORD (*pc++) | ||
| 290 | 291 | ||
| 291 | /* Fetch two bytes from the bytecode stream and make a 16-bit number | 292 | /* Fetch two bytes from the bytecode stream and make a 16-bit number |
| 292 | out of them. */ | 293 | out of them. */ |
| 293 | 294 | ||
| 294 | #define FETCH2 (op = FETCH, op + (FETCH << 8)) | 295 | #define FETCH2 (op = FETCH, op + (FETCH_NORECORD << 8)) |
| 295 | 296 | ||
| 296 | /* Push X onto the execution stack. The expression X should not | 297 | /* Push X onto the execution stack. The expression X should not |
| 297 | contain TOP, to avoid competing side effects. */ | 298 | contain TOP, to avoid competing side effects. */ |
| @@ -375,6 +376,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 375 | bytestr_data = ptr_bounds_clip (bytestr_data + item_bytes, bytestr_length); | 376 | bytestr_data = ptr_bounds_clip (bytestr_data + item_bytes, bytestr_length); |
| 376 | memcpy (bytestr_data, SDATA (bytestr), bytestr_length); | 377 | memcpy (bytestr_data, SDATA (bytestr), bytestr_length); |
| 377 | unsigned char const *pc = bytestr_data; | 378 | unsigned char const *pc = bytestr_data; |
| 379 | unsigned char const *last_pc = pc; | ||
| 378 | ptrdiff_t count = SPECPDL_INDEX (); | 380 | ptrdiff_t count = SPECPDL_INDEX (); |
| 379 | 381 | ||
| 380 | if (!NILP (args_template)) | 382 | if (!NILP (args_template)) |
| @@ -535,7 +537,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 535 | if (CONSP (TOP)) | 537 | if (CONSP (TOP)) |
| 536 | TOP = XCDR (TOP); | 538 | TOP = XCDR (TOP); |
| 537 | else if (!NILP (TOP)) | 539 | else if (!NILP (TOP)) |
| 538 | wrong_type_argument (Qlistp, TOP); | 540 | wrong_type_argument_new (Qlistp, TOP, last_pc - bytestr_data); |
| 539 | NEXT; | 541 | NEXT; |
| 540 | } | 542 | } |
| 541 | 543 | ||