dart-archive/wasm

WasmError: Missing import: function

hnord-vdx opened this issue · 5 comments

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

a::a(int32, int32, int32, int32) is a function import, so you need to bind a Dart function to it in the WasmInstanceBuilder (the thing that the builder() function returns).

When you run it in JS, where is emscripten getting that function from?

I am not very familiar with wasm and emscripten.. The project (trust wallet core) that im compiling to wasm exposes functions through a C interface and has a set of .proto files. Is there a way to automatically bind generated dart protobuf code with the wasm module? It seems the javascript project does that.

"use strict";
// Copyright © 2017-2022 Trust Wallet.
//
// This file is part of Trust. The full Trust copyright notice, including
// terms governing use, modification, and redistribution, is contained in the
// file LICENSE at the root of the source code distribution tree.
Object.defineProperty(exports, "__esModule", { value: true });
exports.WalletCore = exports.TW = void 0;
var core_proto_1 = require("./generated/core_proto");
Object.defineProperty(exports, "TW", { enumerable: true, get: function () { return core_proto_1.TW; } });
var WalletCore = require("./lib/wallet-core"); //! .wasm file and js glue code
exports.WalletCore = WalletCore;

Edit: React JS example that uses the javascript project

I'm guessing it binds those function imports somewhere in this file. You need to provide those function imports, like this:

walletCoreWasm = mod.builder()
      ..addFunction('a', 'a', (int arg1, int arg2, int arg3, int arg4) {
        // Call your functions, eg the generated dart protobuf code.
      }))
    .build();

There's no way of automatically binding those functions.

The code you linked to is generated by emscripten. I guess for dart you have to do it manually. The only problem is I have no idea what the functions in the wasm module are as the names are obfuscated. Thanks for the pointers tho!

@hnord-vdx Did you find a way to use Wallet core in Flutter web?