It’s a great joy to introduce cline, an online C++ interpreter here, which aimed to bring the chram of Cling to the broader public. With a simple and friendly interface, cline helps you to capture your spark of originality wherever the Internet is accessible. If you are curious about how the idea of cline was originated and turned into reality, this blogpost may answer some of your questions.

Motivation

It would easily turn into a heated debate if developers were asked to rate languages based on the difficulty to learn. Meanwhile, we may all agree that Javascript will be among the easiest in mainstream languages. I myself got into programming with Javascript, and the top reason I would recommend it to a beginner is the easily accessible REPL. Allowing users to examine code line by line, it gives a deep insight into the internals of a program, plus one can take this power anywhere a browser is accessible. This is why I feel so excited when I first met Cling, which I thought has the potential to change how people learn and prototype with C++. However, the popularity Cling received didn’t quite match my expectation. I recognized there might be another gap to fill: availability. What if people can use it on a web browser, just like a Javascript console?

Challenges

The idea of turning a compiler into a web application is not something new. These days, people can even run a linux kernel in browser with the magic of WebAssembly. While it’s tempting to port cling as a pure frontend application in the same way, it may not be desirable to send a huge bundle of headers and libraries over the network. Besides, whether this is possible at all remains questionable due to the immutable code segment in wasm, causing difficulties to the implementation of JIT compilation in Cling. A more conventional approach is to put the interpreter on the server, but still posing many challenges, particularly in security. Being able to access low-level primitives with C++, users can take over the whole server if no constraints are imposed. Another big headache is resource management. If this is to be done by Google or Amazon, they would just start a new virtual machine instance for each user, which also eliminates all security concerns. However, with limited resources, efficient utilization becomes critical, as well as ensuring that all users receive a fair share.

Final design

The problem ultimately boils down to a tradeoff between efficiency and security, and the sweet spot I found is the process level of isolation provided by the OS. In the design based on this decision, the service creates a separate interpreter process for each connection, which is the bare minimum required to isolate fatal errors and essential resources like signals. Another advantage of this design is the management of the service can be simply handed over to the websocketd program, saving quite some work. This nice utility forks a cline process every time a new connection is accepted, and bridges the process with the websocket client through IPC. All of these are encapsulated in an unprivileged docker container to prevent interpreter processes from accessing resources in the host’s namespace. The diagram below illustrates the overall architecture of the service:

Websocketd
Websocketd
Cline
Cline
Proxy
Server
Proxy...
Docker Container
Docker Container
Session1
Session1
Session2
Session2
SessionX
SessionX
Cline
Cline
Cline
Cline
Host Network
Host Network
Internet
Internet
Text is not SVG - cannot display

Other sandboxing techniques put into use include seccomp filter and Apparmor, employed by the interpreter and the container, respectively. These were set to intercept malicious system calls and deny accesses to sensitive locations in the file system. To be safe, the current filtering rules are rather strict, interfering with some important language features including threads. A focus of the subsequent work will be to gradually lift these restrictions without compromising the security guarantee. Given all components described above, one could have a hard time putting them together. Ideally, all building and deploying procedure should be packed into a docker image, allowing users to easily host their own service and adjust the level of security as needed. This is another import objective for the near future.

Outlooks

The cline project is still in the early stage of development. In addition to the plans mentioned above, more exciting features will be added soon. To name a few, the permalink to code snippets will allow easy code sharing, and support to VT100 sequences enables raw highlighting in messages the interpreter produce. Of course, the improvement of this open-source project cannot be made without you. Please submit an issue in the Github repository if you find a bug or have any suggestion. Finally, I hope you all can enjoy this work!