tree: d49385574850be001ffe3a5bcba4a4f7f76ea021 [path history] [tgz]
  1. bin/
  2. docs/
  3. lib/
  4. tool/
  5. analysis_options.yaml
  6. OWNERS
  7. pubspec.yaml
  8. README.md
pkg/dart2wasm/README.md

Compiling Dart to WebAssembly (internal SDK developer notes)

This page contains notes for how to compile to WebAssembly for SDK contributors. If you are a Dart developer, using a prebuilt Dart SDK, please refer to the regular documentation.

Note: This feature is under active development, and is currently considered experimental. The tracking issue is #32894.

Running dart2wasm as an SDK contributor

You don't need to build the Dart SDK to run dart2wasm, as long as you have a Dart SDK installed and have the Dart SDK repository checked out. NB: the SDK must be checked out using depot tools and not just cloned from this repo.

To compile a Dart file to Wasm, in a checkout of the Dart SDK repository, run:

dart --enable-asserts pkg/dart2wasm/bin/dart2wasm.dart <options> <input file>.dart <output file>.wasm

Compiler options

OptionDefaultDescription
--dart-sdk=pathrelative to scriptThe location of the sdk directory inside the Dart SDK, containing the core library sources.
--platform=pathnoneThe location of the platform dill file containing the compiled core libraries.
--depfile=pathnoneWrite a Ninja depfile listing the input sources for the compilation.
--[no-]enable-assertsnoEnable assertions at runtime.
--[no-]export-allnoExport all functions; otherwise, just export main.
--[no-]import-shared-memorynoImport a shared memory buffer. If this is on, --shared-memory-max-pages must also be specified.
--[no-]inliningyesEnable function inlining.
--inlining-limit size0Always inline functions no larger than this number of AST nodes, if inlining is enabled.
--[no-]js-compatibilitynoEnable JS compatibility mode.
--[no-]name-sectionyesEmit Name Section with function names.
--[no-]omit-type-checksnoOmit runtime type checks, such as covariance checks and downcasts.
--[no-]polymorphic-specializationnoDo virtual calls by switching on the class ID instead of using call_indirect.
--[no-]print-kernelnoPrint IR for each function before compiling it.
--[no-]print-wasmnoPrint Wasm instructions of each compiled function.
--[no-]verify-type-checksnoInstrument code to verify that type check optimizations produce the correct result.
--shared-memory-max-pages pagecountMax size of the imported memory buffer. If --shared-import-memory is specified, this must also be specified.
--watch offsetPrint stack trace leading to the byte at offset offset in the .wasm output file. Can be specified multiple times.

Dart2Wasm will output a wasm file, containing Dart compiled to Wasm, as well as an mjs file containing the runtime. The result can be run with:

d8 pkg/dart2wasm/bin/run_wasm.js -- /abs/path/to/<output file>.mjs <output file>.wasm

Where d8 is the V8 developer shell.

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 JS objects, use a JS interop type, e.g. JSAny, which translates to the Wasm externref type. These can be passed around and stored as opaque values on the Dart side.
  • For Dart objects, use the corresponding Dart type. This will be emitted as anyref and automatically converted to and from the Dart type at the boundary.

Detecting whether code is running as WebAssembly

dart2wasm defines dart.tool.dart2wasm as true, meaning that bool.fromEnvironment('dart.tool.dart2wasm') can be used in a constant context to determine whether it was compiled to WebAssembly.