Skip to content
This repository was archived by the owner on Jul 1, 2023. It is now read-only.

Async compilation and instantiation #62

Merged
merged 3 commits into from
Nov 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions wasm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
- Add options to setup.dart for configuring the build.
- Add Module.serialize and Module.deserialize.
- Add bin/precompile.dart, which compiles and serializes wasm modules.
- Add `WasmModule.compileAsync` and `WasmInstanceBuilder.buildAsync`, so that
the web API can be supported in the future.

## 0.1.0+1

Expand Down
7 changes: 7 additions & 0 deletions wasm/lib/src/module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ class WasmModule {
/// Deserialize a module. See [WasmModule.serialize] for more details.
WasmModule.deserialize(Uint8List data) : this._(data, true);

/// Asynchronously compile a module.
static Future<WasmModule> compileAsync(Uint8List data) async =>
Future<WasmModule>(() => WasmModule(data));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Future<WasmModule>(() => WasmModule(data));
WasmModule(data);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constructor I'm using here defers execution to a later time, but on the same isolate. My idea was that compilation/instantiation might be expensive, so although I can't do the compile on a different isolate, I can at least give the scheduler a chance to prioritize stuff like UI updates. It would be a bit weird to have an async method that can still block for a while.


/// Returns a [WasmInstanceBuilder] that is used to add all the imports that
/// the module needs before instantiating it.
WasmInstanceBuilder builder() => WasmInstanceBuilder._(this);
Expand Down Expand Up @@ -223,6 +227,9 @@ class WasmInstanceBuilder {
}
return WasmInstance._(_module, _importOwner, _imports, _wasiEnv);
}

/// Asynchronously build the module instance.
Future<WasmInstance> buildAsync() async => Future<WasmInstance>(build);
}

// TODO: should not be required once the min supported Dart SDK includes
Expand Down
33 changes: 33 additions & 0 deletions wasm/test/async_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Test that we can load a wasm module, find a function, and call it.
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:wasm/wasm.dart';

void main() {
test('async compilation', () async {
// int64_t square(int64_t n) { return n * n; }
final data = Uint8List.fromList([
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60, //
0x01, 0x7e, 0x01, 0x7e, 0x03, 0x02, 0x01, 0x00, 0x04, 0x05, 0x01, 0x70,
0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f,
0x01, 0x41, 0x80, 0x88, 0x04, 0x0b, 0x07, 0x13, 0x02, 0x06, 0x6d, 0x65,
0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x06, 0x73, 0x71, 0x75, 0x61, 0x72,
0x65, 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x00,
0x7e, 0x0b,
]);

final mod = await WasmModule.compileAsync(data);
final inst = await mod.builder().buildAsync();
final fn = inst.lookupFunction('square');
final n = fn(1234) as int;

expect(n, 1234 * 1234);

expect(inst.lookupFunction('not_a_function'), isNull);
});
}