[cffi-devel] Optimizing type translators

Luís Oliveira luismbo at gmail.com
Sat Feb 11 17:25:32 UTC 2006


Hello again,

This message was sent friday or so, it took a while to get to the  
mailing-list. Meanwhile, I've implemented this with some changes.  
Read on.


On 2006-feb-10, at 15:48, I wrote:
> Generic Functions:
>
>   (macroexpand-type-to-foreign value-form var body type)
>   (macroexpand-type-from-foreign value type)
>   (macroexpand-to-foreign value-form var body type)
>   (macroexpand-from-foreign value-form type)
>
> A few questions:
>
>   - maybe expand-* instead of macroexpand-*?

I've changed 'macroexpand' to 'expand' as it was getting a bit verbose.


>   - *-to-foreign, as you can see is the equivalent to the previous
>     :to-c-dynamic translation. Would we want to provide the equivalent
>     of :to-c too?

Turns out that we really need to provide this, namely for the  
translation we do for callbacks' return values. So the generic  
functions are now:

   (expand-type-to-foreign-dyn value-form var body type)
   (expand-type-to-foreign value-form type)
   (expand-type-from-foreign value-form type)

   (expand-to-foreign-dyn value-form var body type)
   (expand-to-foreign value-form type)
   (expand-from-foreign value-form type)

If a to-foreign-dyn translation doesn't exist, it'll try to use to- 
foreign. (but not the other way around, of course).


> As I said, I'm trying to keep this simple, so the way this works  
> now is
> that one of these translators completely hijacks the normal
> translators. Namely, it wouldn't follow the typedef chain and apply  
> all
> translators (what would it use the run-time ones? the
> macroexpanion-time ones? Also this would make it a bit harder to
> determine whether a given type has a translator. Right now, what I  
> do is
> call macroexpansion-{to,from}-foreign and one of the default methods
> will return 'no-expansion if no method was specialized on the type.)

Apropos of this, I had a new idea. Providing a way to bail out of the  
expander similar to a compiler macro's "&whole form". The easiest way  
to do this would be with an :around method for the expand-type-* GFs  
binding a special variable to the usual form that calls the  
translators at runtime.

So, a silly optimization for the :string type could be something like  
this...

(defmethod expand-to-foreign-dyn (value var body (type (eql :string)))
   (if (and (constantp value) (stringp (eval value)))
       `(with-foreign-string (,var ,value)
          , at body)
       *runtime-translator-form*))

... while still keeping the flexibility of the runtime translators  
for this type (eg. dispatching based on value).


> One final question. We can guarantee that these are used in defcfun,
> foreign-funcall, defcallback. However, we can't make such  
> guarantees for
> foreign-slot-value (or mem-ref/mem-aref). Would it be a good idea  
> to use
> these translators in the respective compiler macros? I'm inclined  
> to say
> yes.

I'm even more inclined to say yes. :-)

-- 
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/
Equipa Portuguesa do Translation Project
http://www.iro.umontreal.ca/translation/registry.cgi?team=pt




More information about the cffi-devel mailing list