[Vm-dev] Removing most of the windowing code

Ronie Salgado roniesalg at gmail.com
Thu Nov 24 14:06:41 UTC 2016

> you cannot unilaterally do this.
> I hate autoconf too, but in VM list we have a general agreement on how to
> manage the VM build process, and unless you manage to convince the rest of
> people working there (and specially Eliot, who works there more than the
> rest), you have literally zero chance this will be adopted (and then, your
> work will be a general lose of timeā€¦).
> In any case, you have my vote :)
This was something that I did for quickly testing and trying to remove the
windowing code. I also did this, because the building system is not working
all of the time in my linux machine. The scripts for loading the VMMaker
image are most of the time not working at all in Linux. I got frustrated by
not being able on keep working on Lowcode for supporting the 64 bits
version, because of these problems.

Anyway, I do not care if this part gets integrated or not, as long as I can
keep working on my stuff, and I don't have a bunch of manully written
scripts in build.*/* . As long as there is a single script that can be
configured for each target or flavour of the VM I am okay with it.

Now I will document these scripts:

For setting the flavour of the VM, there are the following options
- SPUR_OBJECT_MODEL (On by default)
- SISTA_OPTIMIZER (Off by default)
- PHARO_BRANDING (On by default)
- COG_JIT(On by default. If off, it will build a stack interpreter only VM)

There are platform specific check for choosing whether to build a 64 bits
VM or not. When building in a x86_64 systems, there is the
BUILD_I386_VERSION option (Off by default) which will set the appropiate
flags for building a 32 bits VM in a 64 bits system (-m32)

These options are used for making a string with the vm sources
direction(src ,stacksrc, spursrc, etc) and for selecting the sources of the
vm. In this experimental branch I am moving some of the sources at
platform/<platform_name/vm into the minheadless/source, for including the
barest minimum code for compiling the VM. By the end of this, I should
probably move back the platform specific sources into their original

The plugins to build with the VM are defined in Plugins.cmake (

Most of the time, adding a plugin is just a matter calling a macro:

> # Basic internal plugins
> add_vm_plugin_auto(FilePlugin INTERNAL)
> add_vm_plugin_auto(LargeIntegers INTERNAL)
> add_vm_plugin_auto(LocalePlugin INTERNAL)
> add_vm_plugin_auto(MiscPrimitivePlugin INTERNAL)
> add_vm_plugin_auto(SecurityPlugin INTERNAL)
> add_vm_plugin_auto(SocketPlugin INTERNAL)
> add_vm_plugin_auto(B2DPlugin INTERNAL)
> add_vm_plugin_auto(BitBltPlugin INTERNAL)
> add_vm_plugin_auto(FloatArrayPlugin INTERNAL)
> add_vm_plugin_auto(FloatMathPlugin INTERNAL)
> add_vm_plugin_auto(Matrix2x3Plugin INTERNAL)
> # Basic external plugins
> add_vm_plugin_auto(SurfacePlugin EXTERNAL)

For more selective plugins, such as the SqueakFFIPrims plugin there is the
add_vm_plugin_sources macro:

> add_vm_plugin_sources(SqueakFFIPrims EXTERNAL ${SqueakFFIPrims_Sources})

Later I will add another macro for linking a library with a plugin, which
will perform the correct action depending whether the Plugin is internal or
external. The macros for building a plugin add an option for specifying
whether to build or not a plugin (e.g: BUILD_PLUGIN_FilePlugin,

For building the a default VM using cmake, the only commands are required
in the top level source directory:

> mkdir build_dir
> cd build_dir
> cmake ..
> make

For choosing interactively which options to enable or not, it is possible
to use cmake-gui instead of cmake in the above sequence of commands. The
built VM will be placed at build_dir/dist

Currently, I am not using the cmake configure capabilties for generating
config.h and generating the HAVE_*_H defines. Later I will implement this,
but taking special care in supporting the cross compilation scenario, where
it is not possible to execute compiled program for probing the system for
things such as sizeof(void*).

Could you explain more what traditional display backend means? Because I am
> probably out of domain but want to know more.
If the SUPPORT_TRADITIONAL_DISPLAY cmake option is enabled, and cmake finds
SDL2 (it will look for the SDL2 libraries using the names SDL2-2.0 SDL2),
then a non-headless VM will be built using sqPlatformSpecific-SDL2Window.c
) instead of sqPlatformSpecific-NullWindow.c (

This non-headless VM using SDL2 instead of the platform specific API, which
should help in avoiding conflicts between the OSWindow event loop and the
VM event loop. This works with a normal Pharo 6 image.

This SDL2 based backend creates a window for the VM, only when asked by the
image and process events sent to the VM window in the traditional way of
translating the events into squeak events; placing the translated event in
a queue, and then signaling a semaphore. SDL2 events that are not related
to the VM window are placed untranslated in a separate queue, and there are
used signal a separate semaphore for allowing OSWindow to process the
event. I have already implemented the required primitives and updated
OSWindow for using them, when they exist. I still have to update the
OSWindow configuration. This approach allows preventing conflicts between
the events for the VM window and OSWindow.

Ronie, do you already have code to restore windows after image save? Any
> issue opened?
Not yet for the extra morphic Worlds.

How much VM size it reduced?

I have not checked yet, but this is about reducing some complexity.

How dare you ?
> Yesterday 03:00 am I finally managed to make my shared memory bridge
> between Pharo and C++ to work also on Windows after a ton of debugging and
> here comes you telling me that all my effort was for nothing. It now works
> and is tested on MacOS 10.12 , Ubuntu 15.04 and Windows 10 (all of them 64
> bit).
> That is not worthless at all. That is still an excellent mechanism for
fast IPC.

Have you got no mercy ?

No :) . Ask Thibault about the OpenGL bindings for the UFFI. That time I
was cleaning OSWindow dependencies.

Suffice to say I am super interested in both Non GUI Pharo because I use
> Unreal Game Engine and embedding Pharo because I use Unreal Game Engine.
> Embedding Pharo is a must have for me because my shared memory solution
> would not be acceptable by Apple on iOS since it forbids an app from
> running two executable at the same time which is basic requirement for
> shared memory. Stupid Apple :/ . Android seems to be fine with this.
> For now my game will target only PC where my shared memory solution works
> fine but sooner or later I will have to port to iOS and Android.
> If there is anything I can do to help you out, dont hesitate to ask. I am
> going to give your build a try now :).
It is still needed to define a proper interface for embedding the VM. This
interface should be a single .h file, with the highest level of abstraction
possible. There are some other issues such as potential name clashes, and
the fact that the VM symbols are public by default. At the bare minimum, it
has to provide functions for initializing the VM, passing command line
arguments, loading an image, running the image, and shutting down.

So far I managed to reduce main source code a lot in sqMain.c (
) . I am probably moving most of that into a separate source code file that
will be always linked with VM core library, and keeping the source file
with main function only couple of lines long (Init vm, load image,
interpret and shutdown )

BTW, now I am working for a chilean video game company using Unreal. I do
not like Unreal because it takes a very long time to compile, even with a
44 cores machine (88 threads) that we have in the company for rendering and
compiling. I am wondering how that integration is going to end.

The embedding interface is not in my priority list. My priority is getting
OSWindow working well in Windows (required by the Bloc and Roassal people).
My second priority is getting Lowcode working on Linux, Mac and Windows in
both, 32-bits and 64 bits mode.

Best regards,

2016-11-24 5:59 GMT-03:00 Denis Kudriashov <dionisiydk at gmail.com>:

> Hi
> 2016-11-24 8:12 GMT+01:00 Ronie Salgado <roniesalg at gmail.com>:
>> Hello,
>> I am working on removing most of windowing code from the VM, and in
>> trying to unify the platform specific code of the VM. In the
>> MinimalistHeadless branch of https://github.com/ronsaldo/opensmalltalk-vm
>> I made the following changes:
> This is super cool. With Pavel we just tried open oswindow based world
> from headless image and it work almost perfect. No problems with keyboard
> and scrolling anymore. And it already provides very good approach for
> deploying desktop app.
>> - Unified standard CMake building scripts for Unixes. I hate autoconf. I
>> want to use them in Windows too.
>> - Refactoring the Unix entry points. I am trying to remove a lot of code
>> for simplfying stuff.
>> - Null window driver for true headless.
>> - Optional SDL2 based traditional display backend for compatibility
>> reasons, and because the extra Morphic worlds using OSWindow are a bit
>> unstable.
> Could you explain more what traditional display backend means? Because I
> am probably out of domain but want to know more.
>> So far I managed to run a standard Pharo 6 image using this custom VM in
>> Linux. Windows and Mac are coming next. Hopefully this is going to fix the
>> problems with duplicated events when using OSWindow in Windows.
>> I am also planning on making a standard interface for embedding the VM in
>> an application, at least as a static library. With this new building
>> system, this seems to be easy to do.
>> BTW. When I tried the minimalistic Pharo image, in a completely headless
>> VM, I got the following error:
>> [ "Ugh .... now this is a biggie - a system that does not support
>>         any of the display depths at all."
>> Smalltalk
>>     logError:
>>         'Fatal error: This system has no support for any display depth at
>> all.'
>>     inContext: thisContext.
>> Smalltalk quitPrimitive    "There is no way to continue from here" ] in
>> DisplayScreen>>findAnyDisplayDepth
>> DisplayScreen>>findAnyDisplayDepthIfNone:
>> DisplayScreen>>findAnyDisplayDepth
>> DisplayScreen>>setExtent:depth:
>> DisplayScreen class>>startUp
>> As a workaround, I am doing the following for ioHasDisplayDepth with the
>> null driver:
>> sqInt ioHasDisplayDepth(sqInt depth)
>> {
>>     return true;
>> }
> I guess it is temp solution? Because no DisplayScreen should exist in
> headless mode.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20161124/5bffd06b/attachment-0001.html>

More information about the Vm-dev mailing list