Utilities for loading and running WASM modules from Dart code

Overview

Provides utilities for loading and running WASM modules

Built on top of the Wasmer runtime.

Setup

Run dart run wasm:setup to build the Wasmer runtime.

Basic Usage

As a simple example, we'll try to call the following C function from Dart using package:wasm. For a more detailed example that uses WASI, check out the example directory.

extern "C" int square(int n) { return n * n; }

We can compile this C++ code to WASM using a recent version of the clang compiler:

clang --target=wasm32 -nostdlib -Wl,--export-all -Wl,--no-entry -o square.wasm square.cc

Then we can load and run it like this:

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

void main() {
  final data = File('square.wasm').readAsBytesSync();
  final mod = WasmModule(data);
  print(mod.describe());
  final inst = mod.builder().build();
  final square = inst.lookupFunction('square');
  print(square(12));
}

This should print:

export memory: memory
export function: int32 square(int32)

144
Comments
  • `dart run wasm:setup` fails (on windows? latest dev? not sure)

    `dart run wasm:setup` fails (on windows? latest dev? not sure)

    I couldn't resist trying to run this in between meetings. :p

    PS C:\Users\micro\Documents\GitHub\wasm> dart --version
    Dart SDK version: 2.14.0-182.0.dev (dev) (Thu Jun 3 16:01:27 2021 -0700) on "windows_x64"
    
    [√] Flutter (Channel master, 2.3.0-17.0.pre.220, on Microsoft Windows [Version 10.0.19041.985], locale en-US)
        • Flutter version 2.3.0-17.0.pre.220 at C:\Users\micro\flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 2f88966935 (75 minutes ago), 2021-06-04 13:58:21 -0700
        • Engine revision 03d645e782
        • Dart version 2.14.0 (build 2.14.0-182.0.dev)
    
    PS C:\Users\micro\Documents\GitHub\wasm> dart pub get
    Resolving dependencies...
      analyzer 1.7.0 (1.7.1 available)
    Got dependencies!
    PS C:\Users\micro\Documents\GitHub\wasm> dart run wasm:setup      
    Unhandled exception:
    Invalid argument(s): Could not find ".dart_tool/package_config.json" within "file:///C:/Users/micro/Documents/GitHub/wasm/".
    #0      _getOutDir (file:///C:/Users/micro/Documents/GitHub/wasm/bin/setup.dart:64:5)
    #1      _main (file:///C:/Users/micro/Documents/GitHub/wasm/bin/setup.dart:118:18)
    #2      main (file:///C:/Users/micro/Documents/GitHub/wasm/bin/setup.dart:25:11)
    <asynchronous suspension>
    

    Although there is a comment in the code (_getLibName) suggesting windows support may not be implemented yet, so maybe this is expected.

    Please feel free to disregard if this is not helpful. I just was curious to play with the fancy new code, that's all. Maybe I'll find some time on a weekend to hack on it a bit.

    bug 
    opened by eseidel 24
  • Include setup script in flutter_wasm

    Include setup script in flutter_wasm

    It's necessary to run package:wasm's setup.dart script when using package:flutter_wasm, but pub says "Cannot run executables in transitive dependencies.". So in the documentation users are told to depend on package:wasm as well as package:flutter_wasm. This is not ideal.

    It would be better to include setup.dart in flutter_wasm. It would be nice to figure out a way to avoid code duplication, but export 'package:wasm/bin/setup.dart'; doesn't work because that path is relative to wasm/lib/, so it can't get to the bin directory.

    enhancement 
    opened by liamappelbe 21
  • Android arm64-v8a:  missing requires CPU features:

    Android arm64-v8a: missing requires CPU features: "EnumSet(SSE2)"

    When run code with flutter on Android arm64-v8a:

    import 'package:wasm/wasm.dart';
    
    var mod = WasmModule(m);
    var inst = mod.builder().build();  // error here
    

    got this error:

    E/flutter (10982): WasmError: Wasm module instantiation failed.
    E/flutter (10982): missing requires CPU features: "EnumSet(SSE2)"
    E/flutter (10982): #0      WasmRuntime._checkNotEqual (package:wasm/src/runtime.g.dart:952:7)
    E/flutter (10982): #1      WasmRuntime.instantiate (package:wasm/src/runtime.g.dart:713:5)
    E/flutter (10982): #2      new WasmInstance._ (package:wasm/src/module.dart:261:25)
    E/flutter (10982): #3      WasmInstanceBuilder.build (package:wasm/src/module.dart:228:25)
    

    The reason is this code: https://github.com/dart-lang/wasm/blob/0789947186747fad02d01f5e858b049f09b8cd81/wasm/lib/src/runtime.g.dart#L579

      Pointer<WasmerConfig> _createEngineConfig() {
        final config = _config_new();
        final triple = _wasmer_triple_new_from_host();
        final cpuFeatures = _wasmer_cpu_features_new();
        final sse2 = _allocateString('sse2');
        _wasmer_cpu_features_add(cpuFeatures, sse2);
        calloc.free(sse2.ref.data);
        calloc.free(sse2);
        final target = _wasmer_target_new(triple, cpuFeatures);
        _config_set_target(config, target);
        return config;
      }
    

    after remove _wasmer_cpu_features_add(cpuFeatures, sse2); everything works fine ;-)


    • flutter version: 2.8.1 (stable)
    opened by sceext2 12
  • Untangle, move and hide singleton.

    Untangle, move and hide singleton.

    This moves the runtime singleton into the higher level API so we can hide it, and removes it from the unrelated lower level wasmer bindings where it isn't necessary.


    I think I have a clean solution for #47 that will also allow us to test for wasmer related memory leaks and fix that one place that leaks memory where the import isn't being disposed of. @liamappelbe could you recommend me a workflow to submit multiple PRs that depend on eachother in a way that would make it easy for you to review them and allow us to move faster?

    opened by modulovalue 10
  • Switch to a singleton store

    Switch to a singleton store

    This is one of the feature requests from #38

    This change should be transparent to users at this stage, but will enable future features like sharing memory or functions between modules.

    opened by liamappelbe 9
  • WasmError: This case is not (yet) supported. Please file an issue on pkg:wasm

    WasmError: This case is not (yet) supported. Please file an issue on pkg:wasm

    Hi! Thanks for your work!

    I was receiving the error message WasmError: This case is not (yet) supported. Please file an issue on pkg:wasmwhen trying out the package.

    You can run the test in https://github.com/juancastillo0/dart-parser/blob/main/test/parser_test.dart to receive the same error. The wasm file was generated using wasm-pack build for the Rust project in the dart-parser-wasm folder of the same repository. It uses wasm-pack and wasm-bidgen.

    WasmError: This case is not (yet) supported. Please file an issue on pkg:wasm.
    WasmRuntime.maybeThrowTrap
    package:wasm/src/runtime.g.dart:610
    WasmRuntime.call
    package:wasm/src/runtime.g.dart:680
    WasmFunction.apply
    package:wasm/src/module.dart:403
    _Instance.lookupFunction.<fn>
    package:dart_fixer_test/…/wasm/wasm_interop_native.dart:108
    DartParserWasmModule.parse
    package:dart_fixer_test/…/wasm/dart_parser_wasm_bg.dart:122
    DartParser.parse
    package:dart_fixer_test/wasm/dart_parser_wasm.dart:44
    main.<fn>
    

    The same error was also happening when trying some models in https://github.com/juancastillo0/tensorflow_dart.

    Please let me know if there is something else I can do. I could try to make a PR.

    Thanks!

    opened by juancastillo0 7
  • Migrate WasmModule construction to top-level factory functions.

    Migrate WasmModule construction to top-level factory functions.

    See #92 step 2.

    The following are some TODOs as a note to myself:

    • the circular dependency between runtime.compile and WasmModule should be broken by having the owner be a function that receives the pointer and returns an owner and a generic return type.
    • the async version for constructing a WasmModule is not doing anything that the sync version isn't doing and could be removed. It seems to act as a reminder for providing an async construction scheme in the future?
    opened by modulovalue 6
  • Multiprocessing use case.

    Multiprocessing use case.

    The parallel programming facilities in Dart do not support shared memory parallelism. Any computation that can't block the main isolate needs to run in a different isolate where exchange of data can only happen through message passing. This is safe, but restricting. In general, message passing between isolates isn't free and there are data structures (e.g. the fat node approach for Persistent Data Structures) that can't be efficiently implemented (or simulated) with message passing only.

    One workaround is to allocate memory not on the dart heap, but natively via ffi. Pointers to that natively allocated memory can be shared between isolates and shared memory parallelism can be simulated that way.

    The wasmer bindings shouldn't necessarily focus on solving this use case, but they shouldn't prohibit making use of the workaround mentioned above. We should allow for that by being general enough and provide at least the facilities to allow for the following:

    • manual memory management (e.g. by providing a way to use wasmer without having to use finalizers for memory management)
    • manual memory allocation (e.g. by not forcing users to use dart:typed_data for memory allocation)

    I plan to investigate this, and I think it can be achieved by:

    • having explicit wasmer bindings in the style of #92 without finalizers and with a delegate for injecting a custom memory allocator.
    • an adapter between the wasm_api.dart from #92 and the wasmer bindings. This adapter could use #95 for memory management and dart:typed_data for memory allocation.
    opened by modulovalue 5
  • Migrate finalizers

    Migrate finalizers

    Context #95 After this change, the build step for wasmer should reduce to building the wasmer library only. Creating bindings for ios, android and so on should therefore become significantly simpler.

    @liamappelbe what do you think? I haven't used this API yet personally, but it seems like it was built for this purpose and is probably a wrapper around the same API that you were using natively.

    opened by modulovalue 4
  • fn_import_exception_test flakey on mac

    fn_import_exception_test flakey on mac

    Tried it on linux without an issue.

    Mac @ Dart 2.12 https://github.com/dart-lang/wasm/pull/12/checks?check_run_id=2750754609#step:7:568

    Mac @ Dart SDK version: 2.14.0-176.0.dev (dev) (Wed Jun 2 15:17:55 2021 -0700) on "macos_x64" https://github.com/dart-lang/wasm/pull/12/checks?check_run_id=2750754624#step:7:190

    Here's a repro.

    // 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 throwing exceptions from an imported function.
    import 'dart:typed_data';
    
    import 'package:wasm/wasm.dart';
    
    void main() {
      var data = Uint8List.fromList([
        0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x01, 0x60, //
        0x00, 0x00, 0x02, 0x11, 0x02, 0x03, 0x65, 0x6e, 0x76, 0x01, 0x61, 0x00,
        0x00, 0x03, 0x65, 0x6e, 0x76, 0x01, 0x62, 0x00, 0x00, 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,
        0x0f, 0x02, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x02,
        0x66, 0x6e, 0x00, 0x02, 0x0a, 0x10, 0x01, 0x0e, 0x00, 0x10, 0x80, 0x80,
        0x80, 0x80, 0x00, 0x10, 0x81, 0x80, 0x80, 0x80, 0x00, 0x0b,
      ]);
    
      var thrownException = Exception('Hello exception!');
    
      var errorCount = 0;
      for (var i = 0; true; i++) {
        var builder = (WasmModule(data).builder()
          ..addFunction('env', 'a', () {
            throw thrownException;
          })
          ..addFunction('env', 'b', () {
            throw StateError('should not get here!');
          }));
    
        var inst = builder.build();
    
        var fn = inst.lookupFunction('fn');
    
        try {
          fn();
        } on Exception {
          // noop
        } catch (e, stack) {
          print(e);
          print(stack);
          errorCount++;
    
          if (errorCount > 10) {
            break;
          }
        }
        print([errorCount, i]);
      }
    }
    
    bug 
    opened by kevmoo 4
  • CI failures

    CI failures

    https://github.com/dart-lang/wasm/actions/runs/2178344056

    Started out with just mac failing, but now linux is failing too. So far I am unable to reproduce any of the linux or mac failures locally.

    opened by liamappelbe 3
  • Bump actions/cache from 3.0.11 to 3.2.2

    Bump actions/cache from 3.0.11 to 3.2.2

    Bumps actions/cache from 3.0.11 to 3.2.2.

    Release notes

    Sourced from actions/cache's releases.

    v3.2.2

    What's Changed

    New Contributors

    Full Changelog: https://github.com/actions/cache/compare/v3.2.1...v3.2.2

    v3.2.1

    What's Changed

    Full Changelog: https://github.com/actions/cache/compare/v3.2.0...v3.2.1

    v3.2.0

    What's Changed

    New Contributors

    ... (truncated)

    Changelog

    Sourced from actions/cache's changelog.

    Releases

    3.0.0

    • Updated minimum runner version support from node 12 -> node 16

    3.0.1

    • Added support for caching from GHES 3.5.
    • Fixed download issue for files > 2GB during restore.

    3.0.2

    • Added support for dynamic cache size cap on GHES.

    3.0.3

    • Fixed avoiding empty cache save when no files are available for caching. (issue)

    3.0.4

    • Fixed tar creation error while trying to create tar with path as ~/ home folder on ubuntu-latest. (issue)

    3.0.5

    • Removed error handling by consuming actions/cache 3.0 toolkit, Now cache server error handling will be done by toolkit. (PR)

    3.0.6

    • Fixed #809 - zstd -d: no such file or directory error
    • Fixed #833 - cache doesn't work with github workspace directory

    3.0.7

    • Fixed #810 - download stuck issue. A new timeout is introduced in the download process to abort the download if it gets stuck and doesn't finish within an hour.

    3.0.8

    • Fix zstd not working for windows on gnu tar in issues #888 and #891.
    • Allowing users to provide a custom timeout as input for aborting download of a cache segment using an environment variable SEGMENT_DOWNLOAD_TIMEOUT_MINS. Default is 60 minutes.

    3.0.9

    • Enhanced the warning message for cache unavailablity in case of GHES.

    3.0.10

    • Fix a bug with sorting inputs.
    • Update definition for restore-keys in README.md

    3.0.11

    • Update toolkit version to 3.0.5 to include @actions/core@^1.10.0
    • Update @actions/cache to use updated saveState and setOutput functions from @actions/core@^1.10.0

    3.1.0-beta.1

    • Update @actions/cache on windows to use gnu tar and zstd by default and fallback to bsdtar and zstd if gnu tar is not available. (issue)

    3.1.0-beta.2

    • Added support for fallback to gzip to restore old caches on windows.

    3.1.0-beta.3

    ... (truncated)

    Commits
    • 4723a57 Revert compression changes related to windows but keep version logging (#1049)
    • d1507cc Merge pull request #1042 from me-and/correct-readme-re-windows
    • 3337563 Merge branch 'main' into correct-readme-re-windows
    • 60c7666 save/README.md: Fix typo in example (#1040)
    • b053f2b Fix formatting error in restore/README.md (#1044)
    • 501277c README.md: remove outdated Windows cache tip link
    • c1a5de8 Upgrade codeql to v2 (#1023)
    • 9b0be58 Release compression related changes for windows (#1039)
    • c17f4bf GA for granular cache (#1035)
    • ac25611 docs: fix an invalid link in workarounds.md (#929)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump actions/checkout from 3.1.0 to 3.2.0

    Bump actions/checkout from 3.1.0 to 3.2.0

    Bumps actions/checkout from 3.1.0 to 3.2.0.

    Release notes

    Sourced from actions/checkout's releases.

    v3.2.0

    What's Changed

    New Contributors

    Full Changelog: https://github.com/actions/checkout/compare/v3...v3.2.0

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Example projects are not easy to run

    Example projects are not easy to run

    Neither the hello_world nor the brotli example work "out of the box" e.g. they don't have a pubspec in their folder etc pp, which makes the barrier to enter WASM with dart quite high.

    Also the "basic usage" example from the readme is not there as an "example" to investigate.

    In order to run either example you have to first create a new project and copy the files over, which is not ideal.

    Linking to https://github.com/flutter/flutter/issues/90218 since I tried to test WASM in isolation.

    opened by dkbast 1
  • Add a wasm binding generator

    Add a wasm binding generator

    This PR contains a code generator that takes as input a minimal description of a WASM module, and outputs a String containing a valid Dart program that can be used to safely link to the imports and exports during the construction of a wasm module.

    This PR only contains the generator part, a data source is still needed. In a follow up PR, a Wasmer based data source will be implemented.

    opened by modulovalue 0
  • C & C++ examples

    C & C++ examples

    This PR translates the example in the readme into a living example in the example directory. It also adds a C example that is essentially the same as the C++ example, but since they are considered different languages, I think it would be helpful to have separate examples for them.

    opened by modulovalue 0
Owner
Dart
Dart is an open-source, scalable programming language, with robust libraries and runtimes, for building web, server, and mobile apps.
Dart
Dart GraphQL server implementation. Utilities, code generator, examples and reference implementation.

Leto - GraphQL Server A complete implementation of the official GraphQL specification in the Dart programming language. Inspired by graphql-js, async-

Juan Manuel Castillo 29 Nov 27, 2022
A mobile Truth or Dare game for iOS and Android application built using Flutter with CI/CD running on Codemagic.

ToD Game A mobile Truth or Dare game for iOS and Android application built using Flutter with CI/CD running on Codemagic. Quick Start Prerequisites In

ITCraftship 43 Dec 1, 2022
A collection of helpful utilities for use in Dart projects.

w_common A collection of helpful utilities for use in Dart projects. Right now, it includes the following: Disposable interface / mixin to assist with

Workiva 10 Dec 16, 2022
The FlexGrid control provides a powerful and quickly way to display data in a tabular format. It is including that frozened column/row,loading more, high performance and better experience in TabBarView/PageView.

flex_grid Language: English| 中文简体 The FlexGrid control provides a powerful and quickly way to display data in a tabular format. It is including that f

FlutterCandies 39 Nov 8, 2022
A Flutter package for building custom skeleton widgets to mimic the page's layout while loading.

Skeletons A Flutter package for building custom skeleton widgets to mimic the page's layout while loading. Examples Items ListView (Default) ListView

Moh Badjah 46 Dec 17, 2022
A discord bot, made with Dart, which lets you run your own pure Dart code snippets directly via a discord ping, and get the output in an instant.

A discord bot, made with Dart, which lets you run your own pure Dart code snippets directly via a discord ping, and get the output in an instant.

Anikate De 3 Oct 21, 2022
A collection of Dart code samples by Dart DevRel

Dart samples A collection of Dart programs that illustrate features and best practices. For a list of community-maintained projects, see Awesome Dart.

Dart 458 Dec 30, 2022
A multiplatform Dart movie app with 40% of code sharing between Flutter and the Web.

A multiplatform Dart movie app with 40% of code sharing between Flutter and the Web.

Iiro Krankka 3.4k Dec 30, 2022
Routinger is a task scheduler app that is made to make you a better person at no extra cost. The code is open-source. Dart language and Flutter framework are used extensively.

Routinger This is a simple app that will allow you to schedule your tasks, create a simple to-do, and also make recurring tasks. The app ends you noti

Routinger 16 Dec 17, 2022
Naj - An open-source code generation and file management system written in Dart

Naj An open-source code generation and file management system written in Dart Ov

Najibullah Khoda Rahim 1 Feb 14, 2022
Allows Dart reflection using code generation/builder.

reflection_factory reflection_factory allows Dart reflection with an easy approach, even for third-party classes, using code generation portable for a

Graciliano Monteiro Passos 13 Oct 30, 2022
UI design for mobile, create using visual studio code & flutter dart programming languange

HCIProjectLab A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if

null 1 Oct 13, 2021
App to learn how to code with a lot of great courses and ideas of projects to do, focused on productivity and fast learn. 💻

skoola A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if this i

Batista Tony 3 Oct 29, 2021
a sample flutter app using Injection, routing and simple authentication follows clean code and best practices

Flutter Clean Project A sample flutter app using Injection, routing and simple authentication follows clean code and best practices Features Cleaned f

Moez Shakeri 12 Jan 2, 2023
QR.Flutter is a Flutter library for simple and fast QR code rendering via a Widget or custom painter.

QR.Flutter is a Flutter library for simple and fast QR code rendering via a Widget or custom painter. Need help? Please do not submit an issue for a "

Yakka 612 Jan 4, 2023
A flutter app that reads the qr code and shows the content

qr_code_reader dependencies: qr_flutter: ^3.2.0 barcode_scan: ^3.0.1 url_launche

Aravind B 0 Jan 9, 2022
Berikut merupakan source code Chat Apps dengan Flutter + GetX + Firebase

chatapp A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if this

Sandikha Rahardi 52 Dec 31, 2022
Source code for @flutter.master

Flutter-Master Reels Onboarding screen Go Personal Finance Go Nike Store Go Travel App Go Solar system App Go Animations Implicit animations Go Tween

null 28 Nov 16, 2022
Repository with Frontend code for InnoTutor project. It is written on Flutter.

inno_tutor A new Flutter application. Getting Started This project is a starting point for a Flutter application. A few resources to get you started i

InnoTutor 23 Sep 17, 2022