Hi,
I was looking at ripping some useful stuff from SLIME to Hemlock, and noticed that swank-backend:arglist doesn't seem to work very well with byte-compiled functions in my current version. (Which is CMUCL from CVS per 2004-04-20; SLIME as of earlier today.)
All calls to swank-backend:arglist on a function that has been byte-compiled gives (C:&MORE C::CONTEXT COUNT).
The problem seems to be that kernel:%function-self, called by arglist, in that case, returns a general-ish #<Function "DEFUN INITIALIZE-BYTE-COMPILED-FUNCTION>, which has that kind of arglist.
"Test case":
* (let ((c::*byte-compile* t)) (compile (defun foo (bar &rest zot) (list* bar zot)))) ; Converted FOO. ; Byte Compiling LAMBDA (BAR &REST ZOT): ; Byte Compiling Top-Level Form: FOO NIL NIL * (swank-backend:arglist 'foo) (C:&MORE C::CONTEXT COUNT)
Regards,
'mr
rydis@CD.Chalmers.SE (Martin Rydstr|m) writes:
The problem seems to be that kernel:%function-self, called by arglist, in that case, returns a general-ish #<Function "DEFUN INITIALIZE-BYTE-COMPILED-FUNCTION>, which has that kind of arglist.
That's true. It looks as if CMUCL doesn't record the arglist for byte-compiled functions. I added some code to derive the arglist from the number of argument with some artificial names. The result for your example function is: (arg0 &rest arg1). Byte-compiled functions are primarily a space optimization, so this is probably the best we can do without adding more debug information.
Helmut.
Helmut Eller e9626484@stud3.tuwien.ac.at writes:
rydis@CD.Chalmers.SE (Martin Rydstr|m) writes:
The problem seems to be that kernel:%function-self, called by arglist, in that case, returns a general-ish #<Function "DEFUN INITIALIZE-BYTE-COMPILED-FUNCTION>, which has that kind of arglist.
That's true. It looks as if CMUCL doesn't record the arglist for byte-compiled functions. I added some code to derive the arglist from the number of argument with some artificial names. The result for your example function is: (arg0 &rest arg1). Byte-compiled functions are primarily a space optimization, so this is probably the best we can do without adding more debug information.
Ah. I looked at it a bit after that, and it seemed to me that hooking into the cond in swank-cmucl:arglist in a different way would also work, in some cases, but using the types of the arguments, instead. (Also using stuff that comes with CMUCL, from somewhere in DESCRIBE; I haven't looked very closely at it, but it seemed somewhat workable, at least:
(defimplementation arglist (symbol) (let* ((fun (or (macro-function symbol) (symbol-function symbol))) (arglist (cond ((eval:interpreted-function-p fun) (eval:interpreted-function-arglist fun)) ((pcl::generic-function-p fun) (pcl:generic-function-lambda-list fun)) - ((c::byte-function-or-closure-p fun) - (byte-code-function-arglist fun)) + ((typep fun '(or kernel:byte-function kernel:byte-closure)) + (second (kernel:type-specifier (ext:info function type symbol) ((kernel:%function-arglist (kernel:%function-self fun)) (read-arglist fun)) ;; this should work both for ;; compiled-debug-function and for ;; interpreted-debug-function (t (handler-case (debug-function-arglist (di::function-debug-function fun)) (di:unhandled-condition () :not-available)))))) (check-type arglist (or list (member :not-available))) arglist))
)
Your solution seems a bit more general, though. (And doesn't give the impression of &key args defaulting to T a lot.)
Regards,
'mr