Module Transformation
What is Module Transformation and Why is it Necessary?
In the Browser-based Hello World example, we call a Wasm module called as-echo
that does nothing more than receive a text string as an argument, and echo it back via standard out.
In this case, the values passed from WebAssembly to the native "OS" function (that writes to standard out) are all compatible with JavaScript data types. However, some WASI modules might contain function calls whose interfaces are not compatible, and therefore, such modules cannot immediately be called.
64-bit Integers
The real issue here centers on transferring 64-bit integers between the two runtime environments.
Both JavaScript and WebAssembly use this data type (known as i64
in WebAssembly and BigInt
in JavaScript); but for a variety of reasons, the transfer of this data type has not yet been implemented and is still at the proposal stage. (See here and here for details).
Remember, in the context of a JavaScript program, the WASI bridge between WebAssembly and native "OS" functions has been implemented using a set of JavaScript polyfills. Consequently, you will experience this problem if you try for example to invoke a WebAssembly module that then invokes a native "OS" function such as clock_time_get.
As a temporary fix, this data transfer issue is solved by the @wasmer/wasm-transformer
package.
How Do I Know if a Wasm Module Needs Transformation?
Good question!
Normally, you would discover what data types a native "OS" function interface uses by looking at the well-written interface documentation for the WebAssembly module.
Ok, back in reality...
The clock_time_get
WebAssembly Module
clock_time_get
WebAssembly ModuleIn order to understand whether or not this module needs transformation, we need to take a look inside the WebAssembly module.
Aside
We make no attempt to teach you WebAssembly here!
If you want to know about the inner workings of a WebAssembly module, then please visit the WebAssembly.org website and read the documentation there.
We now continue with your scheduled program...
When converted to WebAssembly Text format, the first few lines look like this:
On line 2, we can see the declaration of a type definition called $t0
. This type definition represents the interface to some func
tion that takes three, signed integers as parameters and returns a signed integer.
Notice the data type of the second parameter. Uh oh! Its an i64
; that is, a 64-bit, signed integer!
So now we know that somewhere in this WebAssembly module, there is a call to function that uses this interface declaration.
Next, look a little further down to line 5. Here we can see an import
statement.
This import
statement tells us several things:
This Wasm module needs to call an external function.
In this particular case, this is a native "OS" function accessible through WASI
The native "OS" function is called
clock_time_get
and lives in an external library calledwasi_unstable
Within our WebAssembly module, this external function will be referred to using the alias
$wasi_unstable.clock_time_get
The interface to this function is described by the type declaration
$t0
We know from the definition of $t0
(on line 2) that this function must be passed an i64
as its second parameter; therefore, we can be certain that before this Wasm module can call function clock_time_get
(using the Wasmer-js polyfill), the interface must first be transformed.
Last updated