On Oct 23, 2012 5:48 AM, "Masayuki Takagi" <firstname.lastname@example.org> wrote:
> Thanks, I understand that (%code-debug-info x) will be transformed by
> the compiler.
> Would you mind if I ask some more questions?
> * Where is the transformation defined? In some file in src/compiler/ directory?
Most directly, SYS:SRC;COMPILER;GENERIC;OBJDEF, line 161 in my local copy (possibly out-of-date, but objdef doesn't change that frequently). Just have a look for %code-debug-info in that file.
This is a :REF-TRANS clause of a slot in DEFINE-PRIMITIVE-OBJECT, which is a macro defined in SYS:SRC;COMPILER;GENERIC;VM-MACS. Using :REF-TRANS can cause a DEFKNOWN to be included in the macroexpansion to tell the compiler that there is a function by the given name (in this case %CODE-DEBUG-INFO) with a particular type. It WILL cause a DEF-REFFER form to be included in the macroexpansion.
DEF-REFFER itself is a macro, expanding to a call to %DEF-REFFER, which is defined in SYS:SRC;COMPILER;FUN-INFO-FUNS.
%DEF-REFFER does some magic that tells the compiler to take a particular sort of action (specifically, call IR2-CONVERT-REFFER) when it sees a call to a named function (in this case, %CODE-DEBUG-INFO) at a certain point in compilation ("IR2 Conversion", if you're wondering).
IR2-CONVERT-REFFER is defined in SYS:SRC;COMPILER;GENERIC;VM-IR2TRAN, and basically says to use the VOP called "SLOT" with certain parameters to read the value. SLOT is defined on a per-backend basis, and just reads a given (constant) slot from a given (variable) object and returns it as a result.
That's the long and the short of where (and how) this particular transformation is defined, from top to bottom.
> * Does "that function" mean (defun %code-debug-info (x) ...)?
> * Can I ask you more step-by-step explanation for the reason that a
> recursive definition is needed?
We need to have an "interpreter stub", the recursive definition you mentioned, for every function that the compiler knows how to expand inline so that they are still "first class" functions, which means that we can treat them as any other data value, FUNCALL them, APPLY them, and so on. If we don't have the interpreter stub, we can't do that, and people get confused when they try (this happened a while back with some part of the thread-local symbol binding machinery).
I hope this has helped your understanding in some way.
-- Alastair Bridgewater
> Best Regards,
> 2012/10/23 Stas Boukarev <email@example.com>:
> > Masayuki Takagi <firstname.lastname@example.org> writes:
> >> Hi,
> >>>From function-debug-info function in introspect.lisp, %code-debug-info
> >> function is called.
> >> Looking the definition of it in stubs.lisp:
> >> (macrolet ((def (name &optional (args '(x)))
> >> `(defun ,name ,args (,name ,@args))))
> >> ...
> >> (def %code-debug-info)
> >> ...)
> >> In this definition, (def %code-debug-info) will be expanded as:
> >> (defun %code-debug-info (x)
> >> (%code-debug-info x))
> >> And this is infinitely recursive.
> > It means that it would be transformed by the compiler. So, whenever
> > (%code-debug-info x) is encountered, it's transformed in some way. Why
> > there needs to be such a recursive definition? (%code-debug-info x) will
> > be transformed inside that function and then you will be able to do
> > (funcall #'%code-debug-info x)
> > --
> > With best regards, Stas.
> Everyone hates slow websites. So do we.
> Make your web apps faster with AppDynamics
> Download AppDynamics Lite for free today:
> Sbcl-devel mailing list