Igor Stasenko wrote:
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).
Well, what's interesting about this is that it becomes much more of an issue if this mechanism is widely used to share function pointers. Right now, 99% of the entry points into plugins are primitives which use the Smalltalk stack and do their own argument checking. There is only a tiny number of functions that is used directly but once you start widening that interface it probably becomes more of an issue. Just something to consider.
One case, as you pointed out, is when you having multiple versions of same plugin and want to swap them on the fly.
Yeah, but that use case is the least convincing to me. We can do pretty much what you describe below (with the minor variation that it has to be an external plugin) and generally, the replacement of plugins has historically not played much of a role. For all practical intents and purposes it seems safer to subclass/switch the primitives in the image instead of replacing the plugin.
Another case, is when you want to overlook some activity by installing a proxy which will log all calls to some functions.
Yes, I could see doing that for debugging/auditing/tracing/profiling purposes. That's definitely a more interesting use case.
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 :)
I don't get this use case. Can you elaborate?
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'.
Again, I find this particular use case not very convincing. In a situation like the above I would prefer having two classes in the image referring to the plugins explicitly and have my code use whichever it finds appropriate - because in this case you can run both the low-end as well as the high-end side-by-side and code won't stomp on each other by one deciding it wants to use the low-end and the other one deciding to use the high-end version.
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.
How so? More flexibility, yes probably. More security? Most definitely not - plugins run at a trusted level already so an evil plugin can do bad things and nothing of what you're describing will prevent that. Modularity I'd say is arguable; but given how badly Smalltalk fares with a flat global namespace I'd say that you'll be hard pressed to explain how using a single flat namespace is an improvement over a per-plugin namespace ;-)
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 :)
Well, actually it's intrinsically related. Part of that story is that plugins use dlopen/dlsym for the lookup from an external plugin. It's because of that that the exports have to be static. So in order to make this dynamic you would have to have a single entry exporting it.
Cheers, - Andreas