diff options
| author | Helmut Eller | 2013-12-02 09:45:22 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2013-12-02 09:45:22 -0500 |
| commit | f345395c71fb70cc6b42edbef06a26bc6b9b31e0 (patch) | |
| tree | 0ae4bc3c939f87014145b609e39bcb0ed9ad7c9b /src/eval.c | |
| parent | a8a15d9d4529d9cc2ace1cbacf0828cb14c6de94 (diff) | |
| download | emacs-f345395c71fb70cc6b42edbef06a26bc6b9b31e0.tar.gz emacs-f345395c71fb70cc6b42edbef06a26bc6b9b31e0.zip | |
* lisp/emacs-lisp/debug.el (debugger-toggle-locals): New command.
(debugger-mode-map): Bind it.
(debugger--backtrace-base): New function.
(debugger-eval-expression): Use it.
(debugger-frame-number): Skip local vars when present.
(debugger--locals-visible-p, debugger--insert-locals)
(debugger--show-locals, debugger--hide-locals): New functions.
* src/eval.c (Fbacktrace__locals): New function.
(syms_of_eval): Defsubr it.
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/eval.c b/src/eval.c index d3fcec5aef4..81666830f4e 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -3576,6 +3576,73 @@ NFRAMES and BASE specify the activation frame to use, as in `backtrace-frame'. | |||
| 3576 | from the debugger. */ | 3576 | from the debugger. */ |
| 3577 | return unbind_to (count, eval_sub (exp)); | 3577 | return unbind_to (count, eval_sub (exp)); |
| 3578 | } | 3578 | } |
| 3579 | |||
| 3580 | DEFUN ("backtrace--locals", Fbacktrace__locals, Sbacktrace__locals, 1, 2, NULL, | ||
| 3581 | doc: /* Return names and values of local variables of a stack frame. | ||
| 3582 | NFRAMES and BASE specify the activation frame to use, as in `backtrace-frame'. */) | ||
| 3583 | (Lisp_Object nframes, Lisp_Object base) | ||
| 3584 | { | ||
| 3585 | union specbinding *frame = get_backtrace_frame (nframes, base); | ||
| 3586 | union specbinding *prevframe | ||
| 3587 | = get_backtrace_frame (make_number (XFASTINT (nframes) - 1), base); | ||
| 3588 | ptrdiff_t distance = specpdl_ptr - frame; | ||
| 3589 | Lisp_Object result = Qnil; | ||
| 3590 | eassert (distance >= 0); | ||
| 3591 | |||
| 3592 | if (!backtrace_p (prevframe)) | ||
| 3593 | error ("Activation frame not found!"); | ||
| 3594 | if (!backtrace_p (frame)) | ||
| 3595 | error ("Activation frame not found!"); | ||
| 3596 | |||
| 3597 | /* The specpdl entries normally contain the symbol being bound along with its | ||
| 3598 | `old_value', so it can be restored. The new value to which it is bound is | ||
| 3599 | available in one of two places: either in the current value of the | ||
| 3600 | variable (if it hasn't been rebount yet) or in the `old_value' slot of the | ||
| 3601 | next specpdl entry for it. | ||
| 3602 | `backtrace_eval_unrewind' happens to swap the role of `old_value' | ||
| 3603 | and "new value", so we abuse it here, to fetch the new value. | ||
| 3604 | It's ugly (we'd rather not modify global data) and a bit inefficient, | ||
| 3605 | but it does the job for now. */ | ||
| 3606 | backtrace_eval_unrewind (distance); | ||
| 3607 | |||
| 3608 | /* Grab values. */ | ||
| 3609 | { | ||
| 3610 | union specbinding *tmp = prevframe; | ||
| 3611 | for (; tmp > frame; tmp--) | ||
| 3612 | { | ||
| 3613 | switch (tmp->kind) | ||
| 3614 | { | ||
| 3615 | case SPECPDL_LET: | ||
| 3616 | case SPECPDL_LET_DEFAULT: | ||
| 3617 | case SPECPDL_LET_LOCAL: | ||
| 3618 | { | ||
| 3619 | Lisp_Object sym = specpdl_symbol (tmp); | ||
| 3620 | Lisp_Object val = specpdl_old_value (tmp); | ||
| 3621 | if (EQ (sym, Qinternal_interpreter_environment)) | ||
| 3622 | { | ||
| 3623 | Lisp_Object env = val; | ||
| 3624 | for (; CONSP (env); env = XCDR (env)) | ||
| 3625 | { | ||
| 3626 | Lisp_Object binding = XCAR (env); | ||
| 3627 | if (CONSP (binding)) | ||
| 3628 | result = Fcons (Fcons (XCAR (binding), | ||
| 3629 | XCDR (binding)), | ||
| 3630 | result); | ||
| 3631 | } | ||
| 3632 | } | ||
| 3633 | else | ||
| 3634 | result = Fcons (Fcons (sym, val), result); | ||
| 3635 | } | ||
| 3636 | } | ||
| 3637 | } | ||
| 3638 | } | ||
| 3639 | |||
| 3640 | /* Restore values from specpdl to original place. */ | ||
| 3641 | backtrace_eval_unrewind (-distance); | ||
| 3642 | |||
| 3643 | return result; | ||
| 3644 | } | ||
| 3645 | |||
| 3579 | 3646 | ||
| 3580 | void | 3647 | void |
| 3581 | mark_specpdl (void) | 3648 | mark_specpdl (void) |
| @@ -3824,6 +3891,7 @@ alist of active lexical bindings. */); | |||
| 3824 | defsubr (&Sbacktrace); | 3891 | defsubr (&Sbacktrace); |
| 3825 | defsubr (&Sbacktrace_frame); | 3892 | defsubr (&Sbacktrace_frame); |
| 3826 | defsubr (&Sbacktrace_eval); | 3893 | defsubr (&Sbacktrace_eval); |
| 3894 | defsubr (&Sbacktrace__locals); | ||
| 3827 | defsubr (&Sspecial_variable_p); | 3895 | defsubr (&Sspecial_variable_p); |
| 3828 | defsubr (&Sfunctionp); | 3896 | defsubr (&Sfunctionp); |
| 3829 | } | 3897 | } |