This implementation has a number of limitations: - Returning a Future from an async function is not supported. - Every async call switches to a new stack. A later optimization will stay on the same stack if the call is directly awaited. - Exceptions that cross async boundaries do not receive full stack traces including the async suspension points. The stack trace of the final exception just reflects the stack trace for the outermost async call. Change-Id: I2a5d5e30d6e955999ba55842c8b2ca3427cbf954 Cq-Include-Trybots: luci.dart.try:dart2wasm-linux-x64-d8-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/241010 Reviewed-by: William Hesse <whesse@google.com> Reviewed-by: Joshua Litt <joshualitt@google.com>
3.6 KiB
Running dart2wasm
You don't need to build the Dart SDK to run dart2wasm, as long as you have a Dart SDK installed.
To compile a Dart file to Wasm, run:
dart --enable-asserts pkg/dart2wasm/bin/dart2wasm.dart
options infile.dart
outfile.wasm
where options include:
Option | Default | Description |
---|---|---|
--dart-sdk= path |
relative to script | The location of the sdk directory inside the Dart SDK, containing the core library sources. |
--platform= path |
none | The location of the platform dill file containing the compiled core libraries. |
-- [no- ]export-all |
no | Export all functions; otherwise, just export main . |
-- [no- ]import-shared-memory |
no | Import a shared memory buffer. If this is on, --shared-memory-max-pages must also be specified. |
-- [no- ]inlining |
no | Inline small functions. |
-- [no- ]lazy-constants |
no | Instantiate constants lazily. |
-- [no- ]name-section |
yes | Emit Name Section with function names. |
-- [no- ]polymorphic-specialization |
no | Do virtual calls by switching on the class ID instead of using call_indirect . |
-- [no- ]print-kernel |
no | Print IR for each function before compiling it. |
-- [no- ]print-wasm |
no | Print Wasm instructions of each compiled function. |
--shared-memory-max-pages pagecount |
Max size of the imported memory buffer. If --shared-import-memory is specified, this must also be specified. |
|
-- [no- ]string-data-segments |
no | Use experimental array init from data segment for string constants. |
--watch offset |
Print stack trace leading to the byte at offset offset in the .wasm output file. Can be specified multiple times. |
The resulting .wasm
file can be run with:
d8 --experimental-wasm-gc --wasm-gc-js-interop --experimental-wasm-stack-switching --experimental-wasm-type-reflection pkg/dart2wasm/bin/run_wasm.js --
outfile.wasm
Imports and exports
To import a function, declare it as a global, external function and mark it with a wasm:import
pragma indicating the imported name (which must be two identifiers separated by a dot):
@pragma("wasm:import", "foo.bar")
external void fooBar(Object object);
which will call foo.bar
on the host side:
var foo = {
bar: function(object) { /* implementation here */ }
};
To export a function, mark it with a wasm:export
pragma:
@pragma("wasm:export")
void foo(double x) { /* implementation here */ }
@pragma("wasm:export", "baz")
void bar(double x) { /* implementation here */ }
With the Wasm module instance in inst
, these can be called as:
inst.exports.foo(1);
inst.exports.baz(2);
Types to use for interop
In the signatures of imported and exported functions, use the following types:
- For numbers, use
double
. - For Dart objects, use the corresponding Dart type. The fields of the underlying representation can be accessed on the JS side as
.$field0
,.$field1
etc., but there is currently no defined way of finding the field index of a particular Dart field, so this mechanism is mainly useful for special objects with known layout. - For JS objects, use the
WasmAnyRef
type (orWasmAnyRef?
as applicable) from thedart:wasm
package. These can be passed around and stored as opaque values on the Dart side.