DEV Community

Cover image for Flutter Web and WASM
aseem wangoo
aseem wangoo

Posted on

Flutter Web and WASM

In case it helped :)
Pass Me A Coffee!!

Website: https://web.flatteredwithflutter.com/#/

We will cover briefly about

  1. Precise Intro about WASM
  2. Web Assembly (WASM) using AssemblyScript
  3. Integrate with Flutter Web

Article here: https://flatteredwithflutter.com/flutter-web-wasm/

Intro to WASM

  • WebAssembly (Wasm) is inspired by the Assembly language. Assembly language is the lowest form of text-based human-readable language which generates optimized fast programs in machine code.

WebAssembly is creating a language that can run as fast as closer to Assembly speeds but on the Web.

  • The idea behind WebAssembly is to create a toolchain for other programming languages like C, C++, Rust, etc. to compile directly to WebAssembly. This way, web programmers can write programs in the language of their choice and run inside a browser.

Note: WebAssembly file is a binary file of standard WebAssembly instruction, and should not be written by hand instead compiled. However, it supports a Text Format called Wat that can be read by us.

Flutter Web and WASM | Add function in WASM
Flutter Web and WASM | Add function in WASM

Web Assembly (WASM) using AssemblyScript

There are different ways to write Web Assembly 

Flutter Web and WASM | Ways to Write
Flutter Web and WASM | Ways to Write

In this article, we will write Wasm using Assembly Script

Assembly Script

AssemblyScript is 

  • TypeScript-to-WebAssembly compiler.
  • a limited subset of TypeScript, so it shouldn’t take long to get up to speed.
  • similar to JavaScript, AssemblyScript lets web developers easily incorporate into their websites.

If you are lazy, you can simply code online using WebAssembly Studio

or if you prefer installing on our machine,

npm i assemblyscript
npm install --save @assemblyscript/loader
npm install --save-dev assemblyscript

For setting up the code structure

npx asinit .

For running the code (to generate Wasm)

npm run asbuild

We will write two functions (addition and multiplication)

export function add(a: i32, b: i32): i32 {
  return a + b;
}

export function mult(a: i32, b: i32): i32 {
  return a * b;
}

i32 data type
i32 data type


For more data types in web assembly, see below

DataTypes in WebAssembly


After building the code, using npm run asbuild we see the following files generated

Flutter Web and WASM
Flutter Web and WASM

We are interested in the .wasm binary.

Note: .wat is a human-readable format for the .wasm binary

In case, you want to decode this .wasm binary, refer to this.

Integrate with Flutter Web

We will add the .wasm generated above in our assets.

As we know that, we can call Javascript functions inside the Flutter Web, we will utilize this feature. In case you don’t read this.

But during my research, I found a package (wasm_interop) that does all the JS interactions for us.

Step1: 

Let’s create an abstract class for Wasm called WasmContract.

abstract class WasmContract {
  WasmContract.loadFromAsset(String path);
  Future<bool> initialized();
  Object callfunc(String name, List<int> input);
  bool get isLoaded;
}

Step2:

Now, we create WasmLoader class which extends the WasmContract.

  • In the initialized function, we load the wasm file from the asset
final bytes = await rootBundle.load(_path);
_wasmInstance = await Instance.fromBufferAsync(bytes.buffer);

What happens under the hood?

  • JavaScript API has a global WebAssembly object available in the browser.

This object has the following static methods:

Step3:

We override the callfunc (from WasmContract) by

@override
Object callfunc(String name, List input) {
  final _func = _wasmInstance.functions[name];
  return _func.call(input.first, input.last);
}
  • Here, name is the function name defined in our Wasm (add and mult)
  • We use the .functions, which returns an ExportedFunction
  • Finally, we invoke the function (.call)passing the params (which are 2 in our case)

Last Step:

Flutter Web and WASM
Flutter Web and WASM

We have 2 buttons on the front end. Load the wasm module first

Future<void> _init() async {
loader = WasmLoader.loadFromAsset(WebAssets.wasmOps);
final isLoaded = await loader.initialized();
}

for calling the functions, we use .callFunc Pass in the function name and the list of params.

// 'add' is the function defined in our wasm
void _addition(List<int> input) {
  _sum = loader.callfunc('add', [1, 3]) as double;
}

// 'mult' is the function defined in our wasm
void _multiply(List<int> input) {
  _mult = loader.callfunc('mult', [3, 3]);
}

In case it helped :)
Pass Me A Coffee!!

Hosted URL : https://web.flatteredwithflutter.com/#/

Source code for Flutter Web App..

Top comments (0)