[Openmcl-devel] GF invocation protocol
Gary Byers
gb at clozure.com
Wed Sep 12 03:25:29 PDT 2007
Sorry; I missed this message, and sent a reply to your earlier message.
A couple of points:
On Wed, 12 Sep 2007, Vyacheslav Akhmechet wrote:
> I can obtain the actual function from a generic function object via:
> (ccl::uvref #'gf ccl::gf.dcode)
On the PPC, FUNCTIONs (including GFs) are vector-like objects, and
you can use CCL::UVREF to access their components.
On the X86, things are a little different. CCL::UVREF will complain
if it's passed a first argument of type FUNCTION; CCL::%GF-DCODE
does know how to find the dcode object of a generic function, regardless
of how functions are represented.
>
> The function it returns requires an extra argument - the dispatch
> table. I can get that via:
> (ccl::%gf-dispatch-table #'gf)
Yes.
>
> With this information I can set-funcallable-instance on the generic
> function to my own function, modify the arguments as I wish (which was
> my intent) and pass them to OpenMCL standard dispatch mechanism:
>
> (defmethod test (a b) (+ a b))
>
> (let ((dfun (ccl::uvref #'test ccl::gf.dcode))
> (dt (ccl::%gf-dispatch-table #'test)))
> (set-funcallable-instance-function #'test
> (lambda (a1 a2)
> (funcall
> dfun dt (1+ a1) (1+ a2)))))
>
> (test 1 1) => 4
>
Different dcode functions expect to receive the GF's arguments (and
the dispatch table) in different ways (depending on the GF's lambda-list
and on which arguments have specializers that refer to something other
than (FIND-CLASS T).)
For instance:
(defmethod three-args (a b c) (+ a b c))
(ccl::%gf-dcode #'three-args) => #<Compiled-function %%1ST-ARG-DCODE #x30004016E75F>)
(ccl::arglist #'ccl::%%1st-arg-dcode) => (DT ARGS)
The second argument - ARGS - represents all of the incoming arguments to
the GF (possibly as a list, or possibly as a fixnum which encodes a
stack address where the arguments were saved.)
(defmethod test-3-args (a b c) (+ a b c))
(let ((dfun (ccl::%gf-dcode #'test-3-args))
(dt (ccl::%gf-dispatch-table #'test-3-args)))
(set-funcallable-instance-function #'test-3-args
(lambda (a1 a2 a3)
(funcall
dfun dt (list
(1+ a1) (1+ a2) (1+ a3))))))
(test-3-args 1 1 1) => 6
If you wanted to pursue this, it might be helpful to know that
ccl::%%one-arg-dcode expects the arguments (DT ARG)
ccl::%%1st-two-arg-dcode expects the arguments (DT ARG0 ARG1)
All other dcode functions expect the arguments (DT ARGS)
I think that this all qualifies as "low-level gunk".
More information about the Openmcl-devel
mailing list