/[slime]/slime/swank-backend.lisp
ViewVC logotype

Contents of /slime/swank-backend.lisp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.22.2.2 - (hide annotations)
Sat Jan 31 11:26:02 2004 UTC (10 years, 2 months ago) by heller
Branch: stateless-emacs
Changes since 1.22.2.1: +13 -0 lines
Use signal driven IO for CMUCL and SBCL.  Use one thread per request
for multithreaded lisps.
1 lgorrie 1.1 ;;;; -*- Mode: lisp; indent-tabs-mode: nil; outline-regexp: ";;;;;*" -*-
2     ;;;
3 lgorrie 1.13 ;;; slime-backend.lisp --- SLIME backend interface.
4 lgorrie 1.1 ;;;
5 lgorrie 1.13 ;;; Created by James Bielman in 2003. Released into the public domain.
6 lgorrie 1.1 ;;;
7 lgorrie 1.13 ;;; This file defines the functions that must be implemented
8     ;;; separately for each Lisp. Each is declared as a generic function
9     ;;; for which swank-<implementation>.lisp provides methods.
10 lgorrie 1.1
11     (defpackage :swank
12     (:use :common-lisp)
13 lgorrie 1.3 (:nicknames #:swank-backend)
14 lgorrie 1.9 (:export #:*sldb-pprint-frames*
15     #:apropos-list-for-emacs
16     #:arglist-string
17     #:backtrace
18     #:call-with-I/O-lock
19     #:call-with-conversation-lock
20 heller 1.5 #:compiler-notes-for-emacs
21 lgorrie 1.9 #:completions
22 lgorrie 1.13 #:create-server
23 lgorrie 1.9 #:create-swank-server
24 lgorrie 1.21 #:describe-definition
25 lgorrie 1.9 #:describe-symbol
26 lgorrie 1.21 #:describe-symbol-for-emacs
27 lgorrie 1.9 #:disassemble-symbol
28 heller 1.5 #:documentation-symbol
29 lgorrie 1.9 #:eval-in-frame
30 heller 1.22 #:return-from-frame
31     #:restart-frame
32 lgorrie 1.9 #:eval-string
33     #:eval-string-in-frame
34 heller 1.7 #:find-function-locations
35 heller 1.5 #:frame-catch-tags
36 lgorrie 1.9 #:frame-locals
37     #:frame-source-location-for-emacs
38 heller 1.5 #:frame-source-position
39 lgorrie 1.9 #:getpid
40     #:give-goahead
41     #:give-gohead
42     #:init-inspector
43     #:inspect-in-frame
44     #:inspect-nth-part
45     #:inspector-next
46 heller 1.5 #:inspector-pop
47 lgorrie 1.9 #:interactive-eval
48     #:interactive-eval-region
49 heller 1.5 #:invoke-nth-restart
50 lgorrie 1.10 #:invoke-nth-restart-for-emacs
51 lgorrie 1.9 #:list-all-package-names
52     #:list-callees
53     #:list-callers
54     #:listener-eval
55     #:load-file
56     #:pprint-eval
57 heller 1.5 #:pprint-eval-string-in-frame
58 lgorrie 1.9 #:quit-inspector
59     #:re-evaluate-defvar
60     #:set-default-directory
61     #:set-package
62 heller 1.5 #:sldb-abort
63 lgorrie 1.10 #:sldb-break-with-default-debugger
64 heller 1.5 #:sldb-continue
65 lgorrie 1.9 #:slime-debugger-function
66     #:start-server
67     #:startup-multiprocessing
68     #:startup-multiprocessing-for-emacs
69     #:swank-compile-file
70     #:swank-compile-string
71     #:swank-macroexpand
72     #:swank-macroexpand-1
73     #:swank-macroexpand-all
74 heller 1.5 #:take-input
75 lgorrie 1.9 #:thread-id
76     #:thread-name
77     #:throw-to-toplevel
78     #:toggle-trace-fdefinition
79     #:untrace-all
80     #:wait-goahead
81 lgorrie 1.21 #:warn-unimplemented-interfaces
82 lgorrie 1.9 #:who-binds
83     #:who-calls
84     #:who-macroexpands
85     #:who-references
86     #:who-sets
87 heller 1.5 ))
88 lgorrie 1.1
89     (in-package :swank)
90    
91    
92 lgorrie 1.21 ;;;; Metacode
93    
94     (defparameter *interface-functions* '()
95     "The names of all interface functions.")
96    
97     (defparameter *unimplemented-interfaces* '()
98     "List of interface functions that are not implemented.
99     DEFINTERFACE adds to this list and DEFIMPLEMENTATION removes.")
100    
101     (defmacro definterface (name args documentation &body default-body)
102     "Define an interface function for the backend to implement.
103     A generic function is defined with NAME, ARGS, and DOCUMENTATION.
104    
105     If a DEFAULT-BODY is supplied then NO-APPLICABLE-METHOD is specialized
106     to execute the body if the backend doesn't provide a specific
107     implementation.
108    
109     Backends implement these functions using DEFIMPLEMENTATION."
110     (flet ((gen-default-impl ()
111     (let ((received-args (gensym "ARGS-")))
112     `(defmethod no-applicable-method ((#:method
113     (eql (function ,name)))
114     &rest ,received-args)
115     (destructuring-bind ,args ,received-args
116     ,@default-body)))))
117 lgorrie 1.22.2.1 `(progn (defgeneric ,name ,args (:documentation ,documentation))
118 lgorrie 1.21 (pushnew ',name *interface-functions*)
119     ,(if (null default-body)
120     `(pushnew ',name *unimplemented-interfaces*)
121 lgorrie 1.22.2.1 (gen-default-impl))
122     ',name)))
123 lgorrie 1.21
124     (defmacro defimplementation (name args &body body)
125     ;; Is this a macro no-no -- should it be pushed out of macroexpansion?
126 lgorrie 1.22.2.1 `(progn (defmethod ,name ,args ,@body)
127     (if (member ',name *interface-functions*)
128     (setq *unimplemented-interfaces*
129     (remove ',name *unimplemented-interfaces*))
130     (warn "DEFIMPLEMENTATION of undefined interface (~S)" ',name))
131     ',name))
132 lgorrie 1.21
133     (defun warn-unimplemented-interfaces ()
134     "Warn the user about unimplemented backend features.
135     The portable code calls this function at startup."
136     (warn "These Swank interfaces are unimplemented:~% ~A"
137     (sort (copy-list *unimplemented-interfaces*) #'string<)))
138    
139    
140 lgorrie 1.13 ;;;; TCP server
141    
142 lgorrie 1.21 (definterface create-socket (port)
143     "Create a listening TCP socket on port PORT.")
144 lgorrie 1.13
145 lgorrie 1.21 (definterface local-port (socket)
146     "Return the local port number of SOCKET.")
147 lgorrie 1.1
148 lgorrie 1.21 (definterface close-socket (socket)
149     "Close the socket SOCKET.")
150 lgorrie 1.1
151 lgorrie 1.21 (definterface accept-connection (socket)
152 heller 1.16 "Accept a client connection on the listening socket SOCKET. Return
153 lgorrie 1.21 a stream for the new connection.")
154 heller 1.16
155 lgorrie 1.21 (definterface add-input-handler (socket fn)
156     "Call FN whenever SOCKET is readable.")
157 heller 1.16
158 lgorrie 1.21 (definterface remove-input-handlers (socket)
159     "Remove all input handlers for SOCKET.")
160 heller 1.18
161 lgorrie 1.13 ;;; Base condition for networking errors.
162     (define-condition network-error (error) ())
163    
164 lgorrie 1.21 (definterface emacs-connected ()
165 lgorrie 1.13 "Hook called when the first connection from Emacs is established.
166     Called from the INIT-FN of the socket server that accepts the
167     connection.
168 lgorrie 1.1
169 lgorrie 1.13 This is intended for setting up extra context, e.g. to discover
170 lgorrie 1.21 that the calling thread is the one that interacts with Emacs."
171     nil)
172 lgorrie 1.1
173    
174 heller 1.20 ;;;; Unix signals
175    
176     (defconstant +sigint+ 2)
177    
178     (defgeneric call-without-interrupts (fn)
179     (:documentation "Call FN in a context where interrupts are disabled."))
180    
181     (defgeneric getpid ()
182     (:documentation "Return the (Unix) process ID of this superior Lisp."))
183    
184    
185 lgorrie 1.1 ;;;; Compilation
186 dbarlow 1.8
187 lgorrie 1.21 (definterface call-with-compilation-hooks (func)
188     "Call FUNC with hooks to trigger SLDB on compiler errors.")
189 lgorrie 1.13
190 vsedach 1.14 (defmacro with-compilation-hooks ((&rest ignore) &body body)
191     (declare (ignore ignore))
192 dbarlow 1.8 `(call-with-compilation-hooks (lambda () (progn ,@body))))
193 lgorrie 1.1
194 lgorrie 1.21 (definterface compile-string-for-emacs (string &key buffer position)
195 lgorrie 1.1 "Compile source from STRING. During compilation, compiler
196     conditions must be trapped and resignalled as COMPILER-CONDITIONs.
197    
198     If supplied, BUFFER and POSITION specify the source location in Emacs.
199    
200     Additionally, if POSITION is supplied, it must be added to source
201 lgorrie 1.21 positions reported in compiler conditions.")
202 lgorrie 1.1
203 lgorrie 1.21 (definterface compile-file-for-emacs (filename load-p)
204 lgorrie 1.1 "Compile FILENAME signalling COMPILE-CONDITIONs.
205 lgorrie 1.21 If LOAD-P is true, load the file after compilation.")
206 lgorrie 1.1
207 lgorrie 1.13 (deftype severity () '(member :error :warning :style-warning :note))
208    
209     ;; Base condition type for compiler errors, warnings and notes.
210     (define-condition compiler-condition (condition)
211     ((original-condition
212     ;; The original condition thrown by the compiler if appropriate.
213     ;; May be NIL if a compiler does not report using conditions.
214     :type (or null condition)
215     :initarg :original-condition
216     :accessor original-condition)
217    
218     (severity :type severity
219     :initarg :severity
220     :accessor severity)
221    
222     (message :initarg :message
223     :accessor message)
224    
225     (location :initarg :location
226     :accessor location)))
227    
228 lgorrie 1.17
229 lgorrie 1.13 ;;;; Streams
230    
231 lgorrie 1.21 (definterface make-fn-streams (input-fn output-fn)
232 lgorrie 1.13 "Return character input and output streams backended by functions.
233     When input is needed, INPUT-FN is called with no arguments to
234     return a string.
235     When output is ready, OUTPUT-FN is called with the output as its
236     argument.
237    
238     Output should be forced to OUTPUT-FN before calling INPUT-FN.
239    
240 lgorrie 1.21 The streams are returned as two values.")
241 lgorrie 1.13
242 lgorrie 1.1
243     ;;;; Documentation
244    
245 lgorrie 1.21 (definterface arglist-string (function-name)
246 lgorrie 1.1 "Return the argument for FUNCTION-NAME as a string.
247 lgorrie 1.21 The result should begin and end with parenthesis.")
248 lgorrie 1.1
249 lgorrie 1.21 (definterface macroexpand-all (form)
250 lgorrie 1.1 "Recursively expand all macros in FORM.
251 lgorrie 1.21 Return the resulting form.")
252 lgorrie 1.1
253 lgorrie 1.21 (definterface describe-symbol-for-emacs (symbol)
254 lgorrie 1.1 "Return a property list describing SYMBOL.
255    
256     The property list has an entry for each interesting aspect of the
257     symbol. The recognised keys are:
258    
259     :VARIABLE :FUNCTION :SETF :TYPE :CLASS :MACRO :COMPILER-MACRO
260     :ALIEN-TYPE :ALIEN-STRUCT :ALIEN-UNION :ALIEN-ENUM
261    
262     The value of each property is the corresponding documentation string,
263     or :NOT-DOCUMENTED. It is legal to include keys not listed here.
264    
265     Properties should be included if and only if they are applicable to
266     the symbol. For example, only (and all) fbound symbols should include
267     the :FUNCTION property.
268    
269     Example:
270     \(describe-symbol-for-emacs 'vector)
271     => (:CLASS :NOT-DOCUMENTED
272     :TYPE :NOT-DOCUMENTED
273 lgorrie 1.21 :FUNCTION \"Constructs a simple-vector from the given objects.\")")
274    
275     (definterface describe-definition (name type)
276     "Describe the definition NAME of TYPE.
277     TYPE can be any value returned by DESCRIBE-SYMBOL-FOR-EMACS.
278    
279     Return a documentation string, or NIL if none is available.")
280 lgorrie 1.2
281    
282     ;;;; Debugging
283    
284 lgorrie 1.21 (definterface call-with-debugging-environment (debugger-loop-fn)
285 lgorrie 1.2 "Call DEBUGGER-LOOP-FN in a suitable debugging environment.
286    
287     This function is called recursively at each debug level to invoke the
288     debugger loop. The purpose is to setup any necessary environment for
289     other debugger callbacks that will be called within the debugger loop.
290    
291     For example, this is a reasonable place to compute a backtrace, switch
292 lgorrie 1.21 to safe reader/printer settings, and so on.")
293 lgorrie 1.2
294     (define-condition sldb-condition (condition)
295     ((original-condition
296     :initarg :original-condition
297 heller 1.5 :accessor original-condition))
298 lgorrie 1.2 (:documentation
299     "Wrapper for conditions that should not be debugged.
300    
301     When a condition arises from the internals of the debugger, it is not
302     desirable to debug it -- we'd risk entering an endless loop trying to
303     debug the debugger! Instead, such conditions can be reported to the
304     user without (re)entering the debugger by wrapping them as
305     `sldb-condition's."))
306    
307 lgorrie 1.21 (definterface debugger-info-for-emacs (start end)
308 lgorrie 1.2 "Return debugger state, with stack frames from START to END.
309     The result is a list:
310 heller 1.12 (condition ({restart}*) ({stack-frame}*)
311 lgorrie 1.2 where
312 heller 1.12 condition ::= (description type)
313 lgorrie 1.2 restart ::= (name description)
314     stack-frame ::= (number description)
315    
316 heller 1.12 condition---a pair of strings: message, and type.
317 lgorrie 1.2
318     restart---a pair of strings: restart name, and description.
319    
320     stack-frame---a number from zero (the top), and a printed
321     representation of the frame's call.
322    
323     Below is an example return value. In this case the condition was a
324     division by zero (multi-line description), and only one frame is being
325     fetched (start=0, end=1).
326    
327 heller 1.12 ((\"Arithmetic error DIVISION-BY-ZERO signalled.
328     Operation was KERNEL::DIVISION, operands (1 0).\"
329     \"[Condition of type DIVISION-BY-ZERO]\")
330 lgorrie 1.2 ((\"ABORT\" \"Return to Slime toplevel.\")
331     (\"ABORT\" \"Return to Top-Level.\"))
332 lgorrie 1.21 ((0 \"(KERNEL::INTEGER-/-INTEGER 1 0)\")))")
333 lgorrie 1.1
334 lgorrie 1.21 (definterface backtrace (start end)
335 lgorrie 1.3 "Return a list containing a backtrace of the condition current
336     being debugged. The results are unspecified if this function is
337     called outside the dynamic contour of a debugger hook defined by
338     DEFINE-DEBUGGER-HOOK.
339    
340     START and END are zero-based indices constraining the number of
341     frames returned. Frame zero is defined as the frame which invoked
342     the debugger.
343    
344     The backtrace is returned as a list of tuples of the form
345     \(FRAME-NUMBER FRAME-DESCRIPTION), where FRAME-NUMBER is the
346     index of the frame, defined like START/END, and FRAME-DESCRIPTION
347     is a string containing text to display in the debugger for this
348     frame.
349    
350     An example return value:
351    
352     ((0 \"(HELLO \"world\")\")
353     (1 \"(RUN-EXCITING-LISP-DEMO)\")
354 lgorrie 1.21 (2 \"(SYS::%TOPLEVEL #<SYS::ENVIRONMENT #x394834>)\"))")
355 lgorrie 1.3
356 lgorrie 1.21 (definterface frame-source-location-for-emacs (frame-number)
357     "Return the source location for FRAME-NUMBER.")
358 lgorrie 1.3
359 lgorrie 1.21 (definterface frame-catch-tags (frame-number)
360 lgorrie 1.3 "Return a list of XXX list of what? catch tags for a debugger
361     stack frame. The results are undefined unless this is called
362     within the dynamic contour of a function defined by
363 lgorrie 1.21 DEFINE-DEBUGGER-HOOK.")
364 lgorrie 1.3
365 lgorrie 1.21 (definterface frame-locals (frame-number)
366 lgorrie 1.3 "Return a list of XXX local variable designators define me
367     for a debugger stack frame. The results are undefined unless
368     this is called within the dynamic contour of a function defined
369 lgorrie 1.21 by DEFINE-DEBUGGER-HOOK.")
370 lgorrie 1.3
371 lgorrie 1.21 (definterface eval-in-frame (form frame-number)
372 lgorrie 1.3 "Evaluate a Lisp form in the lexical context of a stack frame
373     in the debugger. The results are undefined unless called in the
374     dynamic contour of a function defined by DEFINE-DEBUGGER-HOOK.
375    
376     FRAME-NUMBER must be a positive integer with 0 indicating the
377     frame which invoked the debugger.
378    
379     The return value is the result of evaulating FORM in the
380 lgorrie 1.21 appropriate context.")
381 heller 1.22
382     (definterface return-from-frame (frame-number form)
383     "Unwind the stack to the frame FRAME-NUMBER and return the value(s)
384     produced by evaluating FORM in the frame context to its caller.
385    
386     Execute any clean-up code from unwind-protect forms above the frame
387     during unwinding.
388    
389     Return a string describing the error if it's not possible to return
390     from the frame.")
391    
392     (definterface restart-frame (frame-number)
393     "Restart execution of the frame FRAME-NUMBER with the same arguments
394     as it was called originally.")
395 lgorrie 1.3
396    
397     ;;;; Queries
398    
399 heller 1.7 #+(or)
400     ;;; This is probably a better interface than find-function-locations.
401 lgorrie 1.21 (definterface find-definitions (name)
402 heller 1.7 "Return a list of (LABEL . LOCATION) pairs for NAME's definitions.
403 lgorrie 1.3
404 heller 1.7 NAME is string denoting a symbol or \"definition specifier\".
405    
406     LABEL is a string describing the definition, e.g., \"foo\" or
407     \"(method foo (string number))\" or \"(variable bar)\".
408    
409     LOCATION is a source location of the form:
410    
411     <location> ::= (:location <buffer> <position>)
412     | (:error <message>)
413    
414     <buffer> ::= (:file <filename>)
415     | (:buffer <buffername>)
416     | (:source-form <string>)
417    
418     <position> ::= (:position <fixnum> [<align>]) ; 1 based
419     | (:function-name <string>)
420 lgorrie 1.21 ")
421 heller 1.7
422 lgorrie 1.21 (definterface find-function-locations (name)
423 heller 1.7 "Return a list (LOCATION LOCATION ...) for NAME's definitions.
424    
425     LOCATION is a source location of the form:
426    
427     <location> ::= (:location <buffer> <position>)
428     | (:error <message>)
429    
430     <buffer> ::= (:file <filename>)
431     | (:buffer <buffername>)
432     | (:source-form <string>)
433    
434     <position> ::= (:position <fixnum> [<align>]) ; 1 based
435 heller 1.12 | (:line <fixnum> [<fixnum>])
436     | (:function-name <string>)
437     | (:source-path <list> <start-position>)
438 lgorrie 1.21 ")
439 lgorrie 1.9
440    
441 heller 1.19 ;;;; Inspector
442    
443     (defgeneric inspected-parts (object)
444     (:documentation
445     "Return a short description and a list of (LABEL . VALUE) pairs."))
446    
447     (defgeneric describe-primitive-type (object)
448     (:documentation
449     "Return a string describing the primitive type of object."))
450    
451    
452 lgorrie 1.9 ;;;; Multiprocessing
453 lgorrie 1.21 ;;;
454     ;;; The default implementations are sufficient for non-multiprocessing
455     ;;; implementations.
456 lgorrie 1.9
457 lgorrie 1.21 (definterface startup-multiprocessing ()
458 lgorrie 1.9 "Initialize multiprocessing, if necessary.
459    
460     This function is called directly through the listener, not in an RPC
461     from Emacs. This is to support interfaces such as CMUCL's
462     MP::STARTUP-IDLE-AND-TOP-LEVEL-LOOPS which does not return like a
463 lgorrie 1.21 normal function."
464     nil)
465 lgorrie 1.9
466 lgorrie 1.21 (definterface spawn (fn &key name)
467     "Create a new thread to call FN.")
468 lgorrie 1.17
469 lgorrie 1.21 (definterface thread-id ()
470 lgorrie 1.9 "Return a value that uniquely identifies the current thread.
471     Thread-IDs allow Emacs to refer to individual threads.
472    
473     When called several times by the same thread, all return values are
474     EQUAL. The value has a READable printed representation that preserves
475     equality. The printed representation must be identical in Emacs Lisp
476     and Common Lisp, and short enough to include in the REPL prompt.
477    
478     For example, a THREAD-ID could be an integer or a short ASCII string.
479    
480 lgorrie 1.21 Systems that do not support multiprocessing return NIL."
481     nil)
482 lgorrie 1.9
483 lgorrie 1.21 (definterface thread-name (thread-id)
484 lgorrie 1.9 "Return the name of the thread identified by THREAD-ID.
485    
486     Thread names are be single-line strings and are meaningful to the
487 lgorrie 1.21 user. They do not have to be unique."
488     (declare (ignore thread-id))
489     "The One True Thread")
490 lgorrie 1.9
491 lgorrie 1.21 (definterface make-lock (&key name)
492 lgorrie 1.17 "Make a lock for thread synchronization.
493 lgorrie 1.21 Only one thread may hold the lock (via CALL-WITH-LOCK-HELD) at a time."
494     :null-lock)
495 lgorrie 1.9
496 lgorrie 1.21 (definterface call-with-lock-held (lock function)
497     "Call FUNCTION with LOCK held, queueing if necessary."
498     (declare (ignore lock))
499     (funcall function))
500 lgorrie 1.9
501 heller 1.22.2.2 (definterface current-thread ()
502     "Return the currently executing thread."
503     0)
504    
505     (definterface interrupt-thread (thread fn)
506     "Cause THREAD to execute FN.")
507    
508     (definterface send (thread object)
509     "Send OBJECT to thread THREAD.")
510    
511     (definterface receive ()
512     "Return the next message from current thread's mailbox.")
513    
514 lgorrie 1.13
515 lgorrie 1.21 ;;;; XREF
516 lgorrie 1.9
517 lgorrie 1.21 (definterface who-calls (function-name)
518     "Return the call sites of FUNCTION-NAME (a string).
519     The results are grouped together by filename:
520     <result> ::= (<file>*)
521     <file> ::= (<filename> . (<reference>*))
522     <reference> ::= (<label> . <location>)
523     <label> ::= string
524     <location> ::= source-location")
525    
526     (definterface who-references (variable-name)
527     "Return the locations where VARIABLE-NAME (a string) is referenced.
528     See WHO-CALLS for a description of the return value.")
529    
530     (definterface who-binds (variable-name)
531     "Return the locations where VARIABLE-NAME (a string) is bound.
532     See WHO-CALLS for a description of the return value.")
533    
534     (definterface who-sets (variable-name)
535     "Return the locations where VARIABLE-NAME (a string) is set.
536     See WHO-CALLS for a description of the return value.")
537    
538     (definterface who-macroexpands (macro-name)
539     "Return the locations where MACRO-NAME (a string) is expanded.
540     See WHO-CALLS for a description of the return value.")
541    
542     (definterface who-specializes (class-name)
543     "Return the locations where CLASS-NAME (a string) is specialized.
544     See WHO-CALLS for a description of the return value.")
545    
546     ;;; Simpler variants.
547    
548     (definterface list-callers (function-name)
549     "List the callers of FUNCTION-NAME.
550     This function is like WHO-CALLS except that it is expected to use
551     lower-level means. Whereas WHO-CALLS is usually implemented with
552     special compiler support, LIST-CALLERS is usually implemented by
553     groveling for constants in function objects throughout the heap.
554    
555     The return value is as for WHO-CALLS.")
556    
557     (definterface list-callees (function-name)
558     "List the functions called by FUNCTION-NAME.
559     See LIST-CALLERS for a description of the return value.")
560 lgorrie 1.1

  ViewVC Help
Powered by ViewVC 1.1.5