JVM Advent Calendar: Smalltalk With the GraalVM
We're going back to the future to do some Smalltalk with the GraalVM.
Join the DZone community and get the full member experience.Join For Free
Today, we're going back to the future to do some Smalltalk with the GraalVM.
You may also like: Learning to Use GraalVM
The Java HotSpot Performance Engine is one of the most sophisticated process virtual machines (VMs) available and used by millions of Java developers every day. If we go back in the early history of HotSpot, not many people may know that HotSpot was initially built by the same team that worked on Strongtalk, a strongly-typed Smalltalk environment as its name suggests.
In case you've never heard of Smalltalk: it's both a programming language and a programming system created by a research group led by Alan Kay at Xerox PARC. Although the community today is quite small compared with those of more mainstream programming languages, Smalltalk systems such as Squeak/Smalltalk, VisualWorks, Pharo, or GemStone/S are still widely used in research and industry to this day.
One of the most interesting developments in current virtual machine research, on the other hand, is the GraalVM project. GraalVM is a high-performance virtual machine based on HotSpot and comes with support for multiple programming languages. At this point, I'm sure you've already figured out what this blog post is about: running Smalltalk on the GraalVM!
You may be wondering why Smalltalk and GraalVM? For one, it's, of course, an interesting challenge to bring Smalltalk with all its language features and its programming system to the GraalVM (more on that later).
More importantly, we as a research group are interested in exploring the domain of polyglot programming. Polyglot programming is the practice of writing code in multiple programming languages in the same software project. This gives developers a much broader choice in terms of libraries and frameworks they can re-use.
However, we were looking for the right platform that would allow us to experiment with language interoperability and the GraalVM. Instead of having to go through an external API such as the JVM Tool Interface (JVMTI), a Smalltalk programming system would just be yet another programming language on the GraalVM with direct access to all its runtime capabilities.
Moreover, Smalltalk comes with a comprehensive set of programming tools with support for exploratory programming and live object inspection that we could adapt to other programming languages.
That's why we have implemented GraalSqueak, a Squeak/Smalltalk implementation for the GraalVM.
Let's talk a bit about the implementation of GraalSqueak. If you'd like to see some demos first, feel free to skip this section and come back later if you like.
How GraalSqueak Fits into the GraalVM Ecosystem
GraalSqueak's Bytecode Interpreter
To support Smalltalk on GraalVM, we, therefore, needed to implement a Smalltalk VM in Truffle. The first challenge, however, was the fact that Truffle is designed for AST interpreters while the Smalltalk-80 specification, as described in the Blue Book, includes a well-defined bytecode set similar to Java.
Although not well-documented officially, Truffle supports the implementation of bytecode interpreters through a special form of AST representation. This approach is used in GraalVM's LLVM bitcode interpreter and in GraalSqueak, and explained in detail in this paper ( preprint). If you're looking for some code, you can find GraalSqueak's bytecode loop here.
Supporting the Smalltalk Programming System
The Smalltalk programming system, however, needs a lot more than just a bytecode interpreter to work correctly. Smalltalk is mostly written in itself. The compiler, for instance, is written in Smalltalk and so are many language features such as exception handling or reflection. The language also supports some rather uncommon but powerful mechanisms:
allInstances returns a list of all instances for a given class, while can be used to swap identities of two objects. Moreover, everything is an object in Smalltalk, including source code. So instead of using files, Smalltalk VMs save snapshots of the entire object memory in a file, so-called , which can then be loaded again later, even on a different platform.
Truffle, on the other hand, does not support most of these features out-of-the-box. Hence, we had to come up with implementation strategies to support all these features on top of Truffle. In the case of
allInstances, for example, GraalSqueak walks all objects just like a garbage collector. And to load an image file, a Java object is allocated for each Smalltalk objects. To be able to communicate with them from other languages, these objects implement Truffle's interoperability API. On top of all of this, we also needed to port various VM plugins such as BitBlt and Balloon, which are used by the drawing machinery of Squeak/Smalltalk.
Unfortunately, there isn't enough time to go into more detail. But if you'd like to learn more about GraalSqueak, its implementation, and limitations, have a look at the GraalSqueak paper ( preprint) we presented at MPLR'19.
So now, it's time for some demos! In the following screencasts, we run GraalSqueak 1.0.0-rc6 on GraalVM 19.3.0 and demonstrate various Smalltalk tools that allow us to interact with different languages.
Workspace, Inspector, and Explorer
The first tool is the Workspace, which can be used to interactively evaluate code, similar to an interactive shell. For this, it provides so-called print-Its (
ctrl/cmd + p), inspect-Its (
ctrl/cmd + i), explore-Its (
ctrl/cmd + e), and do-Its (
ctrl/cmd + d) to request the execution of code and to display the result. Just like all other GraalVM languages, GraalSqueak provides a Polyglot API for evaluating code of other languages and for sharing data and objects between them.
Math module and invoke its
min function with arguments from Smalltalk and Python. Additionally, the base language of our PolyglotWorkspace can be changed via its context menu. This means the tool can also be used in the same way for all other languages supported by the underlying GraalVM. This demonstrates another advantage of polyglot programming: Language-agnostic tools can provide a much more consistent programming experience and consequently, developers don't have to learn how to use new tools whenever they learn a new language. Just think about all these different language-specific debuggers for example. Instead, they can keep their preferred debugger and use it for all languages. If you find this idea interesting, have a look at our paper ( preprint) on LSP support in Truffle.
The next tool shown in the screencast is our
PolyglotInspector. In this case, it's opened on a Python list and displays both the interface and the contents of the list. The traditional Smalltalk inspector updates frequently to provide more or less live feedback, and so does its polyglot variant. By invoking
append with a Smalltalk object as the argument, we put the object into the Python list, which is displayed in the inspector shortly after. Lastly, the Inspector can easily be turned into an Explorer, which displays interface and contents in a tree view instead of a list.
In our PolyJuS paper ( preprint), we have combined multiple workspaces and explorers to build a polyglot, Jupyter-like notebook system. In the video above, we first play around with a Python array and show, how objects can be shared via a special polyglot
bindings object. Then, we analyze the numbers of contributions for two different programming language conferences per country, always using the best library for the job: Ruby's for extracting data from an HTML table, a Python library called to clean the data set, R's to render a plot, and the tool itself written in Smalltalk. The PolyglotNotebook comes with GraalSqueak. If you're looking for GraalVM-powered Jupyter kernel with similar capabilities, check out our IPolyglot kernel.
Java and Smalltalk
Finally, let's have some fun with Java and Smalltalk! You may have noticed that Java is not listed as one of the supported languages. That's because there isn't a Truffle interpreter for Java yet (the GraalVM team is working on it though). But since Java is the host for all languages running on GraalVM, it is possible to interact with the host Java through a dedicated interface. This, in turn, means we can technically access and interact with all kinds of Java objects including parts of GraalSqueak's own infrastructure. This allows us to change the title of the , for example, that GraalSqueak uses for rendering the programming environment. And just because we can, we can call
System.gc() to request a garbage collect before quitting GraalSqueak via
We hope you enjoyed this dive into Smalltalk, GraalVM, and polyglot programming! If you'd like to give GraalSqueak a try, head over to this GitHub repository. The README.md should cover everything you need to get started! Please keep in mind, though, that this is an experimental research VM with various limitations at this point. Nonetheless, please open issues if you run into any problems or if you have any questions.
This summer term, we ran our first polyglot programming seminar at Hasso Plattner Institute. So if you're interested to see what our students have built with GraalSqueak, check out our post on the GraalVM blog. We look forward to using GraalSqueak for both teaching and research on polyglot programming in the next year!
Last but not least, we wish you a wonderful festive season and a happy new year!
Want to write for the Java Advent blog? We are looking for contributors to fill all 24 slots and would love to have your contribution! Contact the Java Advent Admin at firstname.lastname@example.org!
Published at DZone with permission of Fabio Nascimento. See the original article here.
Opinions expressed by DZone contributors are their own.