WebAssembly output (wasm or wast mode)

Alessandro Pignotti edited this page Jan 18, 2018 · 5 revisions

Generate WebAssembly output

Setting the command line flag -cheerp-mode=wasm lets Cheerp generate binary WebAssembly output. The produced binary output.wasm is a standalone WebAssembly module and requires a JavaScript loader to run in a browser. The corresponding loader can be generated using the flag -cheerp-wasm-loader=loader.js.

/opt/cheerp/bin/clang++ \
  -target cheerp \
  -cheerp-mode=wasm \
  -cheerp-linear-heap-size=128 \
  -cheerp-wasm-loader=loader.js \
  -o output.wasm \
  input.cpp

The command above will generate a binary WebAssembly module output.wasm and a corresponding JavaScript loader loader.js from the C++ source file input.cpp.

The loader JS file will by default load the WASM module using the same path specified in the -o option. You can also use the -cheerp-wasm-file option to manually specify the URL where the WASM file is deployed.

Note: when -cheerp-wasm-loader is omitted and FFI calls (e.g. external or JavaScript functions) are used in the module, Cheerp will emit unreachable instructions at the position where the FFI function should have been called.

For debugging purposes, human-readable WebAssembly output can be generated using -cheerp-mode=wast.

WebAssembly heap size

Since WebAssembly uses linear memory with a certain size, the heap size can be set using -cheerp-linear-heap-size=128. The unit of the -cheerp-linear-heap-size is megabytes, and when omitted defaults to 1 megabyte.

Using DOM APIs

From WebAssembly it is not possible to call any DOM APIs, not even the basic client::console.log. Cheerp provides automatic generation of FFI/code bridges to indirectly use DOM API though. As an example take the following code.

#include <cheerp/clientlib.h>

[[cheerp::genericjs]] int domOutput(const char* str)
{
    client::String* s = new client::String(str);
    client::console.log(s);
    // Also add it to the DOM for good measure
    client::document.get_body()->set_textContent(s);
    return s->get_length();
}

void webMain()
{
    int len = domOutput("Hello WASM!");
    assert(len == 11);
}

Using cheerp::jsexport in combination with WebAssembly

[[cheerp::jexport]] makes it possible to expose C++ classes and functions to JS. (See here for details on jsexport). It is still possible to use it when enabling Wasm output, but it is only supported on classes tagged with the [[cheerp::genericjs]] attribute. This means that code compiled to Wasm needs to be exposed from a genericjs class.

As the loading of the Wasm module must be asynchronous it is also necessary to wait for the completion of the process before using jsexport-ed code. To achieve this Cheerp expose a promise property in every jsexport-ed class and function. The promise can be use to know when the code is eventually ready to run.

class [[cheerp::jsexport]] [[cheerp::genericjs]] JsStruct
{
private:
        float a;
        int b;
public:
        JsStruct(float _a, int _b):a(_a),b(_b)
        {
        }
        void test()
        {
                client::console.log("Invoked test");
        }
};
JsStruct.promise.then(function(){
        var obj = new JsStruct();
        obj.test();
});
Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.