juancastillo0 / wasm_run

A WebAssembly executor for Dart and Flutter applications. Uses Rust's wasmtime optimizing runtime or wasmi interpreter to parse and execute WASM and WAT files.
https://juancastillo0.github.io/wasm_run/
MIT License
112 stars 10 forks source link

Fix Flutter undefined "Fd" #55

Closed michelerenzullo closed 5 months ago

michelerenzullo commented 5 months ago

Fix Flutter web undefined "Fd" since was missing the imports from browser_wasi_shim not auto-loaded by flutter web

michelerenzullo commented 5 months ago

Thanks for sharing a solution to this!

Gave some drive-by suggestions.

You welcome, took me some time before noticing that was so easy. Before this, to circumvent the import error, I wrote in dart 3 WASI API just to make it work my project. Open question: do we actually need our own Dart Runtime instead of relying on other projects?

  ...
  late Module module;
  final WasmImport clockTimeGet = WasmImport(
      "wasi_snapshot_preview1",
      "clock_time_get",
      WasmFunction(
        (int id, I64 precision, int ptr_time) {
          BigInt nanosecondsSinceEpoch =
              BigInt.from(DateTime.now().microsecondsSinceEpoch) *
                  BigInt.from(1000);
          module.view.setAll(ptr_time, int64ToList(nanosecondsSinceEpoch));
          return 0;
        },
        params: [ValueTy.i32, ValueTy.i64, ValueTy.i32],
        results: [ValueTy.i32],
      ));

  final WasmImport procExit = WasmImport(
    "wasi_snapshot_preview1",
    "proc_exit",
    WasmFunction(
      (int code) => throw Exception("Process exited with code ${code}"),
      params: [ValueTy.i32],
      results: [],
    ),
  );

  final WasmImport fdWrite = WasmImport(
      "wasi_snapshot_preview1",
      "fd_write",
      WasmFunction(
        (int fd, int iovs, int iovs_len, int nwritten) {
          // TO_DO Implement file descriptor
          int bytesWritten = 0;
          for (int i = 0; i < iovs_len; i++) {
            int offset = i * 8;
            int base = module.byteData.getUint32(iovs + offset, Endian.little);
            int len =
                module.byteData.getUint32(iovs + offset + 4, Endian.little);
            printf_dart(
                utf8.decode(module.byteData.buffer.asUint8List(base, len)));
            bytesWritten += len;
          }
          module.byteData.setUint32(nwritten, bytesWritten, Endian.little);
          //printf_dart(
          //   "bytes written: ${module.byteData.getUint32(nwritten, Endian.little)}");
          return 0;
        },
        params: [ValueTy.i32, ValueTy.i32, ValueTy.i32, ValueTy.i32],
        results: [ValueTy.i32],
      ));
  final WasmInstanceBuilder builder = (await compileWasmModule(WASM))
      .builder()
      .addImports([clockTimeGet, fdWrite, procExit]);
  module = Module(await builder.build());

  module.instance.getFunction("_initialize")!.inner();
  return module;
juancastillo0 commented 5 months ago

Thank you so much. There may be a way to load the script under the hood for flutter. I am loading it here https://github.com/juancastillo0/wasm_run/blob/6dc89ca63199c7589d84d4714405b87a5bb2f148/packages/wasm_run/lib/src/ffi/web.dart#L22-L69 and I don't remember having any issues, however maybe the debugger or something in flutter web changed.

do we actually need our own Dart Runtime instead of relying on other projects

What do you mean with "Dart Runtime"? do you mean implementing the wasi library in Dart?

michelerenzullo commented 5 months ago

Thank you so much. There may be a way to load the script under the hood for flutter. I am loading it here

https://github.com/juancastillo0/wasm_run/blob/6dc89ca63199c7589d84d4714405b87a5bb2f148/packages/wasm_run/lib/src/ffi/web.dart#L22-L69

and I don't remember having any issues, however maybe the debugger or something in flutter web changed.

do we actually need our own Dart Runtime instead of relying on other projects

What do you mean with "Dart Runtime"? do you mean implementing the wasi library in Dart?

I'm on flutter 3.13.9, perhaps is possible to fix it so that we are not force to add in index.html, will have a look.

Yes, just an idea, like the 3 simple wasi function in pure Dart that I wrote above