The California Smalltalkers meeting on August 13 at 7:00 p.m. PDT will feature a presentation by Craig Latta on his recent work with Catalyst, a WebAssembly GC (WASM GC) implementation of the Open Smalltalk virtual machine. Latta will share surprising results from experiments using AI models to dynamically translate Smalltalk methods into WASM functions.
The talk will also examine the historical evolution of dynamic stack machine optimization and explore BNF-level optimizations enabled by the Epigram compilation framework.
The meeting will additionally include community lightning talks, giving attendees an opportunity to highlight current projects and ideas. Participants are invited to draw inspiration from their peers, and those interested in giving a longer presentation in the future are encouraged to reach out to the organizers.
An initiative has recently emerged within the Squeak community to explore bringing Croquet into the modern Squeak 6.0 environment, with their efforts opening up possibilities for personal and educational applications, and potentially paving the way for long-term developments. Community members Edwin Ancaer and Timothy have taken it upon themselves to explore, port, and troubleshoot Croquet – an ambitious collaborative 3D environment originally designed to run in earlier 32-bit versions of Squeak.
Croquet was a groundbreaking software architecture designed for deep collaboration, originally built as an open, free, and highly portable extension of the Squeak programming system. It provided a platform for both development and real-time collaborative work, with no separation between user and developer environments. Focused on 3D shared spaces, Croquet enabled users to interact in context-based collaborations, observing each other’s actions and focus in real time. A collaboration protocol called TeaTime powered this synchronization, and rendering was based on OpenGL. While newer, proprietary descendants of Croquet have evolved since, the version being revived in Squeak 6.0 reflects this original, exploratory vision.
Croquet Jasmine, a developer’s release of the system, is available and can be run live in a web browser using the SqueakJS virtual machine – allowing others to easily explore Croquet without a local setup. You can try a live version here: codefrau.github.io/jasmine/.
Technical Hurdles and Graphics Considerations
Efforts began early in the process, building on Nikolay Suslov’s work to get the original Open Croquet running on the latest versions of Squeak 5.x. His work laid the groundwork for achieving compatibility with Squeak 6.0. You can explore his repository here: github.com/NikolaySuslov/croquet-squeak. You can also check out detailed steps Nikolay has provided to bring Croquet into an early alpha version of Squeak 6.0 here.
A primary obstacle encountered was the tight coupling between Croquet and OpenGL 1. As Vanessa Freudenberg pointed out, OpenGL has been deprecated on macOS for years, complicating efforts to run the system on 64-bit machines. Vanessa suggested considering Vulkan or OpenGL 4 as possible alternatives for the rendering backend.
In consideration of a long-term solution, it is helpful to explore the potential paths forward, each with its own trade-offs:
Re-implement OpenGL 1 as a compatibility layer – Offers limited long-term value and would still not work effectively on macOS due to deprecated OpenGL support and the absence of modern graphics capabilities. Efforts like MoltenGL, which aim to bridge OpenGL to Metal, do not support OpenGL 1, making this path particularly challenging.
Migrate to a modern OpenGL (3.x or 4.x) – More viable than OpenGL 1 in terms of features, and partially supported on macOS (up to OpenGL 4.1). However, it is deprecated and no longer maintained on Apple platforms, making it an unstable foundation for future development.
Adopt Vulkan for high performance – A modern, low-overhead graphics API designed as a successor to OpenGL. While Vulkan is not natively supported on macOS, it can be used via MoltenVK, which translates Vulkan calls to Metal. This option requires significant integration work but offers the most long-term potential across platforms.
For a long-term solution, Vulkan appears to be the most promising path – essentially a modern, cross-platform successor to OpenGL, developed to overcome many of its limitations. Although not natively supported on Apple platforms, Vulkan’s compatibility through MoltenVK makes it a viable candidate for achieving performance and portability across environments.
While these options are worth exploring for long-term solutions, they may be unnecessarily complex for personal or educational use. However, the current efforts could prove valuable down the road by revealing key details, helping future work begin from well-understood points in the development process.
Vanessa has managed to run Croquet Jasmine without modifying the Smalltalk code by using the browser-based SqueakJS VM, with a custom OpenGL 1 implementation written in JavaScript. This was accessed via FFI and mapped to modern WebGL. The approach preserves the original graphics code inside the image while offloading rendering to the browser, and could serve as a model for similar efforts going forward.
Debugging and the Role of C in a Self-Hosting Environment
In efforts to get Croquet working with Squeak 6.0, contributors encountered challenges requiring low-level debugging. Their focus shifted to analyzing behavior via the debug VM, aiming to isolate root causes of instability or failure.
One may wonder why Squeak, being a self-hosting environment, might still require work in C. The environment is written in Smalltalk and is capable of building and evolving itself entirely from within. This self-hosting capability enables fast iteration, deep system visibility, and live modification of running code – all without leaving the environment.
However, Squeak runs on a virtual machine, with performance-critical parts written in a restricted subset of Smalltalk known as Slang (Swiki link). Slang is not a separate language, but a subset of Smalltalk designed to be translatable into C for compilation. This allows the virtual machine, which is largely written in Smalltalk, to be compiled into efficient native code for multiple platforms. When issues arise at the VM level – such as those involving primitives, foreign function interfaces, or memory management – developers must drop down into the generated C code to diagnose and resolve them. You can read more about the Squeak VM on the Swiki here and here.
The benefit of this design is excellent portability: the Smalltalk environment remains consistent across platforms, while only the VM layer needs to be recompiled or adapted for different operating systems or hardware. Having this level of separation allows the Squeak image to remain consistent across multiple platforms without exposing the underlying hardware implementation to the image code itself.
Further analysis suggested that inconsistencies between expected and actual behavior in the virtual machine’s handling of system-level function calls were at the heart of the issue – at least for now. By carefully tracing how external interfaces were being resolved and invoked, the contributors were able to isolate a likely point of failure. The realization was met with enthusiasm, signaling meaningful progress toward resolving the issue.
The Irony of Debugging and Systems Development
Edwin humorously remarked that he never expected working in Smalltalk would lead him back to debugging C code – a twist that underscores the unpredictable nature of systems development. Tim Rowledge added that, during his time at ParcPlace, it was an inside joke that those who got hooked on Smalltalk inevitably ended up spending too much time writing C, while the C++ fans who joined the team found themselves writing Smalltalk instead. The irony of this unexpected reality highlights the surprising paths developers take when working with complex systems.
Looking Ahead
We extend deep appreciation to Nikolay Suslov for his foundational work in bringing the original Open Croquet to Squeak 5.x, which has served as a solid base for moving toward compatibility with Squeak 6.0. A special thanks also goes to Edwin and Timothy for their time, dedication, and resourcefulness in troubleshooting and adapting Croquet to modern Squeak 6.0 systems. Their efforts contribute to the broader community by preserving an important piece of Squeak history and helping to lay the groundwork for future advancements.
The effort to bring Croquet to Squeak 6.0 is ongoing. We wish those involved continued success and invite anyone curious to jump in, contribute, and join the effort to keep Squeak a vibrant environment for innovation and exploration!
Have a great time with Smalltalk and keep on Squeaking!
Work has progressed with SqueakJS since our last report in April. In May, version 1.2.1 was released, adding a virtual Cmd button and fixes for touch events. The June release, version 1.2.2, made the copy-and-paste menu items functional on mobile devices. The most recent version, 1.2.3, was released in September, bringing a touch keyboard and other minor fixes.
Additionally, we would like to extend congratulations to the SqueakJS project! The Dynamic Language Symposium (DLS) awarded SqueakJS this year’s DLS Most Notable Paper award for the paper “SqueakJS: A Modern and Practical Smalltalk that Runs in Any Browser,” authored by Vanessa Freudenberg, Dan Ingalls, Tim Felgentreff, Tobias Pape, and Robert Hirschfeld. You can read the paper here, and also view the announcement here.
Work continues to progress with SqueakJS, and we are grateful for it. The project leverages web browsers as the primary platform, enabling applications to run directly without the need for native software installations. This feature ensures easy deployment and access, making it ideal for environments where installing traditional software is not possible or practical.
SqueakJS is an HTML5 runtime engine for Squeak/Smalltalk, written in pure JavaScript. It is also compatible with many other OpenSmalltalk-compatible images. Check it out at https://squeak.js.org. If you would like to contribute, head over to https://github.com/codefrau/SqueakJS and see what you might like to help with. Contributions are welcome!
Have a great time with Smalltalk and keep on Squeaking!
When developing complex systems, encountering errors that leave your project in a frozen state can bring much sadness and consternation. For developers working with Squeak/Smalltalk, a frozen image refers to a situation where the system becomes unresponsive. This can happen due to various issues, including deadlocks, infinite loops, or recursive operations in Smalltalk code, which can cause the VM to freeze, hang, or lock up.
A recent discussion in the Squeak community highlighted how one such incident, caused by a stuck semaphore during an image load, turned into an opportunity for both recovery and valuable practices in safeguarding against future mishaps. You can explore the full conversation in the Squeak-dev mailing list thread (here).
The Problem: Semaphore Deadlock in the Image File
In this case, a developer encountered an issue while attempting to draw in multiple background threads, using a chain of semaphores to manage the UI thread. After resolving an error in one of the background threads, the drawing process was resumed. However, it was found that the image would fail to load. Instead of opening, the image became unresponsive and effectively “frozen.” It had likely become stuck due to a semaphore waiting for a signal that would never come. This left the image unresponsive and effectively unusable – or so it would have seemed.
Recovery Options: DoItFirst and Debugging
The good news is that there are several options available for recovering from such failures.
For developers dealing with frozen images at startup, Squeak provides a mechanism called DoItFirst. This is a class that is processed at the very beginning of the image startup sequence, allowing developers to inject custom code or actions before the main system fully loads. By using command-line arguments like --debug, it is possible to force the image to enter the debugger at the earliest point in the startup process, allowing issues to be diagnosed and fixed before the image fully loads.
Additionally, for situations where the issue is well-understood, the --doit option allows Smalltalk expressions to be passed and executed before any problematic behavior occurs, giving developers a chance to resolve issues before they impact the image during loading.
Another option is to open the Virtual Machine (VM) in a debugger. In the specific case of a stuck semaphore, you can set a breakpoint in interpret. Run the VM until it reaches interpret a second time (the first invocation does some initialization). At this point, you can use printAllProcesses to locate the stuck process. This should display the semaphore the process is waiting on. Once identified, you can invoke synchronousSignal with that semaphore to unstick it and restore functionality without losing significant progress. While this technique can specifically handle a stuck semaphore, it could also be helpful for other cases of system hangs or unresponsiveness.
The Importance of Backups and Versioning
While debugging and recovery tools are invaluable, it is clear that prevention is equally important. Routine backups and effective versioning are essential practices that can mitigate the risks associated with frozen images and other failures. One practice that proved helpful in this case was maintaining regular system backups, which made it possible to quickly restore a previous version of the image with minimal data loss. However, more granular versioning, especially in environments with frequent risky changes, would provide an additional layer of safety.
Specifically, incremental versioning of the image can be a lifesaver when things go wrong. By saving a new version of the image each time a meaningful step in development is reached, developers can create a clear history of their work. This allows them to revert to earlier versions of the image if issues arise, minimizing the impact of failed changes and speeding up the recovery process. Incremental image saves help ensure that even if an image becomes frozen or corrupted, a previous, stable version can be restored with minimal effort.
The Robustness of Squeak: Multiple Recovery Options
One of the key takeaways from this experience is how robust Squeak is in terms of recovery options. Even when a frozen image occurs or the system becomes unresponsive, Squeak offers multiple layers of recovery mechanisms. Whether using DoItFirst to inject custom code during startup or interacting with the VM through a debugger to manually resolve issues with semaphores, there are a variety of ways to recover from errors and get back on track.
Additionally, Squeak’s development environment is designed to be highly flexible, encouraging experimentation while ensuring that recovery is always possible. One of the key advantages of Squeak is that all the code executed or saved during development is stored in the .changes file. This makes it possible to recover from almost any issue, as the system is built to retain all your code. Even if an image becomes frozen or corrupted, the code itself is never truly lost. With the resources mentioned in this article, developers can restore their environment and continue their work. In Squeak, code is safe; no matter what happens to the image, your code can always be recovered.
Conclusion
In conclusion, while Squeak’s development environment offers tools to recover from serious errors, the most effective defense is good preventive practice: maintain regular backups, version your work consistently, and always be mindful of the unexpected.
For more detailed information on using DoItFirst to debug and recover your Squeak image, visit the DoItFirst Swiki page (here). If you encounter issues like crashes or freezes in Squeak, there are various levels of potential failure to consider, and helpful guidance is available in the What to do if Squeak crashes or freezes resource (here), which offers insight into diagnosing and resolving different types of system freezes or crashes.
Have a great time with Smalltalk and keep on Squeaking!
.. I expect this is the year [the threaded FFI] will be [production ready]. Spur provides pinning, so the VM infrastructure is there. The Pharo community plus some commercial relationships that have developed are providing funding. Esteban Lorenzano and I want to collaborate on this and I hope to get help from some other people, such as Ronie Salgado. And Mariano is working on an important part of the problem. So I feel there’s sufficient momentum for us to realize the threaded FFI this year.
.. and when Craig Latta tried to use it late last year it worked up to a point. The thing that didn’t work was callbacks from foreign threads. So it looks like the core threading code is not too far away from working.
Another really important part, bigger than threading, is marshaling. Being able to handle the full x86_64 abi requires a better approach than interpreting tops signatures. Igor’s NativeBoost gave an example of how to generate marshaling machine code, but alas only for x86. But Sista includes an extensible bytecode set for arbitrary instructions. Sista is close to production, and we know the bytecode set works. So the plan is to use these bytecodes to do the marshaling. That neatly solves the problems of a) associating marshaling machine code with a method and b) marshaling in an interpreted stack VM, since the bytecode set works in any Cog VM. So the plan is to write an ABI compiler from C signatures to marshaling code to replace the interpreted FFI plugin.
So this year I hope we will have an excellent high-performance FFI.
Word has it that Clément Béra is working With Eliot Miranda on Cog. Göran pointed out Clements excellent blog: here, to me a few weeks ago after meeting him at ESUG.
From Eliot: Clément Béra is, amongst other things, working on Cog performance, looking at adaptive optimization/speculative inlining (Sista in Cog, for Speculative Inlining Smalltalk Architecture).
I just wanted to welcome Clément Béra and to say thank you to everyone working on the VM for both communities, you know who you are (and we do to) and especially Eliot for working on Cog and keeping the advancements coming! Hip Hip … and all that.
I’ve just published a blog post on lazy become and the partial read barrier in Spur. I’d really appreciate criticism, preferably as comments on the blog page (Eliot’s blog not this one, please follow the link to comment). This is one of the riskier parts of the design so it really does need to be pounded on.
In this episode we talk to tim Rowledge about his work on Smalltalk VMs over the years, especially for the RISC OS Platform and ARM machines.. The latest and probably hottest thing in this arena is his port of Squeak to the Raspberry Pi. This is not only cool in itself, but more importantly enables Raspberry Pi users to use Scratch and EToys on this little machine on RISC OS (the Raspbian Linux version existed before). You can probably imagine how much fun we had in recording this session.