Flutter Web and WASM
Tags: flutter, javascript, computerscience, productivity
Published: 2020-12-05 07:36:20

*In case it helped :)*
<a href="https://www.buymeacoffee.com/aseemwangoo" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Pass Me A Coffee!!" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>

<!-- wp:paragraph -->
<p><strong><em>Website: </em></strong><a href="https://web.flatteredwithflutter.com/#/" rel="noreferrer noopener" target="_blank"><strong><em>https://web.flatteredwithflutter.com/#/</em></strong></a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We will cover briefly about</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>Precise Intro about WASM</li><li>Web Assembly (WASM) using AssemblyScript</li><li>Integrate with Flutter Web</li></ol>
<!-- /wp:list -->

{% youtube bmgzW_PWFJg %}

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


<!-- wp:heading {"level":4} -->
<h4>Intro to&nbsp;WASM</h4>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><li><strong>WebAssembly</strong> (<strong><em>Wasm</em></strong>) 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.</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>WebAssembly is creating a language that can run as fast as closer to Assembly speeds <strong>but on the Web</strong>.</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>The idea behind WebAssembly is to create a <strong>toolchain</strong> for other programming languages like <strong>C</strong>, <strong>C++</strong>, <strong>Rust</strong>, etc. to compile directly to WebAssembly. This way, <strong>web programmers can write programs in the language of their choice and run inside a browser</strong>.</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Note: WebAssembly file is a binary file of standard WebAssembly instruction, and <strong>should not be written by hand</strong> instead compiled. However, it supports a <strong>Text Format</strong> called <strong>Wat</strong> that can be read by us.</p>
<!-- /wp:paragraph -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://cdn-images-1.medium.com/max/1600/1*bnXT9ADVNjHaCwxFjtWqRA.png" alt="Flutter Web and WASM | Add function in WASM"/><figcaption>Flutter Web and WASM | Add function in&nbsp;WASM</figcaption></figure>
<!-- /wp:image -->

<!-- wp:heading {"level":4} -->
<h4>Web Assembly (WASM) using AssemblyScript</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>There are different ways to write Web Assembly&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","width":422,"height":736} -->
<div class="wp-block-image"><figure class="aligncenter is-resized"><img src="https://cdn-images-1.medium.com/max/1600/1*GEqBBjzWFvtTntukJOa1Vw.png" alt="Flutter Web and WASM | Ways to Write" width="422" height="736"/><figcaption>Flutter Web and WASM | Ways to Write</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

<!-- wp:paragraph -->
<p>In this article, we will write Wasm using <strong>Assembly Script</strong></p>
<!-- /wp:paragraph -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://cdn-images-1.medium.com/max/1600/1*0cKzrmF2XzvUHYuI_gG8wg.png" alt=""/><figcaption>Assembly Script</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>AssemblyScript is&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>TypeScript-to-WebAssembly compiler.</li><li>a limited subset of TypeScript, so it shouldn’t take long to get up to speed.</li><li>similar to JavaScript, AssemblyScript lets web developers easily incorporate into their websites.</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>If you are lazy, you can simply code online using <a href="https://webassembly.studio/" rel="noreferrer noopener" target="_blank"><strong>WebAssembly Studio</strong></a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>or if you prefer installing on our machine,</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">npm i assemblyscript<br>npm install --save @assemblyscript/loader<br>npm install --save-dev assemblyscript</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>For setting up the code structure</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">npx asinit .</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>For running the code (to generate Wasm)</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">npm run asbuild</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>We will write two functions (<strong>addition</strong> and <strong>multiplication</strong>)</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">export function add(a: i32, b: i32): i32 {
  return a + b;
}

export function mult(a: i32, b: i32): i32 {
  return a * b;
}</pre>
<!-- /wp:preformatted -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://cdn-images-1.medium.com/max/1600/1*lWWnlXh-qazXp7-8qxlLXA.png" alt="i32 data type"/><figcaption>i32 data type</figcaption></figure>
<!-- /wp:image -->

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

<!-- wp:paragraph -->
<p>For more data types in web assembly, see below</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p><a href="https://www.assemblyscript.org/types.html" rel="noreferrer noopener" target="_blank">DataTypes in WebAssembly</a></p></blockquote>
<!-- /wp:quote -->

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

<!-- wp:paragraph -->
<p>After building the code, using <code>npm run asbuild</code> we see the following files generated</p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://cdn-images-1.medium.com/max/1600/1*Crcvx_9OWqCVOu4IURfKyA.png" alt="Flutter Web and WASM"/><figcaption>Flutter Web and&nbsp;WASM</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>We are interested in the <code>.wasm</code> binary.</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note:&nbsp;<code>.wat</code> is a human-readable format for the&nbsp;<code>.wasm</code> binary</p></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p>In case, you want to decode this <code><em>.wasm</em></code> binary, <a rel="noreferrer noopener" href="https://wasdk.github.io/wasmcodeexplorer/" target="_blank">refer to this</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>Integrate with Flutter&nbsp;Web</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We will add the&nbsp;<code>.wasm</code> generated above in our assets.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>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.</p>
<!-- /wp:paragraph -->

{% link https://dev.to/aseemwangoo/flutter-web-and-location-2l1 %}

<!-- wp:paragraph -->
<p>But during my research, I found a <strong>package (</strong><a rel="noreferrer noopener" href="https://pub.dev/packages/wasm_interop" target="_blank"><strong>wasm_interop</strong></a><strong>) </strong>that does all the JS interactions for us.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Step1:&nbsp;</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Let’s create an abstract class for Wasm called <strong>WasmContract</strong>.</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">abstract class WasmContract {
  WasmContract.loadFromAsset(String path);
  Future&lt;bool> initialized();
  Object callfunc(String name, List&lt;int> input);
  bool get isLoaded;
}</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p><strong>Step2:</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Now, we create <strong>WasmLoader</strong> class which extends the <strong>WasmContract.</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>In the initialized function, we load the wasm file from the asset</li></ul>
<!-- /wp:list -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">final bytes = await rootBundle.load(_path);
_wasmInstance = await Instance.fromBufferAsync(bytes.buffer);</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>What happens under the hood?</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>JavaScript API has a global <code>WebAssembly</code> object available in the browser.</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>This object has the following static methods:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate" rel="noreferrer noopener" target="_blank">WebAssembly.instantiate()</a>: </code>Compile and instantiate bytes at the same time.</li><li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming" rel="noreferrer noopener" target="_blank">WebAssembly.instantiateStreaming()</a>:</code> Same functionality as instantiate(), but uses streaming to compile and instantiate the module, which eliminates an intermediate step of converting the&nbsp;.wasm bytes into an ArrayBuffer.</li><li><code>Instance.fromBufferAsyc</code> is a wrapper for<code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming" rel="noreferrer noopener" target="_blank">WebAssembly.instantiateStreaming()</a></code> coming from the <a href="https://pub.dev/packages/wasm_interop" rel="noreferrer noopener" target="_blank"><strong>wasm_interop</strong></a></li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Step3:</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We override the callfunc (from WasmContract) by</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">@override
Object callfunc(String name, List&lt;int> input) {
  final _func = _wasmInstance.functions[name];
  return _func.call(input.first, input.last);
}</pre>
<!-- /wp:preformatted -->

<!-- wp:list -->
<ul><li>Here, <code>name</code> is the function name defined in our Wasm (<code>add and mult</code>)</li><li>We use the&nbsp;<code>.functions</code>, which returns an <a href="https://pub.dev/documentation/wasm_interop/latest/wasm_interop/ExportedFunction-class.html" rel="noreferrer noopener" target="_blank"><strong>ExportedFunction</strong></a></li><li>Finally, we invoke the function (<code>.call</code>)passing the params (which are 2 in our case)</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Last Step:</strong></p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center"} -->
<div class="wp-block-image"><figure class="aligncenter"><img src="https://cdn-images-1.medium.com/max/1600/1*m4ZcpFYS0gsqLwzNRYa42A.png" alt="Flutter Web and WASM"/><figcaption>Flutter Web and WASM</figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>We have 2 buttons on the front end. Load the wasm module first</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">Future&lt;void&gt; _init() async {<br>   loader = WasmLoader.loadFromAsset(WebAssets.wasmOps);<br>   final isLoaded = await loader.initialized(); <br>}</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>for calling the functions, we use <code>.callFunc</code> Pass in the function name and the list of params.</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">// 'add' is the function defined in our wasm
void _addition(List&lt;int> input) {
  _sum = loader.callfunc('add', [1, 3]) as double;
}

// 'mult' is the function defined in our wasm
void _multiply(List&lt;int> input) {
  _mult = loader.callfunc('mult', [3, 3]);
}</pre>
<!-- /wp:preformatted -->


*In case it helped :)*
<a href="https://www.buymeacoffee.com/aseemwangoo" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Pass Me A Coffee!!" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>

{% youtube bmgzW_PWFJg %}

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Hosted URL&nbsp;: <a href="https://web.flatteredwithflutter.com/#/" rel="noreferrer noopener" target="_blank">https://web.flatteredwithflutter.com/#/</a></p></blockquote>
<!-- /wp:quote -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p><a href="https://github.com/AseemWangoo/experiments_with_web" rel="noreferrer noopener" target="_blank">Source code for Flutter Web App..</a></p></blockquote>
<!-- /wp:quote -->