FFI syntax (was: Re: [Vm-dev] Re: testing MT and reentrant)

Igor Stasenko siguctua at gmail.com
Fri Mar 25 19:19:51 UTC 2011


On 25 March 2011 19:03, Colin Putney <colin at wiresong.com> wrote:
>
> Looks like a bit of interpretation is necessary here.
>
> Lukas wrote:
>
>>> I don't like it to have methods polluted with meaningless symbols
>>> (that will also show up in senders/implementors).
>
> Igor replied:
>
>> That's exactly why i like it. Now i could use standard tools to figure
>> out which FFI function using
>> some fancy type(s).
>> And that's exactly why i using symbols in primitive names:
>>
>> <primitive: #primName module: #moduleName>
>>
>> So, i can quickly access them. And it is _not_ meaningless. Its handy.
>
> Igor is right, using named primitives make it easy to find out where
> primitives are called, since they show up as senders. However,
> consider Eliot's example from earlier in the thread:
>
> #(int (struct { field : 8; fence : 8; gate: 16; } arg))
>
> Here you get a lot more than the module name and the primitive name.
> You also end up with a bunch of C keywords, identifiers and
> punctuation in the symbol table:
>
> #':'
> #';'
> #'{'
> #'}'

This is really extreme example just to see if it can parse things like above.
Normally you won't find declarations like that. And after all, you can
always do some cleanup :)

> #arg
> #fence
> #field
> #gate
> #int
> #struct
>
> That *is* pretty meaningless. You can get spurious senders of things
> like #field and #gate, but at the same time, you can't easily search
> for FFI calls that include 'struct { field : 8; fence : 8; gate: 16;
> }' in them.
>

You can always rename your arguments to something unique, to ensure
that only your methods using them in signatures.
Then you can make use of browser to help you finding stuff quickly.
Really. It is the same as with usual code. If you name your method
like #value , then it is your fault that you cannot meaningfully (or
quickly)
find all senders which will invoke your method.

So i found this as a weak argument against this syntax, because it
applies to the rest of smalltalk code as well.

>>> I doubt that the symbol hack will make parsing much simpler, because
>>> you still need to analyze the token sequence.
>>>
>> Yes, that's what my class does.  It is reusing smalltalk parser as a tokenizer.
>
> Lukas' point is that this hack doesn't actually buy us much. We get a
> scanner for free, but that's the easy part. The hard part is
> implementing the parser.
>
> If the point of all this is to take advantage of the fact that Igor
> has already done the hard work of implementing a parser for C
> declarations, why not choose a cleaner syntax, write a scanner for it,
> and adapt Igor's parser to fit?
>
> I mean, we already have a quick-and-dirty syntax. It works fine. If
> we're going to replace it, we'll have to maintain backward
> compatibility during the transition period, deprecate the old syntax,
> encourage/help people migrate to the new syntax etc. Do we really want
> to do that for something that still doesn't get us proper C
> declaration pragmas?
>

Note that in NativeBoost i'm not using pragmas for defining a function
signature:

destroyWindow
	"destroy the window"
	<primitive: 'primitiveNativeCall' module: 'NativeBoostPlugin'>

	^ NBFFICallout
		stdcall: #( BOOL DestroyWindow ( HWND self ))
		module: #user32
		options: #( + optMayCallback )  " calls windowproc"

So, yes, i could put everything into string literal.. no big deal:

stdcall: ' BOOL DestroyWindow ( HWND self ) '
instead of:
stdcall: #( BOOL DestroyWindow ( HWND self ))

but then i cannot browse all senders of BOOL, DestroyWindow,HWND anymore :(


> Colin
>


-- 
Best regards,
Igor Stasenko AKA sig.


More information about the Vm-dev mailing list