WebAssembly / wabt

The WebAssembly Binary Toolkit
Apache License 2.0
6.72k stars 684 forks source link

[wasm2c] too few arguments to function `wasm2c_fac_instantiate` #2442

Closed DevLARLEY closed 1 month ago

DevLARLEY commented 1 month ago

Hello all, I've converted a wasm file I found online to C headers and source. ./wasm2c fac.wasm -o fac.c. I used the example main.cto build a starting point, but the compiler complains that I'm missing two arguments:

void wasm2c_fac_instantiate(w2c_fac* instance, struct w2c_env* w2c_env_instance, struct w2c_global* w2c_global_instance) {
  assert(wasm_rt_is_initialized());
  init_instance_import(instance, w2c_env_instance, w2c_global_instance);
  init_globals(instance);
  init_tables(instance);
  init_memories(instance);
  init_elem_instances(instance);
  init_data_instances(instance);
}

These do not seem to be required by the example c file here.

Any help is greatly appreciated!

keithw commented 1 month ago

The difference is that this module imports from two other module namespaces -- "env" and "global". So to instantiate this module, the owner has to provide instances of the other two modules, either as other Wasm modules that you've also converted with wasm2c, or as host code that you've implemented in C. The wasm2c README and the rot13 example give some examples of this. We don't have a single "example main.c" -- there's a differently main.c for each example, partly because the arguments required to instantiate each module depend on what it wants to import (and the interface it wants from the host).

The presence of imports from the "env" namespace suggests that your module is probably a .o file (from clang/LLVM) that's intended to be linked, not a completed Wasm module intended to be run in an engine. So, I guess, where did this Wasm module come from and are you sure it's the one you want to run? It's pretty rare to want to run a .o file directly.

DevLARLEY commented 1 month ago

By "example main.c" i meant the one shown in the wasm2c README. The WASM is definitely the only file and comes from a JavaScript library that contains 'control code' and this file in encoded in base64. The file itself is a YUV frame converter.

lib_player.zip

keithw commented 1 month ago

There are multiple main functions in the wasm2c README. The fac module doesn't import anything, so it doesn't require any additional arguments to instantiate it. The rot13 module imports from the host namespace and requires a host instance to instantiate it. (The JavaScript API is similar, e.g. WebAssembly.instantiate takes an importObject for whatever the module imports.)

It sounds like your module imports a bunch of functionality from the host, and comes with a JavaScript implementation of that host-side functionality. If you want to run this module in a "VMless engine" like wasm2c, you'll need an implementation of the host-side functionality in some language that can be linked with the wasm2c output. (E.g. C, C++, Rust, Fortran, etc.)