GithubHelp home page GithubHelp logo

dart-archive / wasm Goto Github PK

View Code? Open in Web Editor NEW
311.0 40.0 24.0 1.17 MB

Utilities for loading and running WASM modules from Dart code

Home Page: https://pub.dev/packages/wasm

License: BSD 3-Clause "New" or "Revised" License

Dart 90.53% Rust 0.01% Python 7.71% Perl 0.50% Raku 0.11% C 0.62% Kotlin 0.51%
wasm dartlang dart ffi

wasm's Introduction

These packages provide utilities for loading and running WASM modules.

Status: Discontinued

Notice: This package was an experiment in consuming WASM code - integrating a WASM runtime into applications, allowing them to leverage existing native libraries compiled to WASM. While this is still an interesting path to explore, generally as a team we're investing in producing WASM from Dart - letting a Dart based app run in a WASM runtime (ala Flutter Web in a browser). See https://docs.flutter.dev/platform-integration/web/wasm for more information.

For people who do wish to continue to experiment with a similar technique to package:wasm / leveraging a wasm runtime, please feel free to fork this repo.

See also #146.

Packages

Package Description Published Version
wasm Runs WASM modules in Dart native. pub package
flutter_wasm Runs WASM modules in Flutter.

wasm's People

Contributors

dependabot[bot] avatar devoncarew avatar kevmoo avatar liamappelbe avatar mit-mit avatar modulovalue avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wasm's Issues

[ux] WASI

I'm trying to bind some WASM modules, and here is one error that is extremely confusing from the perspective of a user:

https://github.com/dart-lang/wasm/blob/ddb2d46ac000827f44a3d18c6564b13b8b3876ef/wasm/lib/src/runtime.dart#L355-L365

WasmRuntimeError: Failed to fill WASI imports.
Failed to resolve import "env" "exit"
#0      WasmRuntime._checkNotEqual (package:wasm/src/runtime.dart:384:7)
#1      WasmRuntime.getWasiImports (package:wasm/src/runtime.dart:360:5)
#2      _WasmInstanceBuilder.enableWasi (package:wasm/src/module.dart:210:13)

To be honest, I'm not entirely sure how WASI is supposed to work.
As far as I understood it, it's a known set of imports that WASM modules can choose to depend on? So if a module expects a particular set of imports, can we then derive that it depends on WASI? We should perhaps provide some help here or at least a little more information about what actually went wrong.

Support Android/iOS

I am having an issue with the WasmModule loading. I have the following in my Flutter app:

  final data = await rootBundle.load('assets/add.wasm');

  final mod = WasmModule(data.buffer.asUint8List());

  print(mod.describe());

  final inst = mod.builder().build();
  final add = inst.lookupFunction('add_one');

  print(add(12));

I have run dart run wasm:setup. The issue I find is Directory.current.uri returns \ which is obviously incorrect. In particular, I am talking about _getLibPath() where locating the library fails.

Is this not designed to work with Flutter applications? Mobile in particular.

iOS support has some problems

i pull ios_support branch, and run flutter pub run flutter_wasm:ios_setup(but readme.md says flutter pub run flutter_wasm:setup,should update?), then get this exception:

Unhandled exception:
RangeError (index): Invalid value: Valid value range is empty: 0
#0      List.[] (dart:core-patch/growable_array.dart:264:36)
#1      main (file:///Users/yuvan/Documents/github/wasm/flutter_wasm/bin/ios_setup.dart:98:32)
<asynchronous suspension>
pub finished with exit code 255

I read this file ios_setup.dart,Found several paths in the file that are absolute,for example:

final frameworkTemplatePath = '/Users/liama/dev/wasm/flutter_wasm/ios/FrameworkTemplate

Then I changed it to my local path,Run flutter pub run flutter_wasm:ios_setup again with a successful result:

Creating fat library for iphoneos at /Users/yuvan/Documents/github/wasm/flutter_wasm/example/.dart_tool/pub/bin/flutter_wasm/ios/build/iphoneos/flutter_wasm
FFFFF: /Users/yuvan/Documents/github/wasm/flutter_wasm/example/.dart_tool/pub/bin/flutter_wasm/ios_setup.dart-2.18.2.snapshot
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo -create /Users/yuvan/Documents/github/wasm/flutter_wasm/example/.dart_tool/pub/bin/flutter_wasm/ios/build/iphoneos/aarch64-apple-ios/libwasmer.dylib -output /Users/yuvan/Documents/github/wasm/flutter_wasm/example/.dart_tool/pub/bin/flutter_wasm/ios/build/iphoneos/flutter_wasm
Creating framework at /Users/yuvan/Documents/github/wasm/flutter_wasm/example/Frameworks/flutter_wasm.xcframework
FFFFF: /Users/yuvan/Documents/github/wasm/flutter_wasm/example/.dart_tool/pub/bin/flutter_wasm/ios_setup.dart-2.18.2.snapshot
xcrun xcodebuild -create-xcframework -framework /Users/yuvan/Documents/github/wasm/flutter_wasm/example/.dart_tool/pub/bin/flutter_wasm/ios/build/iphoneos/lib_wasm.framework -output /Users/yuvan/Documents/github/wasm/flutter_wasm/example/Frameworks/flutter_wasm.xcframework
xcframework successfully written out to: /Users/yuvan/Documents/github/wasm/flutter_wasm/example/Frameworks/flutter_wasm.xcframework

But when I run it next example/lib/main.dart,get this error

Error (Xcode): File not found: /Users/yuvan/Documents/github/wasm/flutter_wasm/example/ios/Pods/../.symlinks/plugins/flutter_wasm/ios/Frameworks/flutter_wasm.xcframework/ios-x86_64-simulator/flutter_wasm

I mean, are you sure the ios example is runnable? or rather ios is supported?

Windows dart run wasm:setup fail

Result

D:\developSoftware\flutter\workspace\surnote\plugin\demo\master\flutter-quill\example> dart run wasm:setup 
Dart SDK directory: D:\developSoftware\flutter\fvm\versions\3.0.4\bin\cache\dart-sdk\
Dart SDK include directory: D:\developSoftware\flutter\fvm\versions\3.0.4\bin\cache\dart-sdk\include\
Source directory: C:\Users\joahyan\AppData\Local\Pub\Cache\hosted\pub.dartlang.org\wasm-0.1.0+1\bin\
Output directory: D:\developSoftware\flutter\workspace\surnote\plugin\demo\master\flutter-quill\example\.dart_tool\wasm\
Target: x86_64-pc-windows-msvc
OS: windows
Output library: D:\developSoftware\flutter\workspace\surnote\plugin\demo\master\flutter-quill\example\.dart_tool\wasm\wasmer.dll

cargo build --target x86_64-pc-windows-msvc --target-dir D:\developSoftware\flutter\workspace\surnote\plugin\demo\master\flutter-quill\example\.dart_tool\wasm\ --manifest-path C:\Users\joahyan\AppData\Local\Pub\Cache\hosted\pub.dartlang.org\wasm-0.1.0+1\bin\Cargo.toml --release

    Finished release [optimized] target(s) in 0.87s

clang -DDART_SHARED_LIB -DNDEBUG -fno-exceptions -O3 -target x86_64-pc-windows-msvc -I D:\developSoftware\flutter\fvm\versions\3.0.4\bin\cache\dart-sdk\include\ -I D:\developSoftware\flutter\workspace\surnote\plugin\demo\master\flutter-quill\example\.dart_tool\wasm\include\ -c D:\developSoftware\flutter\fvm\versions\3.0.4\bin\cache\dart-sdk\include\dart_api_dl.c -o D:\developSoftware\flutter\workspace\surnote\plugin\demo\master\flutter-quill\example\.dart_tool\wasm\dart_api_dl.o

FAILED with exit code 2 `clang -DDART_SHARED_LIB -DNDEBUG -fno-exceptions -O3 -target x86_64-pc-windows-msvc -I D:\developSoftware\flutter\fvm\versions\3.0.4\bin\cache\dart-sdk\include\ -I D:\developSoftware\flutter\workspace\surnote\plugin\demo\master\flutter-quill\example\.dart_tool\wasm\include\ -c D:\developSoftware\flutter\fvm\versions\3.0.4\bin\cache\dart-sdk\include\dart_api_dl.c -o D:\developSoftware\flutter\workspace\surnote\plugin\demo\master\flutter-quill\example\.dart_tool\wasm\dart_api_dl.o`
PS D:\developSoftware\flutter\workspace\surnote\plugin\demo\master\flutter-quill\example>

No JIT on iOS

iOS platforms do not support certain primitives needed for fast JITing in applications distributed through the App Store. JITing is needed for a fast wasm runtime.

Wasmer added support for precompilation through which wasm can be compiled to a dylib and that dylib can then be bundled with applications to allow distribution through the App Store.

There are other wasm runtimes that interpret wasm and do not depend on JITing. The catch is that they are slower than JITed runtimes and I'm not sure if applications that interpret wasm are allowed on the App Store.

So either:

  • the API for compiling wasm will need to be adjusted to support precompilation on iOS platforms
  • or wasm will need to be intrepreted on iOS through e.g. wasm3
  • or we'll have to wait until Apple adds first party wasm support (I have no reason to assume that they have plans to do so)
  • or no iOS support

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.

Android build fails on macOS

Building an app with flutter_wasm currently fails on macOS for me. The gradle output is:

  running: "/Users/nydillon/Library/Android/sdk/ndk/21.1.6352462/toolchains/llvm/prebuilt/mac" "os" "x-x86_64/bin/aarch64-linux-android29-clang" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-Wall" "-Wextra" "-DCFG_TARGET_OS_ANDROID" "-o" "/Users/nydillon/dev/AmplifyFlutter-DSTestApp/build/flutter_wasm/intermediates/stripped_native_libs/debug/out/lib/arm64-v8a/aarch64-linux-android/release/build/wasmer-vm-2eff8b72936265b4/out/src/trap/handlers.o" "-c" "src/trap/handlers.c"

  --- stderr

  error occurred: Failed to find tool. Is `mac` installed?

It seems that this line produces a string with spaces "mac os x", but regardless is not retrieving the correct value, given this listing of the directory it's searching.

$ ls /Users/nydillon/Library/Android/sdk/ndk/21.1.6352462/toolchains/llvm/prebuilt
darwin-x86_64

Manually changing that line of code to search the darwin-x86_64 directory fixes the issue.

Exec "dart run wasm:setup" cmd return dart/dart_api.h:24:10: fatal error: 'assert.h' file not found

Windows 10

Exec "dart run wasm:setup" cmd return error result:

clang -DDART_SHARED_LIB -DNDEBUG -fno-exceptions -O3 -target x86_64-pc-windows-msvc -I I:\MyProgramFiles\flutter\bin\cache\dart-sdk\include\third_party\dart\ -I I:\MyProjects.dart_tool\wasm\include\ -c I:\MyProgramFiles\flutter\bin\cache\dart-sdk\include\third_party\dart\dart_api_dl.c -o I:\MyProjects.dart_tool\wasm\dart_api_dl.o

In file included from I:\MyProgramFiles\flutter\bin\cache\dart-sdk\include\third_party\dart\dart_api_dl.c:7:
In file included from I:\MyProgramFiles\flutter\bin\cache\dart-sdk\include\third_party\dart/dart_api_dl.h:10:
I:\MyProgramFiles\flutter\bin\cache\dart-sdk\include\third_party\dart/dart_api.h:24:10: fatal error: 'assert.h' file not found
#include <assert.h>
^~~~~~~~~~
1 error generated.
FAILED with exit code 1 clang -DDART_SHARED_LIB -DNDEBUG -fno-exceptions -O3 -target x86_64-pc-windows-msvc -I I:\MyProgramFiles\flutter\bin\cache\dart-sdk\include\third_party\dart\ -I I:\MyProjects\.dart_tool\wasm\include\ -c I:\MyProgramFiles\flutter\bin\cache\dart-sdk\include\third_party\dart\dart_api_dl.c -o I:\MyProjects\.dart_tool\wasm\dart_api_dl.o

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 flutter/flutter#90218 since I tried to test WASM in isolation.

flaky macos CI

===== CRASH =====
si_signo=Segmentation fault: 11(11), si_code=1, si_addr=0x34
version=2.12.0 (stable) (Thu Feb 25 19:50:53 2021 +0100) on "macos_x64"
pid=15130, thread=5639, isolate_group=(nil)(0x0), isolate=(nil)(0x0)
isolate_instructions=0, vm_instructions=10ab8d880
  pc 0x00000001134f94e2 fp 0x0000[70](https://github.com/dart-lang/wasm/actions/runs/3510196781/jobs/5879803450#step:7:71)0001f85de0 wasm_trap_delete+0x12
  pc 0x000000010b2f65f7 fp 0x0000700001f85e20 dart::FinalizablePersistentHandle::Finalize(dart::IsolateGroup*, dart::FinalizablePersistentHandle*)+0x77
  pc 0x000000010ad3f98d fp 0x0000700001f85e80 dart::IsolateGroup::~IsolateGroup()+0xdd
  pc 0x000000010ad404d0 fp 0x0000700001f85eb0 dart::IsolateGroup::Shutdown()+0xd0
  pc 0x000000010ae90aae fp 0x0000700001f85f30 dart::ThreadPool::WorkerLoop(dart::ThreadPool::Worker*)+0x14e
  pc 0x000000010ae90fad fp 0x0000700001f85f60 dart::ThreadPool::Worker::Main(unsigned long)+0x5d
  pc 0x000000010adfaf98 fp 0x0000700001f85fb0 dart::OSThread::GetMaxStackSize()+0xb8
  pc 0x00007ff[81](https://github.com/dart-lang/wasm/actions/runs/3510196781/jobs/5879803450#step:7:82)8a3d4e1 fp 0x0000700001f85fd0 _pthread_start+0x7d
  pc 0x00007ff818a38f6b fp 0x0000700001f85ff0 thread_start+0xf
-- End of DumpStackTrace
/Users/runner/work/_temp/b5b0[82](https://github.com/dart-lang/wasm/actions/runs/3510196781/jobs/5879803450#step:7:83)5a-e454-415b-ae1e-0db500660f[83](https://github.com/dart-lang/wasm/actions/runs/3510196781/jobs/5879803450#step:7:84).sh: line 1: 15130 Abort trap: 6           dart test

Seems to only happen on macos 2.12.0.

dart run wasm:setup fails on linux when referenced as a dependency pointing to git

I tried to reproduce the example on README on Ubuntu and it failed when i executed dart run wasm:setup.

I got this error:

...
manifest path `/home/abner/dart-wasm-project/.dart_tool/pub/bin/wasm/Cargo.toml` does not exist

I referenced the wasm project in my pubspec.yaml using git reference:

dependencies:
  wasm: 
    git:
      url: https://github.com/dart-lang/wasm.git
      ref: main

I manually copied the files in the wasm repository bin folder (Cargo.toml, finalizers.cc, setup.dart, wasmer.rs) into my .dart_tool/pub/bin/wasm and after it, the command dart run wasm:setup just worked.

Actually, i wanna also to know if dart-lang/wasm is intended to work inside Flutter apps (both mobile, desktop and web)?

[bindgen] functions starting with an underscore

Consider the following set of exports (from tree-sitter in this case):

...
export function: int32 towupper(int32)
export function: int32 __errno_location()
export function: int32 memchr(int32, int32, int32)
export function: int32 strlen(int32)
export function: int32 stackSave()
export function: void stackRestore(int32)
export function: int32 stackAlloc(int32)
export function: void setThrew(int32, int32)
export function: int32 _ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED2Ev(int32)
export function: void _ZNSt3__212basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE9__grow_byEmmmmmm(int32, int32, int32, int32, int32, int32, int32)
...

Notice that there are functions starting with an underscore. I guess this is a convention to signal that a function is private and not meant to be used? Should we generate bindings for them? (I'm wondering if there are already some established expectations here)

Wasm for web

I Was wondering if it is possible to add web support to wasm someway (it uses ffi so assuming it will not support web),
or maybe have source_gen generate interop with something like wasm_interop for web.

This could help package developers as they will not have to maintain 2 packages(package using ffi and package using js interop) and also having just a single file binary file to read from unlike for the ffi would be great!

pkg:wasm: hello_wasi test failing on mac

dart test
00:02 +0: test/hello_wasi_test.dart: hello wasi                                                                                                                                                                                             hello, world!
00:02 +2 -1: test/hello_wasi_test.dart: hello wasi [E]
  Invalid argument(s): Count must be in the range [0, 4611686018427387903].
  dart:ffi                             Uint8Pointer.asTypedList
  package:wasm/src/runtime.dart 88:33  _WasiStreamIterator.current

00:02 +2 -1: loading test/hello_wasi_test.dart
Consider enabling the flag chain-stack-traces to receive more detailed exceptions.
For example, 'pub run test --chain-stack-traces'.
00:04 +12 -1: Some tests failed.

around commit 40856c14c19fedb35f00321df3b7ec74e0613cd8

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!

Wasmer async module compilation.

Under the assumption that wasmer doesn't offer a way to asynchronously compile modules, we should investigate the new Isolate.run functionality for giving users the choice to asynchronously build wasmer modules.

This might be a little annoying, because we can't pass Pointers between isolates see: dart-lang/sdk#50457.
Isolate.run is also not available on 2.12.0 which is our current dart lower bound.

First build with flutter_wasm for android is flaky

The first build of a flutter_wasm app for android sometimes fails. Specifically, the app will build successfully, but at runtime it will be missing libwasmer.so.

Rebuilding fixes the issue, and it never happens again, but we should still figure out why it's happening. At the very least, we should add a check to setup.dart to make sure the artifacts are all produced correctly, so that the build doesn't claim to succeed when it has actually failed.

API does not fully support sharing objects between multiple modules

Multiple modules may need to use the same Memory, Function, Table, or Global objects. Example scenarios that seem to be currently unsupported:

  • Creating a Memory object, filling it with data, then importing it into multiple modules. Potential solution: move WasmerStore out of WasmModule (this may require adjusting finalizers).
  • Exporting a Function from one Module and importing it into another. Potential solution: relax WasmInstanceBuilder.addFunction to accept WasmFunction or add a new WasmInstanceBuilder.addWasmFunction method.
  • Creating a Global object and importing it into multiple modules.
  • Importing a Global exported from another module.

WasmError: Missing import: function

I am trying to import a wasm module in dart but keep getting this error:

WasmError: Missing import: function: void a::a(int32, int32, int32, int32)
WasmInstanceBuilder.build  package:wasm/src/module.dart:212

Code snippet

 final data = File('file.wasm').readAsBytesSync();
 final mod = WasmModule(data);
 print(mod.describe());
 walletCoreWasm = mod.builder().build(); //! causes error
mod.describe() output
import function: void a::a(int32, int32, int32, int32)
import function: int32 a::b(int32)
import function: void a::c(int32, int32, int32)
import function: void a::d(int32, int32, int32)
import function: void a::e(int32, int32, int32, int32, int32, int32, int32, int32)
import function: void a::f(int32, int32, int32, int32, int32, int32, int32)
import function: void a::g(int32, int32, int32, int32, int32, int32, int32, int32, int32, int32, int32, int32, int32)
import function: void a::h(int32, int32, int32)
import function: void a::i(int32)
import function: void a::j(int32, int32, int32, int32)
import function: void a::k(int32)
import function: void a::l(int32, int32, int32, int32, int32)
import function: void a::m(int32)
import function: void a::n()
import function: int32 a::o(int32)
import function: void a::p(int32, int32, int32)
import function: void a::q(int32, int32, int32, int32, int32, int32)
import function: int32 a::r(int32, int32, int32, int32)
import function: int32 a::s(int32, int32, int32, int32)
import function: int32 a::t(int32, int32, int32, int32)
import function: int32 a::u(int32, int32, int32)
import function: float64 a::v()
import function: void a::w(int32, int32)
import function: void a::x(int32, int32, int32)
import function: int32 a::y(int32, int32, int32, int32)
import function: int32 a::z(int32)
import function: int32 a::A(int32, int32)
import function: int32 a::B(int32, int32, int32, int32, int32)
import function: void a::C(int32, int32, int32, int32, int32, int32, int32)
import function: int32 a::D(int32, int32, int32, int32, int32)
import function: int32 a::E(int32, int32)
import function: int32 a::F(int32, int32)
import function: int32 a::G(int32, int32, int32)
import function: int32 a::H(int32)
import function: int32 a::I(int32, int32, int32, int32, int32, int32)
import function: int32 a::J()
import function: void a::K(int32, int32, int32)
import function: void a::L(int32, int32)
import function: void a::M(int32, int32, int32, int32, int32)
import function: void a::N(int32, int32)
import function: void a::O(int32, int32, int32, int32)
import function: int32 a::P(int32, int32)
export memory: Q
export function: void R()
export table: S
export function: void T(int32)
export function: int32 U(int32)
export function: int32 V()
export function: int32 W(int32)
export function: void X()
export function: int32 Y(int32, int32)
export function: int32 Z(int32)
export function: int32 _(int32, int32, int32, int32, int32)
export function: int32 $(int32, int32, int32, int32, int32, int32)
export function: int32 aa(int32, int32, int32, int32)
export function: int32 ba(int32, int32, int32, int32, int32)
export function: int32 ca(int32, int32, int32, int32, int32)
export function: int32 da(int32, int32, int32, int32, int32, int32)
export function: int32 ea(int32, int32, int32, int32, int32, int32, int32, int32)
export function: int32 fa(int32, int32, int32, int32)
export function: void ga(int32, int32, int32, int32, int32, int32, int32)
export function: int32 ha(int32, int32)
export function: void ia(int32, int32, int32, int32, int32, int32, int32, int32, int32, int32, int32, int32, int32)
export function: int32 ja(int32, int32, int32)
export function: int32 ka(int32, int32, int32)
export function: void la(int32, int32, int32, int32, int32)
export function: int32 ma(int32, int32, int32, int32, int32)
export function: int32 na(int32, int32, int32, int32, int32, int32, int32)
export function: int32 oa(int32, int32, int32, int32, int32, int32, int32, int32, int32)
export function: int32 pa(int32, int32, int32, int32, int32, int32, int32, int32, int32, int32)

It works in javascript so I am wondering how dart processes this differently. Should I export all methods from the original c++ project? Or maybe tag them using EMSCRIPTEN_KEEPALIVE

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)

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.

Provide an explicit public API and hide internals from users.

This issue is a response to the feedback from liamappelbe in #91

Here is a rough sketch of what I plan to submit in separate PRs:

  1. wasm_api.dart which will expose the interfaces found in module.dart and all error types without the implementation details (it will be unused for the moment, to be migrated to in a subsequent PR).
  2. a migration from using constructors to construct a WasmModule instance to using a top level function to construct a WasmModule instance.
  3. all declarations (excluding the top level factory functions from 2.) in module.dart will be made private and the interfaces from wasm_api.dart will be exposed.

Slow CI

Once #112 (and some few other minor changes) land, we should be able to use prebuilt binaries for wasmer which will significantly speed up our CI.

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]);
  }
}

step 4 error

dart run wasm:setup
Could not find a file named "pubspec.yaml" in "/home/colatea/.pub-cache/hosted/pub.flutter-io.cn/boolean_selector-2.1.0".

`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.

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

Hi, when I use this "clang --target=wasm32 -nostdlib "-Wl,--export-all" "-Wl,--no-entry" -o square.wasm square.cc"

It reports error, error message is "error: unable to create target: 'No available targets are compatible with triple "wasm32"'
1 error generated."

I have do step by step this page "wasm basic usage".

And I have done (1),(2), (3), (4), and they are correct.

But, when I try to do (5) and run this command "clang --target=wasm32 -nostdlib "-Wl,--export-all" "-Wl,--no-entry" -o square.wasm square.cc", it is Failed.

Maybe, I think the target "wasm32" is not exists.

So, I run these command,
1, "rustup target add wasm32-wasi"
2, "rustup target add wasm32-unknown-unknown"
3, "rustup target add wasm32-unknown-emscripten"
by this page platform-support

These run correct, when I run "rustup target list", it shows "installed"

  • wasm32-unknown-emscripten (installed)
  • wasm32-unknown-unknown (installed)
  • wasm32-wasi (installed)

But, when I run "clang --print-targets", it shows
Registered Targets:

  • aarch64 - AArch64 (little endian)
  • aarch64_32 - AArch64 (little endian ILP32)
  • aarch64_be - AArch64 (big endian)
  • arm - ARM
  • arm64 - ARM64 (little endian)
  • arm64_32 - ARM64 (little endian ILP32)
  • armeb - ARM (big endian)
  • thumb - Thumb
  • thumbeb - Thumb (big endian)
  • x86 - 32-bit X86: Pentium-Pro and above
  • x86-64 - 64-bit X86: EM64T and AMD64

So, is something not correct about my operation?

import_error_test crash on exit

The crash is in the wasm imported function finalizers. With all the finalizers, the isolate shutdown flow is pretty complicated:

Test finishes (Dart code) -> Dart_ShutdownIsolate, finalizes weak handles (Dart VM, C++ code) -> wasm_func_finalizer (package:wasm, C++ code) -> wasm_func_delete (wasmer, Rust code) -> ... -> wasm_func_new_with_env::drop (wasmer, Rust code) -> _wasmFnImportFinalizer (package:wasm, Dart code)

That last step from Rust to Dart is where the crash is happening. I suppose it makes sense that this step would crash if the isolate is shutting down. I don't understand why this is only crashing in this one test though, since every pretty much every test has something like this flow. Need to investigate a bit more.

I've disabled this finalizer for now, since this only leaks a _WasmFnImport, which is small.

Failed to load dynamic library

Repro steps:

  1. Clone this repo, and run dart run wasm:setup to complete setup
  2. Create a new Dart app: cd ~/tmp; dart create wasmtest
  3. Add wasm to the pubspec (as a git dep)
  4. Add a small wasm app (like square.cc from readme) and compile to Wasm
  5. Replace bin/wasmtest.dart with:
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));
}
  1. Try to run: dart run

=>

mit-macbookpro4:wasmtest mit$ dart run
Unhandled exception:
Invalid argument(s): Failed to load dynamic library '/Users/mit/tmp/wasmtest/.dart_tool/wasm/libwasmer.dylib': dlopen(/Users/mit/tmp/wasmtest/.dart_tool/wasm/libwasmer.dylib, 1): image not found
#0      _open (dart:ffi-patch/ffi_dynamic_library_patch.dart:11:55)
#1      new DynamicLibrary.open (dart:ffi-patch/ffi_dynamic_library_patch.dart:20:12)
#2      new WasmRuntime._init (package:wasm/src/runtime.g.dart:118:47)
#3      runtime (package:wasm/src/runtime.dart:20:29)
#4      runtime (package:wasm/src/runtime.dart)
#5      new WasmModule (package:wasm/src/module.dart:21:14)
#6      main (file:///Users/mit/tmp/wasmtest/bin/wasmtest.dart:6:15)
#7      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:283:19)
#8      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

Dart bindings via javascript transpilation/execution.

I think it is safe to assume that all languages that have javascript as a compilation target will eventually support targeting wasm as a compilation target as well.

As part of the compilation pipeline of languages that target wasm today, it seems to be common to also generate bindings written in javascript to the generated wasm code (e.g. see Rust).

It would be very hard to convince all the languages that target wasm to also write bindings for Dart. What if we take the javascript that those compilation pipelines produce, and extract the wasm bindings out of them, and generate Dart bindings ourselves?

The open question here is whether this approach would be feasible. I can see the following levels of difficulty:

  • AST-based: Is it possible to extract enough information about the wasm bindings from the raw AST of javascript-based bindings?
  • Resolved-AST-based: Is it possible to extract enough information about the wasm bindings from the CST that had some simple transformations (such as name resolution) applied to it?
  • Type-flow-based: Is it possible to extract enough information about the wasm bindings from some resolved AST that had some types inferred using more complicated type flow based approaches?
  • Runtime-mirroring: Is it possible to extract enough information about the wasm bindings by simply executing the javascript bindings and using the prototype based nature of javascript and/or some other methods that allow reflection to extract enough information to generate Dart bindings?

I don't have enough insight into javascript to evaluate the Runtime-mirroring approach yet, but that would probably be the simplest.

To investigate this approach we should probably first collect some autogenerated javascript bindings and see if there's a common pattern there that we can make use of.

plans for publishing on pub?

I know this package is still very new but I wanted to check on what the plans are for publishing it on pub?

I ask as I already have a small package that is making successful use of it, but because its using this package as a git dependency, I'm blocked from publishing my package on pub as well.

Investigate generating bindings.

It would be good to have some machinery that is able to generate bindings for any given WASM module i.e. generate type-safe APIs in Dart that would allow us to use the declarations declared in a WASM module without having to use any unsafe features (i.e. casting) ourselves. There are some open questions:

  • Would it be practical to extract the type information from a wasm binary itself? This would not give us the best type information, because the type system of WASM seems limited, but it would give us some safety, and that safety could be guaranteed to be sound.

  • Consider dart: I think, a dart program compiled to wasm would have to store strings in an array of code units. We could create zero cost views over those code units using native dart APIs. However, how can we soundly prove that any given list of e.g. uint16 is meant to represent a String? Would the dart2wasm compiler have to generate the bindings? Should it generate some intermediary file that allows us to generate more refined bindings? Will dart2wasm store this information in the compiled WASM module itself? We should perhaps look into how other languages are tackling the generate-type-safe-bindings issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.