[Openmcl-devel] "internal" functions and xref

Takehiko Abe keke at gol.com
Tue Nov 18 06:21:39 PST 2008


Gary Byers wrote:

 > [...]
 >
 > In 1.2 or later, an otherwise unnamed function that's defined within
 > a named function is given a name of the form (:INTERNAL
 > <outer-function-name>):

Aha. Now I know where I got confused. I missed that an anonymous
function is hidden inside print-unreadable-object :

(defun write-an-istruct (istruct stream level)
   (let* ((type (istruct-cell-name (uvref istruct 0)))
          (wrapper-p  (eq type 'class-wrapper)))
     (print-unreadable-object (istruct stream :identity t)
       (write-internal stream type (%i- level 1) nil)
       (when wrapper-p
         (pp-space stream)
         (print-object (class-name (%wrapper-class istruct)) stream)))))

(defmethod print-object ((class class) stream)
   (print-unreadable-object (class stream)
     (print-object (class-name (class-of class)) stream)
     (pp-space stream)
     (print-object (class-name class) stream)))

That's why (ccl::callers 'print-object) returns

   (:INTERNAL CCL::WRITE-AN-ISTRUCT)
   (:INTERNAL (PRINT-OBJECT (CLASS T)))

for them.

 > [...]
 >
 > I don't know how (if at all) any of this affects XREF.  As I recall,
 > the XREF utility hooks itself into the compiler frontend and notes
 > references (function calls and other things) from the function being
 > compiled to other things.

who-calls (both ccl's and slime's) uses ccl:get-relation which
in turn calls ccl::callers and ccl::make-xref-entry:


(dolist (caller (callers name2))
   (pushnew (make-xref-entry caller relation)
            matches
            :test #'xref-entry-equal))


ccl::make-xref-entry has got a comment:

;; MAKE-XREF-ENTRY -- internal
;;
;; Takes a simple input form and makes a XREF-ENTRY from it. The input
;; is assumed to be a function, macro or variable when a simple symbol
;; is passed, or a method when it is a cons. Since this needs to also
;; handle the ouput from CCL::CALLERS, there is additional hackery
;; trying to do the right thing.

But since ccl::make-xref-entry does not handle the (:internal ...)
list, I believe it needs more hackery.

? (ccl::make-xref-entry '(:INTERNAL CCL::WRITE-AN-ISTRUCT)
                         :direct-calls)
#<XREF-ENTRY INTERNAL METHOD (WRITE-AN-ISTRUCT)>
? (ccl::make-xref-entry '(:INTERNAL (PRINT-OBJECT (CLASS T)))
                         :direct-calls)
#<XREF-ENTRY NIL NIL>

? (who-calls 'print-object)

  PRINT-OBJECT is directly called by:
      NIL
      PRINT-OBJECT (#<BUILT-IN-CLASS COMPLEX> #<BUILT-IN-CLASS T>)
      WRITE-A-FROB
      REPORT-CONDITION (#<STANDARD-CLASS CONDITION> #<BUILT-IN-CLASS T>)
      PRINT-OBJECT (#<STANDARD-CLASS UNBOUND-MARKER> #<BUILT-IN-CLASS T>)
      INTERNAL (WRITE-AN-ISTRUCT)

It so happens that, for who-calls /ccl::callers, returning an xref for
the outer-function instead is fine or even desirable.

regards,
T.



More information about the Openmcl-devel mailing list