dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.31k stars 1.59k forks source link

Compile Dart to Wasm #32894

Closed listepo-alterpost closed 6 months ago

listepo-alterpost commented 6 years ago

It would be very cool to add support for the WebAssembly


Admin comment: For current status, see https://dart.dev/web/wasm

liudonghua123 commented 2 years ago

@liudonghua123 Dart SDK version: 2.19.0-374.1.beta (beta) dartaotruntime path-to-sdk/bin/snapshots/dart2wasm_product.snapshot -h

I see, I need to use beta channel currently. Is there any release roadmap about dart?

askeksa-google commented 2 years ago

I always got Error when reading 'pkg/dart2wasm/bin/dart2wasm.dart': No such file or directory. errors.

You need to run the command in a checkout of the SDK repository.

Added a clarification to the text: https://dart-review.googlesource.com/c/sdk/+/271881

ykmnkmi commented 2 years ago

@askeksa-google I'm trying to run WASM module in the browser, but I got error like this CompileError: wasm validation error: at offset 13.

askeksa-google commented 1 year ago

@askeksa-google I'm trying to run WASM module in the browser, but I got error like this CompileError: wasm validation error: at offset 13.

The Wasm extensions we depend on for running Wasm code produced by dart2wasm are still experimental and in flux. The experimental instructions indicate how such a Wasm file can be run using d8, but this way of running it will also change and will sometimes only work on specific version ranges of d8.

dxvid-pts commented 1 year ago

Updates: https://twitter.com/kevmoo/status/1600973667638607872

Keithcat1 commented 1 year ago

Will Dart support WASI? It'd be able to run anywhere there's a WASM runtime like Wasmer or Wasmtime, maybe one day users can just download one .wasm file and not have to worry about the getting the wrong platform / architecture.

jodinathan commented 1 year ago

@mraleph

You could build a dialect of Dart which eliminates hidden allocations and allows you to manage memory manually

How so?
For clarification, do you have any examples please?

ykmnkmi commented 1 year ago

@jodinathan look at Vala lang. Compiles to C. Reference counting.

StEvUgnIn commented 1 year ago

This developer @NachoBrito actually shows that Dart needs to focus on Webassembly instead of JavaScript. JS Interop needs work to support the new HTML5 APIs: https://github.com/NachoBrito/flutter-multiapp-poc/blob/main/component1/web/js/interop.js

unicomp21 commented 1 year ago

Will dart webassembly support using the upcoming tail call support? My reason for asking. Looking at the "out of order execution" supported by modern cpu's, will tail call's essentially allow us to await cache line misses? And run something else in the meantime where the cache lines have been loaded?

kevmoo commented 1 year ago

Will dart webassembly support using the upcoming tail call support? My reason for asking. Looking at the "out of order execution" supported by modern cpu's, will tail call's essentially allow us to await cache line misses? And run something else in the meantime where the cache lines have been loaded?

@askeksa-google ?

askeksa-google commented 1 year ago

Will dart webassembly support using the upcoming tail call support? My reason for asking. Looking at the "out of order execution" supported by modern cpu's, will tail call's essentially allow us to await cache line misses? And run something else in the meantime where the cache lines have been loaded?

The tail call instructions are just fused call-and-return instructions that pop the caller's stack frame before pushing the callee's stack frame. While this is a useful primitive in some coroutine implementations, the tail call instructions do not by themselves confer any capability to suspend and resume the execution of a function body. Such capabilities are being discussed as part of the Stack Switching Proposal.

Dart has the sync* feature for writing generator functions, which have the capability to be suspended and resumed somewhat similarly to what you suggest. The current implementation of these in the Wasm backend (and in the other backends as well) has some significant overhead associated with it, though, mainly from having to keep the local state of the function alive in heap objects across suspension points. A future Wasm-level stack switching feature could potentially reduce some of that overhead.

unicomp21 commented 1 year ago

@askeksa-google I'm confused. Why are the leaningtech guys realizing large performance boosts by having tail calls?

https://leaningtech.com/extreme-webassembly-2-the-sad-state-of-webassembly-tail-calls/ https://leaningtech.com/fantastic-tail-calls-and-how-to-implement-them/

askeksa-google commented 1 year ago

Maybe I misunderstood what you wanted to do with the tail calls. It's certainly feasible to add an option to emit tail calls whenever the result of a call is directly returned. This will make stack traces different from what would be expected from the Dart source, but this is already the case for other optimizations, such as inlining.

It may indeed improve performance in some cases. I don't see what it has to do with hiding cache misses, though.

unicomp21 commented 1 year ago

@askeksa-google In talking w/ some of the redpanda engineers, my understanding is c++ co_await essentially makes cache line misses "await'able". Another strand/coroutine can be resumed where the cache line has been loaded.

Per Gor, tail calls are required in order to support co_await in webassembly. I'm wondering if dart await can perform as efficiently as c++ co_await, in webassembly?

https://www.youtube.com/watch?v=_fu0gx-xseY&t=11s

liudonghua123 commented 1 year ago

flutter 3.10 and dart 3.0 is released with some wasm support, how can I compile dart code to wasm in 2023?

I also noticed https://pub.dev/packages/wasm, but it is about loading wasm module in dart, not compile dart code to wasm module.

kevmoo commented 1 year ago

@liudonghua123 we're not ready to release things beyond preview.

Keep in mind, all of the runtime support for WasmGC is also in preview.

https://flutter.dev/wasm has the latest details

liudonghua123 commented 1 year ago

@liudonghua123 we're not ready to release things beyond preview.

Keep in mind, all of the runtime support for WasmGC is also in preview.

https://flutter.dev/wasm has the latest details

Thanks, I also found some docs on https://github.com/dart-lang/sdk/tree/main/pkg/dart2wasm.

iapicca commented 1 year ago

@kevmoo will the "final" version of the feature require d8 as it does now?

kevmoo commented 1 year ago

@iapicca – "final" is tricky to define. We'll certainly need a runtime that supports WasmGC. It's possible we may make our first release require a JS runtime as well, since we're VERY focused on the Flutter+Browser scenario. Our support will certainly evolve, though. I'd love to think we'd run on most Wasm runtimes (as long as they support GC), but that's not our focus now or in the near future.

nex3 commented 1 year ago

I'm also extremely interested in a more portable WASM output. Requiring GC is totally understandable, but it's very important for our use-cases that we be able to integrate with as many WASM runtimes as possible—even if it means using a much lower-level API to communicate out.

iapicca commented 1 year ago

@kevmoo I was attempting to make a dart package to use fermyon spin, but this is kinda of a blocker I understand a true dart2wasm compilation is blocked by wasmGC, I just hope that once is out we don't keep depending on flutter related approaches kneecapping any possible "pure dart" implementation

mit-mit commented 11 months ago

We've now landed new support in the dart cli for invoking the dart 2 wasm compiler in the Dart and Flutter main channels:

$ dart help compile wasm
Compile Dart to a WebAssembly/WasmGC module (EXPERIMENTAL).

Usage: dart compile wasm [arguments] <dart entry point>
-h, --help              Print this usage information.
-o, --output            Write the output to <file name>.
                        This can be an absolute or relative path.
    --[no-]optimize     Optimize wasm output using Binaryen wasm-opt.
                        (defaults to on)
-v, --verbose           Print debug output during compilation
    --enable-asserts    Enable assert statements.

I have a small example of how this can be used for a Dart web app here: https://github.com/mit-mit/sandbox/tree/main/demos/webwasm

Note that this is still within our initial focus of using WasmGC in the context of web apps (whether Flutter web apps or general ones). Over time we'd like to support more general WasmGC execution -- this issue tracks some of the additional work required for that: https://github.com/dart-lang/sdk/issues/53884

liudonghua123 commented 6 months ago

It seems I can compile dart to wasm with dart 3.4.0.

Liu.D.H  dart2wasm-hello   7ms  15:37 > cat > hello.dart
void main() {
  print("Hello, World!");
}

Liu.D.H  dart2wasm-hello   17.767s  15:38 > dart hello.dart
Hello, World!

Liu.D.H  dart2wasm-hello   3.995s  15:38 > dart --version
Dart SDK version: 3.4.0 (stable) (Mon May 6 07:59:58 2024 -0700) on "windows_x64"

Liu.D.H  dart2wasm-hello   1.434s  15:38 >
Liu.D.H  dart2wasm-hello   337ms  15:39 > dart help compile wasm
Compile Dart to a WebAssembly/WasmGC module (EXPERIMENTAL).

Usage: dart compile wasm [arguments] <dart entry point>
-h, --help                  Print this usage information.
-o, --output                Write the output to <file name>.
                            This can be an absolute or relative path.
-v, --verbose               Print debug output during compilation
    --enable-asserts        Enable assert statements.
-D, --define=<key=value>    Define an environment declaration. To specify multiple declarations, use multiple options or
                            use commas to separate key-value pairs.
                            For example: dart compile wasm -Da=1,b=2 main.dart

Run "dart help" to see global options.

Liu.D.H  dart2wasm-hello   2.156s  15:40 > dart compile wasm hello.dart -o hello.wasm
*NOTE*: Compilation to WasmGC is experimental.
The support may change, or be removed, with no advance notice.

Generated wasm module 'hello.wasm', and JS init file 'hello.mjs'.

Liu.D.H  dart2wasm-hello   9.375s  15:41 >

But I can't run it with wasmer or wasmedge.

Liu.D.H  dart2wasm-hello   16ms  15:43 > node hello.mjs

Liu.D.H  dart2wasm-hello   1.027s  15:43 > wasmer hello.unopt.wasm
error: Unable to compile "hello.unopt.wasm"
╰─▶ 1: compile error

Liu.D.H  dart2wasm-hello   39ms  15:44 > wasmedge hello.wasm
[2024-05-21 15:44:21.194] [error] loading failed: integer representation too long, Code: 0x36
[2024-05-21 15:44:21.197] [error]     Bytecode offset: 0x0000000c
[2024-05-21 15:44:21.198] [error]     At AST node: function type
[2024-05-21 15:44:21.199] [error]     At AST node: type section
[2024-05-21 15:44:21.199] [error]     At AST node: module
[2024-05-21 15:44:21.200] [error]     File name: "D:\\code\\dart\\dart2wasm-hello\\hello.wasm"

Liu.D.H  dart2wasm-hello   385ms  15:44 > wasmer hello.wasm
error: Unable to compile "hello.wasm"
╰─▶ 1: compile error

Liu.D.H  dart2wasm-hello   36ms  15:44 >
iapicca commented 6 months ago

It seems I can compile dart to wasm with dart 3.4.0.

[...]

But I can't run it with wasmer or wasmedge.

@liudonghua123 because compile only to wasm js runtime see

yanglaolee commented 6 months ago

Wen dart to wasm runtime??

--2024.05.23

mit-mit commented 6 months ago

This feature is now considered done. There are some planned improvements outside the core though. For current status, please see https://dart.dev/web/wasm

mkustermann commented 6 months ago

For those looking for future things