[slime-devel] Re: Would like to add 'changed definitions' functionality

Helmut Eller e9626484 at stud3.tuwien.ac.at
Thu Jun 17 15:28:13 UTC 2004


Glenn Ehrlich <glenn.ehrlich.lists at cox.net> writes:

> Helmut,
>
> I've emailed you separately, but thanks for the comments.  If no one
> else thinks it would be useful, I can easily be persuaded to work on
> something else.  I've got a rough design floating around in my head
> that would use the existing definition support in swank plus some
> additional functionality from imenu.  I looked at the way Franz eli
> does it and it's sort of similar to the way I was thinking of doing
> it.  I don't think it would be too difficult to implement, but I would
> like to spend my time working on something that others would find
> useful.  As I said to Helmut, I'm more in the mindset of "I'd like to
> contribute in ways folks will find useful", rather than "I've got to
> get feature X into slime".

Just in case people run out of ideas, here are some from my TODO/half
baked ideas list:

  
- rename throw-to-toplevel as restart-toplevel

- unify compiler warnings buffer with xref buffer

- think about :lisp filename in compilation notes

- stepper

- better handling of segfaulted cmucl

- debugger-limit

- implement inspector history and use a "path" instead of a stack.

- better describe-function.  With clickable text that brings you to
  the source of the function.

- better source location handling in sbcl, probably with
  sb-introspect.

- support for redirecting the output of C-x C-e to the current buffer;
  like Emacs built-in C-x C-e.

- support polling of the redirected input stream.

- multiple listners (low priority).  This should be relatively easy
  for multi-threaded Lisps but is a bit strange for CLISP and CMUCL.

- better scrolling.  Ideally similar to term-mode.

- implement sldb-show-source for Allegro; at least a bit.

- OpenMCL: Make M-. work for functions compiled with C-c C-c.
  Probably involves setting *loading-file-source-file* in
  swank-compile-string.  Might be similar to the kludge used in
  swank-lispworks.lisp.

- CLISP: produce better backtraces; requires C hacking.  Improve
  source location recording/defintion finding.  Perhaps the easiest
  to fall back to TAGS.

- LispWorks: idea to improve sldb-show-source: first READ the toplevel
  form for the frame then find the location of a form that looks like
  a call to the callee (the next-frame).  LispWorks graphical debugger
  is somehow able to highliht (/ 1 0) in the following form: 

   (defun foo () 
     (print (/ 1 0)))

  I wonder how they do it.

- implement restart-frame and return-from-frame in CMUCL.  The major
  problem is that CMUCL uses 4 stacks to represent the dynamic
  environment -- Control Stack, Binding Stack, Eval Stack and Alien
  Stack (Non x86 have a Number Stack but no Alien stack.) -- but it
  isn't easy to reconstruct all stack pointers by the debugger.  SBCL
  implements return-from-frame with some relatively inefficient
  mechanism: every function is rewritten as a (defun ... (...) (catch
  (make-symbol "SB-CATCH-TAG") ...)) and the debugger searches the tag
  (with string comparision) in that frame and throws to it.  This
  approach isn't particularly appealing, because it is expensive to
  allocate a symbol for each call, it's expensive to save the dynamic
  environment on each call, it infers with tail call optimization, is
  not "pay as you go".  

  Relatively simple way to avoid allocating a symbol for each catch,
  is to use a special unwind function.  All we need to do is to set
  the current-catch-block (or whatever) to the target catcher.
  Throwing will then execute all unwind blocks and skip all catchers
  event if they have the same catch tag.

  I think it should be possible to reconstruct the dynamic environment
  if we safe the spill locations for stack pointers in the debugging
  info.  Stack pointers are saved on the control stack in the
  following situations: catch, unwind-protect, all sort of NLXs, alien
  allocations, evaluations, and dynamic lets.

  It seems that Allegro saves the dynamic binding stack pointer at
  function entry if the function binds a dynamic variable. This would
  be quite a robust way to reconstruct the dsp.  I don't know all the
  details needed for an actual implementation, but I assume it would
  similar to the handling of nfp on the RISC ports.

  Another problem are the restart entry points and the locations for
  the arguments for the to be restarted function.  This might be very
  difficult.

- test the scalability of the xref fasl dumping. saving callers _and_
  callees seems like a redundancy (especially since the compiler only
  sees callees).  think about xref and compile-defun and
  compile-from-stream.  Also think about the usefulness of precise
  callsite recording, probably only feasible for small projects.
  Should xref info be attached to function objects?  A lot of the
  stuff is already there in particular callees (and callers can be
  reconstructed by memory/symbol-groveling).  We could add a bitvector
  indicating which fdefn or symbol in the constant pool is a callee, a
  referenced/set/used variable ...  How useful is this xref stuff
  anyway? Isn't grep good enough?  The interesting/hard cases like
  indirect calls to function objects stored in tables aren't covered
  by xref.  Should we record where a function escapes? Again,
  funcalling symbols will not be covered.

- Zmacs and ELI have a concept of "changed definitions".  Sounds
  difficult to implement in the presence of toplevel macros and
  eval-when. perhaps we could deal with toplevel forms insteaod of
  definitions? or some shortcut like forms starting in the first
  column with "(def".  Worth to bother?
  http://bitsavers.org/pdf/ti/explorer/2243192-0001A_Zmacs_Jun87.pdf

- enhance the disassembler so that we can find the code location of
  references to fdefn objects and use that as approximation for the
  call-site. [difficult]

> The way it works in LispWorks is exactly the same way it works on the
> Lisp Machine, same keystroke bindings, too, I think.  Basically, meta
> shift e evaluates all changed definitions in the current buffer (yes,
> I know that emacs doesn't recognize the shift modifier, but zmacs
> does) and meta shift c compiles the changed defintions in the current
> buffer.  There's similar commands for doing the same for all buffers,
> but they aren't bound to any keystrokes.  The definition of changed is
> roughly "edited since last sent to Lisp".

And what's the definition of "definition"?


Helmut.




More information about the slime-devel mailing list