Cheerp 2.0-RC2 released — C++ to WebAssembly compiler with advanced JavaScript/WebAssembly interoperability

(originally published on May 9, 2018)

Today we announce the second release candidate of Cheerp 2.0, our C++ to JavaScript and WebAssembly compiler, available for download here.

Most of the updates for this release compared to RC1 are incremental, relating to improved performance, some optimisations on code elimination and code size, as well as some extended support for C++ constructs.

In addition to these, we focused on increasing the extent and power of the interoperability between JavaScript and WebAssembly in Cheerp. JavaScript-WebAssembly interoperability is one of the unique characteristic setting Cheerp apart from Emscripten, and we have been receiving very positive feedback on this feature, as a way to ‘get around’ many of the current limitations of WebAssembly, and take advantage of its power in a wider range of use cases.

We will soon be publishing a new worked example of a C++ library converted to WebAssembly using Cheerp 2.0, and leveraging its advanced JavaScript interoperability features to enable a clean JavaScript API to the library.

JavaScript-WebAssembly interoperability in Cheerp 2.0

It is now possible to compile C++ into a combination of JavaScript and WebAssembly code with much improved flexibility and granularity compared to RC1.

The -cheerp-mode command line switch selects the main compile output mode between JavaScript and WebAssembly (asm.js is also supported).

In addition, individual classes and functions can be tagged using Cheerp custom attributes ([[cheerp::wasm]], [[cheerp::genericjs]] and [[cheerp::asmjs]]), to determine how they will be compiled. As an example, see this code snippet which can be compiled to WebAssembly:

This is very useful in the (very common) case of wanting to compile a body of C++ code into fast WebAssembly code, but needing to interface with it from JavaScript. Using Cheerp’s interoperability and granular attribute tagging, this can be done without needing to write any ‘glue’ code.

Any method tagged with [[cheerp::genericjs]] will allow full access to the browser APIs (e.g. the DOM, WebGL, etc.), as well as any third-party JavaScript libraries. At the same time, and with no manual intervention, you can allocate and use objects from WebAssembly without having to worry about interfaces - Cheerp will generate all that automatically.

Any time some code cannot be compiled in the desired mix of WebAssembly and JavaScript (due to the current limitations of the WebAssembly standard), the compiler will alert you with a meaningful error message at compile time.

In Cheerp 2.0-RC2, we also strengthened the compile-time checks whenever combining WebAssembly with JavaScript outputs.

As an example, consider this C++ code:

Here, the user wants to interact with the DOM to show a message to the user, while compiling some heavy computation code in WebAssembly for performance reasons. If compiled with the -cheerp-mode wasmflag, Cheerp will try to compile the entire code to WebAssembly, which cannot directly access the DOM. As a result, you will get this error at compile time:

interop.cpp:7:19: error: Cheerp: Method 'getElementById' of object client::document of non-wasm type 'client::Document' cannot be called in the wasm section
client::document.getElementById("testDiv")->set_textContent(str);
^
interop.cpp:7:46: error: Cheerp: Method 'set_textContent' of object client::document.getElementById("testDiv") of non-wasm type 'client::HTMLElement *' cannot be called in the wasm section
client::document.getElementById("testDiv")->set_textContent(str);
^
2 errors generated.

Fixing this is very easy, the user only needs to add the [[cheerp::genericjs]] tag to the writeMessageToDom function. Changing the signature of the function to something like this:

[[cheerp::genericjs]] void writeMessageToDom(const char* str)

will allow the code to compile correctly.

Other updates in Cheerp 2.0-RC2

Other updates comping with Cheerp 2.0-RC2 are:

  • C++ virtual bases are now supported both in WebAssembly and in JavaScript targets, removing the last unsupported C++ construct in Cheerp.
  • Support for runtime bounds checking in WebAssembly and JavaScript
  • Support for variable length stack arrays in both WebAssembly and JavaScript targets
  • Introduced Identical Code Folding to remove duplicated code in WebAssembly and asm.js
  • New size optimisations for the WebAssembly target

Download

Cheerp 2.0-RC2 is available to download for Linux, Windows and macOS at https://leaningtech.com/cheerp/download/. To get started with Cheerp, please visit the main GitHub project page. You will find instructions on how to download, install and use Cheerp, as well as step-by-step tutorials.

Want to know more?

For more information on how Cheerp, check out our website at https://leaningtech.com/cheerp/. Follow us on twitter (@leaningtech), visit our website, and our main Documentation page for more information.