Wasm for web
SushantChandla opened this issue ยท 13 comments
I Was wondering if it is possible to add web support to wasm someway (it uses ffi so assuming it will not support web),
or maybe have source_gen generate interop with something like wasm_interop for web.
This could help package developers as they will not have to maintain 2 packages(package using ffi and package using js interop) and also having just a single file binary file to read from unlike for the ffi would be great!
That's definitely what we plan to do, but I can't give you an ETA at the moment.
As the author of wasm_interop, I second that.
The immediate issue is the difference between JS and Wasmer API designs.
Hopefully we can abstract away the API differences.
It's mainly just a question of prioritization. Since this is considered an experimental package, and we don't know how many users we're going to have until we publish, web support wasn't prioritized (especially since we basically have to re-implement the whole package for JS). But the more people request this feature, the sooner we'll start working on it.
I'm curious @lexaknyazev do you see these API design differences an insurmountable? Does this package need to end up as package:wasmer if so (e.g. would the API need to change significantly to eventually accommodate js compat)?
Before making any suggestions, I'd list a few outstanding issues:
- JS API strongly favors async compilation and instantiation. Some browsers refuse to compile large modules synchronously.
- In JS environment, WebAssembly's
i64
type is mapped tobigint
which is a built-in type in JS. Dart'sBigInt
is always emulated when compiled to JS, so I had to add another interop layer. It would be great to enhance the language and the SDK as proposed here. - WebAssembly JS API does not yet have runtime type information (it's WIP), i.e. an application cannot get signatures of functions or types of globals.
Thanks for the info. Async compilation is also on our todo list. Sounds like we should implement that first.
I'm curious @lexaknyazev do you see these API design differences an insurmountable? Does this package need to end up as package:wasmer if so (e.g. would the API need to change significantly to eventually accommodate js compat)?
Here are my initial thoughts on this after reading through the sources of this package.
- The Wasmer API (with all its structs and pointers) is tailored to native apps, while the JS API is web-first (with strings and plain JS objects).
- This package is heavily tied to Wasmer and Dart native FFI. Neither of these is needed or relevant on the web. Users that target only the web shouldn't be required to install Rust SDK, clang, etc.
- The
wasm_interop
package was designed to provide a very thin Dart-like layer over the existing browser API โ it fits into a single source file and does almost nothing (except type coercion) while exposing as many WebAssembly features as currently possible on stable browser versions (e.g. reference types). On the other hand, it cannot perform certain validations that exist in Wasmer, such as checking signatures of the imported functions, because the corresponding JS API is not broadly available yet.
WDYT?
Web users won't use wasmer or FFI or have to install rust (they probably won't even need to run the setup script). Dart packages support conditional importing, so for web we'll have an alternative implementation similar wasm_interop.
The key is that the web implementation will have exactly the same interface, so theoretically users shouldn't notice the difference. So the question is whether the JS API is so different that we will run into problems trying to squeeze it into the package:wasm interfaces. From our discussion so far I don't see any such issues (other than async compilation).
So the question is whether the JS API is so different that we will run into problems trying to squeeze it into the package:wasm interfaces. From our discussion so far I don't see any such issues (other than async compilation).
Sure, nothing insurmountable here. In the order of decreasing importance, I'd list the differences as:
- Async compilation and instantiation.
- 64-bit integers support via BigInt.
- More precise error handling: single
WasmError
class vsWebAssembly.CompileError
,WebAssembly.LinkError
,WebAssembly.RuntimeError
, and occasionalTypeError
on the web.
All of these (except some edge cases related to TypeError
interception) are supported in wasm_interop
, so package:wasm
could use it as a backend.
Not sure if this is useful or not, but since a few days ago Wasmer (in Rust) can be compiled to Javascript.
wasmerio/wasmer#2460
We are working on an article showcasing how to use it.
What this implies, is that if necessary even dart-lang/wasm could be eventually be compiled (with your current same syntax) to js :)
While I don't know the INS and outs of this, I've had the need to use C libraries recently. Adding an automated tool, like ffi gen augmented with maybe behind the hood emscript to have automatic binding for both Web and mobile would be an extremely appealing feature. To me that sounds like a game changer in positioning dart as a language that works well with other languages.
Let me give some use cases:
-
anything cryptography oriented really, there are good c libraries out there that cannot be used on the web but can be compiled to wasm. I did use ffi and the Js to load the wasm for some small features but this is way too painful to be part of any workflow.
-
encoding decoding of various file types
-
audio analysis
-
dart-lang/mime for example is an official dart repository that's somewhat unmaintained. There are already C libraries doing that that could be used
Not to mention all the dev time that go in this problem could instead be channeled here, but that might be wishful thinking
Bump. I was thinking of using Flutter for app UI and WASM for logic specifically to have it work on both web and desktop... any news?
I'm still working on properly supporting iOS. I haven't started on web support yet, but that will come next.