[squeak-dev] Re: [Vm-dev] Better VM <-> plugin API

Igor Stasenko siguctua at gmail.com
Sat Nov 22 00:58:52 UTC 2008


2008/11/22 Andreas Raab <andreas.raab at gmx.de>:
> Igor Stasenko wrote:
>>>
>>> Why would it be advantageous to write:
>>>
>>>  static sqInt bitBlitAtom = makeAtom('ioBitBlt');
>>>  registerService(bitBlitAtom, (void*) bitBlt);
>>>  bitBltFn = getService(bitBlitAtom);
>>>
>>> instead of using
>>>
>>>  bitBltFn = ioLoadFunctionFrom("ioBitBlt", "BitBltPlugin");
>>>
>>> Is there any reason for making things even more lengthy than they are
>>> already?
>>
>> First, you are statically associating functionality with specific
>> module ("ioBitBlt" in your example), while using atoms i don't care
>> which module may set it , i care only about specific functionality.
>
> I see. This wasn't clear in your example. What use cases do you have in
> mind? I have only once needed something like this which was during an
> interim period where we supported two BitBlt variants and I wanted to be
> able to use either one from Balloon.
>
> Also, keep in mind that the unstructured namespace you are proposing can
> easily lead to conflicts - one of the reasons why ioLoadFunctionFrom is
> explicit about providing the plugin name is because of all of these
> "primitiveVersion" implementations out there. If you use the flat namespace
> throughout the system you'll have to have a need to disambiguate somehow.
>

The main reason why to use the flat namespace is to allow sharing
state identified by name between modules without exact knowledge where
this state comes from. This, of course implies some contracts about
meaning of symbols , e.g. "bitblt" is a function pointer which takes N
arguments and so on (but hey, you implying the same contract anyways,
when calling  ioLoadFunctionFrom("ioBitBlt", "BitBltPlugin") - just
with one exception, that you have to explicitly specify the source
module where it comes from).
This common namespace can act as meeting point , provided by VM, where
plugins can share data without knowing exact source of it.
As for ambiguous names: we have not much plugins to care about this
problem so far :) In any case - this problem can be addressed in same
way as currently in squeak e.g. define 'abcValue' instead of 'Value'.
Or define 'mymodule.myname' .. any form which you may prefer. But in
latter case, 'mymodule.myname' is nothing more better than
ioLoadFunctionFrom("myname", "mymodule") and simply indicates that you
abusing the global namespace by defining too specific values.

And finally, if we care so much about ambiguousness , one can always
register symbols like 'myModule.version' so others could check if
version is ok.

>> Second, with ioLoadFunctionFrom you can retrieve function, not
>> arbitrary value(s).
>
> ioLoadFunctionFrom retrieves pointers and they can of course point to
> values. For example, the Windows VM exports references to the main window
> ("stWindow") and message hooks. Check out <platform>/vm/sq<Plat>Exports.c
> for examples of platform specific exports.
>
>> Third - you can change atom value dynamically , while
>> ioLoadFunctionFrom doomed to return same value all the time - null if
>> no module found or no such function in module , or function address on
>> success.
>
> Well, of course for changing values, you export functions ;-) Seems like the
> most obvious reason for exporting a function instead of a value. Though
> either way will work.
>
>> Fourth, there are many cases where i wouldn't want to expose functions
>> of my module directly (by exporting them), only indirectly.
>
> Again, I'd be interested in knowing more about your use cases. It is
> certainly doable to do this in the VM but we should be careful about adding
> duplicate functionality.
>

One case, as you pointed out, is when you having multiple versions of
same plugin and want to swap them on the fly.

Smalltalk unloadModule: 'OldBlt'.
Smalltalk loadModule: 'NewBlt'.

Another case, is when you want to overlook some activity by installing
a proxy which will log all calls to some functions.

Smalltalk loadModule: 'SecurityLogger'.
... do some testing/debugging etc ..
Smalltalk unloadModule: 'SecurityLogger'

Third case:

Smalltalk unloadModule: 'UnwantedStuff'.

if there another hideous plugin (or VM) which using
ioLoadFunctionFrom(), it would be very hard to prevent from loading it
again :)

Another one, as variant of first case (OldBlt/NewBlt), suppose you
have module 'fooBar' which using functionality of some 'defaultFoo'
module.
But as well, you have a 'highEndFoo' module, loaded as well which
having same interface as defaultFoo, but slightly different
implementation:

Smalltalk lowerCPUUsage: bool
  bool ifTrue: [ HighEndFoo deactivate ]
  ifFalse: [ HighEndFoo reactivate ]

Note, that here, #deactivate wont lead to unloading a module. It stays
in memory, ready to be used later, but simply rerouting things back to
'defaultFoo'.

I'm not saying that there's much pressing need in such use cases. But
these 3 functions will give us more flexibility , security and
modularity.

To be fair , i'd make all plugins to export only single function, like
setInterpreter(), which then tells VM what things it wants to expose.
Currently, all plugins exposing functions and primitives in static
manner - and have no control at run time what to expose or not.
But that's another story :)

> Cheers,
>  - Andreas

-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list