On Tue, Jul 1, 2008 at 12:49 PM, Bert Freudenberg <bert@freudenbergs.de> wrote:
Am 01.07.2008 um 21:25 schrieb Eliot Miranda:

I would go further and rip out support for named primitives from the VM and put it up in the image where it belongs.  I would build the machinery for looking up named primitives in the image and have a primitive that allowed one to slam a function address into a method.

For me the VM should include an execution engine, a small and fast FFI and nothing else.  One needs some VM support to bootstrap the FFI.  i.e. the VM must include a primitive to load a platform library and another to lookup a name in it.  But other than that everything can be up in the image.  When one invokes a method with a primitive that has not been bound to a function yet then the primitive fails and the image's primitive failure code looks up the primitive's name and retries the call or reports an error if the library or name can't be found.

Well, until now FFI was intentionally optional. Making it mandatory would immensely widen the Smalltalk-System interface, in fact, there would be no clearly defined interface anymore. Until now, Squeak is a relatively safe place, bad crashes are rare etc. Whenever you deal with FFI the next crash is only minutes away. Also, you could expect that the image would soon fill up with lots of platform-specific code. But more importantly, it would make sand-boxing impossible, as any code in the image can do anything to your machine if it has access to FFI.

So it would simplify the VM at the expense of added complexity in the image. Which may of course fit the bill for Croquet which already relies on FFI, and except for Etoys nobody really uses the sand boxing anyway.

One doesn't have to *use* the FFI.   If the FFI isn't exposed via a primitive then no FFI.  One can still have named primitives supported by the image and not by the VM and not use the FFI.  To call a named primitive in a primitive plugin the following sequence occurs:

the method containing a named primitive spec is activated and the primitive call fails because its function pointer is null.
the failure code extracts the plugin name and invokes a primitive to load the plugin library
the failure code extracts the primitive name and uses the lookup primitive to find the function in the loaded plugin library
the failure code uses a primitive to slam the function pointer into the method
the failure code uses the executeMethodWithArgs primitive to retry the bound named primitive method

So the FFI is an optional extra.  One needs four primitives, load library, lookup name in library, insert primitive function pointer. and executemethodWithArgs (thanks Tim!).  Slamming the function into the method could also be done using, say, objectAt:.

So one can still have a nice small safe VM and have no direct support for named primitives in the VM.

- Bert -