<div dir="auto"><div>Andres,<div dir="auto"><br></div><div dir="auto">Agreed... I was mainly trying to point out that Alien isn't the uniformly superior approach that it often seems to be portrayed as nor are plugins obsolete (which seems to be the case Eliot is making). It would be nice to have a single approach that did it all but we're not there yet.</div><div dir="auto"><br></div><div dir="auto">Thanks,</div><div dir="auto">Phil</div><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, May 27, 2020, 3:29 PM Andres Valloud via Cuis-dev <<a href="mailto:cuis-dev@lists.cuis.st">cuis-dev@lists.cuis.st</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Ok, just remember there are a multitude of situations where FFI is the <br>
wrong approach (like, literally, it's undefined behavior).  FFI alone is <br>
not enough.<br>
<br>
On 5/27/20 12:10, Phil B via Cuis-dev wrote:<br>
> Related to the discussion is this rather dated thread: <br>
> <a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/2010-March/147241.html" rel="noreferrer noreferrer" target="_blank">http://lists.squeakfoundation.org/pipermail/squeak-dev/2010-March/147241.html</a> I <br>
> haven't yet seen much in the way of objective analysis since then to <br>
> render it obsolete. (if it exists and I've missed it, please point it out!)<br>
> <br>
> Conventional wisdom (prior to Cog & Spur VMs... that likely changes the <br>
> equation at least a bit along with whatever (de-)evolution has occurred <br>
> in the respective approaches over the years) used to be that Plugin > <br>
> FFI > Alien from a raw performance standpoint.  But Alien had <br>
> callbacks... and when you need them, you need them.  Also, IIRC Alien <br>
> utilizes introspection and therefore wouldn't run without a sources file <br>
> which is an issue for some deployment scenarios.<br>
> <br>
> As you mention the (at least theoretical) advantage of abstracting <br>
> functionality by pushing it to the VM shouldn't be dismissed.  I've <br>
> experienced both the good and bad side of this with things like the <br>
> sound and ssl plugins.  When they work, it's great: you don't care what <br>
> platform you're on: it just works.  With an FFI solution, you're dealing <br>
> with different libraries/locations and possibly entirely different APIs <br>
> entirely on different platforms and it's usually up to you to sort it <br>
> out.  However, when there is a plugin problem (i.e. mismatched library <br>
> versions etc), you have all of the issues of dealing with plugin and FFI <br>
> code.  So a lot of this potential advantage comes down to how well <br>
> plugins are maintained.  If they aren't, you may be better off with FFI <br>
> since sometimes fixing a broken plugin can be more work than just <br>
> rolling your own solution.<br>
> <br>
> Thanks,<br>
> Phil<br>
> <br>
> On Wed, May 27, 2020 at 1:49 PM Juan Vuletich via Cuis-dev <br>
> <<a href="mailto:cuis-dev@lists.cuis.st" target="_blank" rel="noreferrer">cuis-dev@lists.cuis.st</a> <mailto:<a href="mailto:cuis-dev@lists.cuis.st" target="_blank" rel="noreferrer">cuis-dev@lists.cuis.st</a>>> wrote:<br>
> <br>
>     Hi Philip,<br>
> <br>
>     On 5/27/2020 2:17 AM, Philip Bernhart via Cuis-dev wrote:<br>
>      > Hi,<br>
>      ><br>
>      > I recently asked on the squeak vm-beginners list about the stability<br>
>      > of the external plugin interface. The general vibe from Eliot was:<br>
>      >    don't! Use FFI instead!<br>
>      ><br>
>      > See:<br>
>      ><br>
>     <a href="http://forum.world.st/Stability-of-the-external-plugin-interface-td5117112.html" rel="noreferrer noreferrer" target="_blank">http://forum.world.st/Stability-of-the-external-plugin-interface-td5117112.html</a><br>
> <br>
>     Ok. Specifically on this. I've used buth alternatives over the years. I<br>
>     developed or fixed bugs in JPEGReadWriterPlugin2, BitBltPlugin,<br>
>     ExtendedClipboardPlugin, SoundPlugin, (old experiment)<br>
>     VectorCanvasPlugin. I ported FFI to 64 bit Cuis (the 32 bit FFI was<br>
>     inherited from Squeak), and used it for OpenCL. I don't have a<br>
>     favorite,<br>
>     and I think there shouldn't be one. So, today I spent a couple of hours<br>
>     writing this:<br>
> <br>
>     ================================<br>
> <br>
>     FFI or Vm Plugins?<br>
>     ------------------<br>
> <br>
>     There are two main ways to call external code in the Cuis / Squeak<br>
>     world. One is FFI (what is usually used in other dynamic languages) and<br>
>     VM Plugins (a mechanism that is specific to the Squeak VM). There might<br>
>     be use cases where one of them is preferable to the other. Let's take a<br>
>     look at what they do, to see their pros and cons.<br>
> <br>
>     FFI<br>
>     ---<br>
>     FFI is a general mechanism to call external platform libraries. DLLs<br>
>     and<br>
>     the like. The mechanism is general, so for each different function we<br>
>     might call, we need a way to build the native platform call stack<br>
>     (function arguments). This is different for each platform, and<br>
>     different<br>
>     for each function. This function+platform specific specification lives<br>
>     in the Smalltalk image.<br>
> <br>
>     FFI break with the idea that the VM defines the boundary between the<br>
>     Smalltalk world and the external world:<br>
>     - Any platform specific difference in functions called via FFI is<br>
>     handled in the Smalltalk image<br>
>     - The Smalltalk image is aware of each platform we might want to run on<br>
> <br>
>     For a non trivial example, evaluate `Feature require: 'OpenCL'` and<br>
>     browse the OpenCLPrimitiveInterface hierarchy.<br>
> <br>
>     VM Plugins<br>
>     ----------<br>
>     VM Plugins are a Squeak VM specific way to call C code. The call<br>
>     mechanism is general, and handled by the VM. The C code is specific to<br>
>     the problem to solve, and must follow the rules for building<br>
>     plugins. In<br>
>     many cases it is not platform specific. This function specific code in<br>
>     plugin form lives in Slang or C code.<br>
> <br>
>     VM plugins follow the idea that the VM defines the boundary between the<br>
>     Smalltalk world and the external world:<br>
>     - Smalltalk image is platform independent<br>
>     - VM + Plugins are platform dependent<br>
> <br>
>     As examples of their use, you might browse all methods containing<br>
>     string<br>
>     `module: 'FloatArrayPlugin'>` or module: 'JPEGReadWriter2Plugin'><br>
> <br>
> <br>
>     Use cases<br>
>     ---------<br>
>     Both FFI and VM Plugins can be used in a variety of scenarios, with<br>
>     possible different needs:<br>
>     (1) Using platform specific functionality (for instance, the Windows<br>
>     API)<br>
>     (2) Using third party code distributed as dynamic libraries (for<br>
>     example, TensorFlow)<br>
>     (3) Using third party code distributed as source code or static linked<br>
>     libraries (for example, libJPEG, stdlib.h memcpy(), math.h float stuff)<br>
>     (4) Own code, written in Slang or C for performance reasons (BitBlt,<br>
>     FloatArray)<br>
>     (5) Own code, needing to deal with Smalltalk object internals, or VM<br>
>     services.<br>
> <br>
>     Additionally, some calls need to be done with strict real time<br>
>     restrictions (like music / audio), or execution might be so quick<br>
>     and so<br>
>     frequent that any call overhead needs to be minimized (for example,<br>
>     BitBlt, LargeInteger).<br>
> <br>
> <br>
>     How do they compare?<br>
>     --------------------<br>
> <br>
>     a) Ease of development and prototyping.<br>
>     For the scenarios where FFI is well suited, (1) or (2), working with<br>
>     FFI<br>
>     is much faster and easier. It is possible to reuse API docs and general<br>
>     know how from outside the Smalltalk world. On the other hand, code that<br>
>     needs to deal with Smalltalk object internals and VM services (5) is<br>
>     easier to do as a plugins. For code written in C (and not regular<br>
>     Smalltalk) for performance reasons (4), if you already have the<br>
>     required<br>
>     setup, writing a plugin is easier and faster, as you don't need to deal<br>
>     with the platform stack.<br>
>     -- Bottom line: It depends.<br>
> <br>
>     b) Ease of modifications, ease of updating users installations.<br>
>     Modifying a plugin usually requires the developer to compile a new dll.<br>
>     Modifying FFI calls can be done with just Smalltalk code.<br>
>     -- Bottom line: Clear win for FFI.<br>
> <br>
>     c) Call Speed.<br>
>     Plugin calls are almost as fast as regular numbered primitives. FFI<br>
>     calls range from terribly slow to just plain slow, when compared to<br>
>     that.<br>
>     -- Bottom line: Plugin wins, if you really need low call overhead.<br>
> <br>
>     d) Support for callbacks<br>
>     Recent implementations of FFI do support real callbacks. With VM<br>
>     plugins, the best we can do is to register a semaphore for the<br>
>     plugin to<br>
>     signal. This is usually safer, as the callback is done as a Smalltalk<br>
>     Process switch, making it easier to protect shared state. But there<br>
>     might be a large delay from the moment the semaphore is signaled to the<br>
>     moment where the "callback" is actually ran.<br>
>     -- Bottom line: FFI (callbacks enabled) clear win, if you need<br>
>     callbacks.<br>
> <br>
>     e) Access to VM services and data structures to deal with Smalltalk<br>
>     objects<br>
>     VM plugins have a lot of services provided by available VM functions,<br>
>     and types provided by VM maker. Slang/C code needing to deal with the<br>
>     internals of Smalltalk objects is usually much easily done in plugins.<br>
>     -- Bottom line: Plugin wins, if you need this.<br>
> <br>
> <br>
>     What is each alternative good for?<br>
>     ----------------------------------<br>
> <br>
>     FFI is good for:<br>
>     - Tight integration with host platform (Host windowing system, native<br>
>     widget libraries)<br>
>     - 3rd party code that is meant to be linked dynamically, and everyone<br>
>     else calls via FFI<br>
>     - Application specific stuff (where dealing with platform specific<br>
>     details is not a problem)<br>
>     - Functionality that requires real callbacks<br>
>     - Stuff that is in development, APIs that are not yet stable,<br>
>     experimental code<br>
> <br>
>     Plugins are good for:<br>
>     - Own code written for performance<br>
>     - 3rd party code that is meant to be linked statically<br>
>     - Kernel Smalltalk functionality<br>
>     - Functions that take very short time to run, and overhead becomes<br>
>     dominant time<br>
>     - Stable functionality that will be used by many people over a long time<br>
> <br>
> <br>
>     ================================<br>
> <br>
>     I hope I haven't left out too many details. Feel free to argue,<br>
>     correct,<br>
>     discuss, etc.<br>
> <br>
>     Thanks,<br>
> <br>
>     -- <br>
>     Juan Vuletich<br>
>     <a href="http://www.cuis-smalltalk.org" rel="noreferrer noreferrer" target="_blank">www.cuis-smalltalk.org</a> <<a href="http://www.cuis-smalltalk.org" rel="noreferrer noreferrer" target="_blank">http://www.cuis-smalltalk.org</a>><br>
>     <a href="https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev" rel="noreferrer noreferrer" target="_blank">https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev</a><br>
>     <a href="https://github.com/jvuletich" rel="noreferrer noreferrer" target="_blank">https://github.com/jvuletich</a><br>
>     <a href="https://www.linkedin.com/in/juan-vuletich-75611b3" rel="noreferrer noreferrer" target="_blank">https://www.linkedin.com/in/juan-vuletich-75611b3</a><br>
>     @JuanVuletich<br>
> <br>
>     -- <br>
>     Cuis-dev mailing list<br>
>     <a href="mailto:Cuis-dev@lists.cuis.st" target="_blank" rel="noreferrer">Cuis-dev@lists.cuis.st</a> <mailto:<a href="mailto:Cuis-dev@lists.cuis.st" target="_blank" rel="noreferrer">Cuis-dev@lists.cuis.st</a>><br>
>     <a href="https://lists.cuis.st/mailman/listinfo/cuis-dev" rel="noreferrer noreferrer" target="_blank">https://lists.cuis.st/mailman/listinfo/cuis-dev</a><br>
> <br>
> <br>
-- <br>
Cuis-dev mailing list<br>
<a href="mailto:Cuis-dev@lists.cuis.st" target="_blank" rel="noreferrer">Cuis-dev@lists.cuis.st</a><br>
<a href="https://lists.cuis.st/mailman/listinfo/cuis-dev" rel="noreferrer noreferrer" target="_blank">https://lists.cuis.st/mailman/listinfo/cuis-dev</a><br>
</blockquote></div></div></div>