![Aske Simon Christensen](/assets/img/avatar_default.png)
With the decision to support non-nullable locals in WasmGC as per https://github.com/WebAssembly/function-references/issues/44 the support in dart2wasm for forcing all locals to be nullable is no longer needed. This CL removes that support and cleans up some related nullability issues. Specifically: - Remove the `--local-nullability` and `--parameter-nullability` commandline options. These are now always enabled. - Clean out special cases around forced nullable locals throughout the compiler. - Make `thisLocal` and `preciseThisLocal` always non-nullable. - Make `returnValueLocal` (for storing the return value of `return` statements inside `try` blocks with `finally`) always defaultable, since its initialization flow crosses control constructs. - Make type argument parameters non-nullable. - Make non-nullable `FutureOr` translate to a non-nullable Wasm type. - Implement the "initialized until end of block" validation scheme in the Wasm instruction validator. - Run tests with the `--experimental-wasm-nn-locals` option. This is likely going away soon, but for now we need it. Change-Id: I05873dd70510af5944d86d37cb5765c7bdef73a9 Cq-Include-Trybots: luci.dart.try:dart2wasm-linux-x64-d8-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/252600 Commit-Queue: Aske Simon Christensen <askesc@google.com> Reviewed-by: Joshua Litt <joshualitt@google.com> Reviewed-by: William Hesse <whesse@google.com>
3.7 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- ]nominal-types |
yes | Emit nominal types. |
-- [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. |
-- [no- ]runtime-types |
no | Use RTTs for allocations and casts. |
--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 --experimental-wasm-nn-locals --wasm-gc-js-interop 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.