Skip to content

Choosing between FFI and plugin

Dr. Nicola Mingotti edited this page Dec 11, 2021 · 1 revision
  • This is is excerpt taken from here, Juan is talking.
>> >> ================================
>> >>
>> >> FFI or Vm Plugins?
>> >> ------------------
>> >>
>> >> There are two main ways to call external code in the Cuis / Squeak
>> >> world. One is FFI (what is usually used in other dynamic languages) and
>> >> VM Plugins (a mechanism that is specific to the Squeak VM). There might
>> >> be use cases where one of them is preferable to the other. Let's take a
>> >> look at what they do, to see their pros and cons.
>> >>
>> >> FFI
>> >> ---
>> >> FFI is a general mechanism to call external platform libraries. DLLs and
>> >> the like. The mechanism is general, so for each different function we
>> >> might call, we need a way to build the native platform call stack
>> >> (function arguments). This is different for each platform, and different
>> >> for each function. This function+platform specific specification lives
>> >> in the Smalltalk image.
>> >>
>> >> FFI break with the idea that the VM defines the boundary between the
>> >> Smalltalk world and the external world:
>> >> - Any platform specific difference in functions called via FFI is
>> >> handled in the Smalltalk image
>> >> - The Smalltalk image is aware of each platform we might want to run on
>> >>
>> >> For a non trivial example, evaluate `Feature require: 'OpenCL'` and
>> >> browse the OpenCLPrimitiveInterface hierarchy.
>> >>
>> >> VM Plugins
>> >> ----------
>> >> VM Plugins are a Squeak VM specific way to call C code. The call
>> >> mechanism is general, and handled by the VM. The C code is specific to
>> >> the problem to solve, and must follow the rules for building plugins. In
>> >> many cases it is not platform specific. This function specific code in
>> >> plugin form lives in Slang or C code.
>> >>
>> >> VM plugins follow the idea that the VM defines the boundary between the
>> >> Smalltalk world and the external world:
>> >> - Smalltalk image is platform independent
>> >> - VM + Plugins are platform dependent
>> >>
>> >> As examples of their use, you might browse all methods containing string
>> >> `module: 'FloatArrayPlugin'>` or module: 'JPEGReadWriter2Plugin'>
>> >>
>> >>
>> >> Use cases
>> >> ---------
>> >> Both FFI and VM Plugins can be used in a variety of scenarios, with
>> >> possible different needs:
>> >> (1) Using platform specific functionality (for instance, the Windows API)
>> >> (2) Using third party code distributed as dynamic libraries (for
>> >> example, TensorFlow)
>> >> (3) Using third party code distributed as source code or static linked
>> >> libraries (for example, libJPEG, stdlib.h memcpy(), math.h float stuff)
>> >> (4) Own code, written in Slang or C for performance reasons (BitBlt,
>> >> FloatArray)
>> >> (5) Own code, needing to deal with Smalltalk object internals, or VM
>> >> services.
>> >>
>> >> Additionally, some calls need to be done with strict real time
>> >> restrictions (like music / audio), or execution might be so quick and so
>> >> frequent that any call overhead needs to be minimized (for example,
>> >> BitBlt, LargeInteger).
>> >>
>> >>
>> >> How do they compare?
>> >> --------------------
>> >>
>> >> a) Ease of development and prototyping.
>> >> For the scenarios where FFI is well suited, (1) or (2), working with FFI
>> >> is much faster and easier. It is possible to reuse API docs and general
>> >> know how from outside the Smalltalk world. On the other hand, code that
>> >> needs to deal with Smalltalk object internals and VM services (5) is
>> >> easier to do as a plugins. For code written in C (and not regular
>> >> Smalltalk) for performance reasons (4), if you already have the required
>> >> setup, writing a plugin is easier and faster, as you don't need to deal
>> >> with the platform stack.
>> >> -- Bottom line: It depends.
>> >>
>> >> b) Ease of modifications, ease of updating users installations.
>> >> Modifying a plugin usually requires the developer to compile a new dll.
>> >> Modifying FFI calls can be done with just Smalltalk code.
>> >> -- Bottom line: Clear win for FFI.
>> >>
>> >> c) Call Speed.
>> >> Plugin calls are almost as fast as regular numbered primitives. FFI
>> >> calls range from terribly slow to just plain slow, when compared to that.
>> >> -- Bottom line: Plugin wins, if you really need low call overhead.
>> >>
>> >> d) Support for callbacks
>> >> Recent implementations of FFI do support real callbacks. With VM
>> >> plugins, the best we can do is to register a semaphore for the plugin to
>> >> signal. This is usually safer, as the callback is done as a Smalltalk
>> >> Process switch, making it easier to protect shared state. But there
>> >> might be a large delay from the moment the semaphore is signaled to the
>> >> moment where the "callback" is actually ran.
>> >> -- Bottom line: FFI (callbacks enabled) clear win, if you need callbacks.
>> >>
>> >> e) Access to VM services and data structures to deal with Smalltalk objects
>> >> VM plugins have a lot of services provided by available VM functions,
>> >> and types provided by VM maker. Slang/C code needing to deal with the
>> >> internals of Smalltalk objects is usually much easily done in plugins.
>> >> -- Bottom line: Plugin wins, if you need this.
>> >>
>> >>
>> >> What is each alternative good for?
>> >> ----------------------------------
>> >>
>> >> FFI is good for:
>> >> - Tight integration with host platform (Host windowing system, native
>> >> widget libraries)
>> >> - 3rd party code that is meant to be linked dynamically, and everyone
>> >> else calls via FFI
>> >> - Application specific stuff (where dealing with platform specific
>> >> details is not a problem)
>> >> - Functionality that requires real callbacks
>> >> - Stuff that is in development, APIs that are not yet stable,
>> >> experimental code
>> >>
>> >> Plugins are good for:
>> >> - Own code written for performance
>> >> - 3rd party code that is meant to be linked statically
>> >> - Kernel Smalltalk functionality
>> >> - Functions that take very short time to run, and overhead becomes
>> >> dominant time
>> >> - Stable functionality that will be used by many people over a long time
>> >>
Clone this wiki locally