Opened on 10/17/2018 at 03:19:43 PM

Closed on 08/29/2019 at 05:43:52 PM

Last modified on 10/08/2019 at 06:06:08 PM

#7058 closed change (rejected)

Write WebAssembly module loader

Reported by: mjethani Assignee:
Priority: Unknown Milestone:
Module: Core Keywords: closed-in-favor-of-gitlab
Cc: sergz, sebastian, kzar, hfiguiere, greiner Blocked By:
Blocking: Platform: Unknown / Cross platform
Ready: no Confidential: no
Tester: Unknown Verified working: no
Review URL(s):

Description (last modified by mjethani)

Background

We would like to start moving some of our code to WebAssembly if and where possible as we run into our limits of what we can do with pure JavaScript (#7000). This would be somewhat in parallel to the Emscripten effort, but could also be seen as a way to gradually migrate to that implementation over time. In any case, the lessons learnt from the Emscripten effort would come in handy in this piecemeal migration.

The first step for doing this is to have a loader that can load a WebAssembly version of a module on platforms that support it and automatically fall back to a pure JavaScript implementation otherwise, based on a mapping somewhere. This mapping could be in the build script, for example, or it could be hardcoded into the source of the module.

These days it's easy to load a WebAssembly module using a few lines of JavaScript:

<script>
  function loadModule(path)
  {
    return fetch(`${path}.wasm`).then(response => response.arrayBuffer())
           .then(bytes => WebAssembly.instantiate(bytes))
           .then(object => object.instance.exports);
  }

  loadModule("simple").then(({add}) =>
  {
    console.log(add(1, 2)); // prints 3
  });
</script>

It would be easy to modify the above implementation to fall back to require'ing the pure JavaScript version of the module if the .wasm file is not found or if WebAssembly is not supported on the platform, while keeping it transparent to client code.

It is also trivial these days to write WebAssembly, even by hand:

;; simple.wat

(module
  (func (export "add") (param i32) (param i32) (result i32)
    get_local 0
    get_local 1
    i32.add
  )
)

This can be compiled to a WebAssembly binary using WABT:

wat2wasm -o simple.wasm simple.wat

There are higher-level languages and frameworks being built around this (e.g. Walt). The web is no longer so tightly coupled with JavaScript.

As a first step, we need a WebAssembly module loader that falls back to alternative pure JavaScript implementations based on certain criteria.

Compatibility

(What versions of Chrome, Firefox, and Edge is WebAssembly supported on? What are the details we need to know before we start work? To be filled out.)

What to change

To be determined.

Attachments (0)

Change History (17)

comment:1 Changed on 10/17/2018 at 03:21:20 PM by mjethani

  • Description modified (diff)

comment:2 Changed on 10/17/2018 at 03:24:48 PM by mjethani

  • Description modified (diff)

comment:3 Changed on 10/17/2018 at 03:25:47 PM by mjethani

  • Cc sergz sebastian kzar hfiguiere added

comment:4 Changed on 10/17/2018 at 03:26:14 PM by mjethani

  • Description modified (diff)

comment:5 Changed on 10/17/2018 at 03:46:58 PM by hfiguiere

Issue #6312 is for the emscripten branch

comment:6 Changed on 10/17/2018 at 03:48:52 PM by hfiguiere

Support matrix:
https://developer.mozilla.org/en-US/docs/WebAssembly

No IE, Edge 16, Chrome 57, Firefox 52

comment:7 Changed on 10/17/2018 at 03:49:17 PM by mjethani

  • Blocking 7000 added

comment:8 Changed on 10/17/2018 at 03:49:47 PM by hfiguiere

Also we don't need C++ to write wasm code. We can do it in Rust.

comment:9 follow-up: Changed on 10/17/2018 at 04:00:29 PM by mjethani

Based on the little that I know about Rust, I would very much prefer it over C++.

comment:10 in reply to: ↑ 9 ; follow-up: Changed on 10/17/2018 at 04:31:58 PM by mjethani

Replying to mjethani:

Based on the little that I know about Rust, I would very much prefer it over C++.

Seriously though, there are two things we would have to consider:

  1. Skills: Do we have the skills in the team? Anybody can write a "Hello world" program in Rust, but it takes a long time to master a language. In order to get the best out of it, one really must grok it. We have some very skilled C++ programmers on the team with lots of experience.
  2. Performance: If we're going to adopt WebAssembly as a target for performance reasons, we should try to get the best tradeoff between performance and maintainability. The question is whether Rust can be compiled to WebAssembly bytecode as optimally as C++.

comment:11 in reply to: ↑ 10 Changed on 10/17/2018 at 04:47:38 PM by hfiguiere

Replying to mjethani:

The question is whether Rust can be compiled to WebAssembly bytecode as optimally as C++.

Yes.

comment:12 Changed on 10/18/2018 at 11:50:45 PM by mjethani

This will actually have to be part of buildtools. We will need a custom webpack loader that loads the WebAssembly version of a given module if it's available and fall back on the JavaScript version otherwise. The WebAssembly binary would be included in the generated lib/adblockplus.js by the build script as a byte array.

We need to work out the details.

comment:13 Changed on 10/19/2018 at 03:48:46 PM by hfiguiere

I think we could start by doing it for the emscripten branch, and then we can move that patch to the main branch when needed/wanted.

comment:14 Changed on 10/23/2018 at 11:38:38 AM by mjethani

  • Blocking 7000 removed

comment:15 Changed on 03/08/2019 at 05:32:58 PM by greiner

  • Cc greiner added

comment:16 Changed on 05/16/2019 at 07:36:13 AM by Himanshu0709

spam

Last edited on 10/08/2019 at 06:06:08 PM by kzar

comment:17 Changed on 08/29/2019 at 05:43:52 PM by sebastian

  • Keywords closed-in-favor-of-gitlab added
  • Resolution set to rejected
  • Status changed from new to closed

Sorry, but we switched to GitLab. If this issue is still relevant, please file it again in the new issue tracker.

Add Comment

Modify Ticket

Change Properties
Action
as closed .
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from (none).
 
Note: See TracTickets for help on using tickets.