I am not sure how much WASI support wabt's wasm2c has, but it does show up
in tests and examples:

https://github.com/WebAssembly/wabt/blob/0583f0f664ccd481f4e8e5a29328b3b987881701/test/wasm2c/hello.txt#L4

Asking in a wabt issue might be the best place to find people that know
those details.


On Sun, Dec 1, 2024 at 9:12 AM guest271314 <guest271...@gmail.com> wrote:

> I compiled JavaScript to Web Assembly using Bytecode Alliance's Javy. I
> then compiled the `.wasm` to C using WABT's `wasm2c`. Now I am trying to
> compile the resulting C to a standalone executable.
>
> ```
> ./javy emit-plugin -o plugin.wasm
> ./javy build -C dynamic -C plugin=plugin.wasm -o javy-permutations.wasm
> permutations.js
> ```
>
> The code can be run using
>
> ```
> wasmtime run --preload javy_quickjs_provider_v3=plugin.wasm
> javy-permutations.wasm
> ```
> Compiling WASM to C
>
> ```
> ./wabt/bin/wasm2c javy-permutations.wasm -n array_nth_permutation -o
> javy-permutations.c
> ```
>
> ```
> ./wabt/bin/wasm2c plugin.wasm -n w2c_javy__quickjs__provider__v3 -o
> plugin.c
> ```
>
> which writes `plugin.c` and `plugin.h` to the filesystem. The Javy
> implementation of WebAssembly toolchain.
>
> I also, in my attempts to replicate a working JavaScript implementation of
> this using Node.js
> https://github.com/bytecodealliance/javy/blob/main/docs/docs-using-nodejs.md,
> compiled `wasi_snapshot_preview1.reactor.wasm` to C using `wasm2c`. I have
> not been able to reproduce what I do using JavaScript in C.
>
> I was able to achieve the result for the factorial example in `wasm2c`
> https://github.com/WebAssembly/wabt/blob/main/wasm2c/README.md#tutorial-wat---wasm---c.
>
>
> There's no examples in `wasm2c` for compiling WASI to a standalone
> executable.
>
> Here's one version of the working JavaScript version that I'm trying to
> reproduce in C
>
> ```
> import { readFile } from "node:fs/promises";
> import { WASI } from "node:wasi";
>
> try {
>   const [embeddedModule, pluginModule] = await Promise.all([
>     compileModule("./javy-permutations.wasm"),
>     compileModule("./plugin.wasm"),
>   ]);
>   const result = await runJavy(pluginModule, embeddedModule);
>   // console.log("Success!", JSON.stringify(result, null, 2));
> } catch (e) {
>   console.log(e);
> }
>
> async function compileModule(wasmPath) {
>   const bytes = await readFile(new URL(wasmPath, import.meta.url));
>   return WebAssembly.compile(bytes);
> }
>
> async function runJavy(pluginModule, embeddedModule) {
>   /*
>   // Use stdin/stdout/stderr to communicate with Wasm instance
>   // See
> https://k33g.hashnode.dev/wasi-communication-between-nodejs-and-wasm-modules-another-way-with-stdin-and-stdout
>   */
>   try {
>     const wasi = new WASI({
>       version: "preview1",
>       args: [],
>       env: {},
>       returnOnExit: true,
>     });
>
>     const pluginInstance = await WebAssembly.instantiate(
>       pluginModule,
>       { "wasi_snapshot_preview1": wasi.wasiImport },
>     );
>     const instance = await WebAssembly.instantiate(
>       embeddedModule,
>       { "javy_quickjs_provider_v3": pluginInstance.exports },
>     );
>     console.log(pluginInstance.exports);
>     // Javy plugin is a WASI reactor see
> https://github.com/WebAssembly/WASI/blob/main/legacy/application-abi.md?plain=1
>     wasi.initialize(pluginInstance);
>     instance.exports._start();
>     return "Done";
>   } catch (e) {
>     console.log(e);
>     if (e instanceof WebAssembly.RuntimeError) {
>       if (errorMessage) {
>         throw new Error(errorMessage);
>       }
>     }
>     throw e;
>   } finally {
>     // console.log("Finally");
>   }
> }
>
> ```
>
>
> Here's `javy-permutations.h`
>
> ```
> /* Automatically generated by wasm2c */
> #ifndef JAVY_PERMUTATIONS_H_GENERATED_
> #define JAVY_PERMUTATIONS_H_GENERATED_
>
> #include "wasm-rt.h"
>
> #include <stdint.h>
>
> #ifndef WASM_RT_CORE_TYPES_DEFINED
> #define WASM_RT_CORE_TYPES_DEFINED
> typedef uint8_t u8;
> typedef int8_t s8;
> typedef uint16_t u16;
> typedef int16_t s16;
> typedef uint32_t u32;
> typedef int32_t s32;
> typedef uint64_t u64;
> typedef int64_t s64;
> typedef float f32;
> typedef double f64;
> #endif
>
> #ifdef __cplusplus
> extern "C" {//
> #endif
>
> struct w2c_javy__quickjs__provider__v3;
> extern wasm_rt_memory_t* w2c_javy__quickjs__provider__v3_memory(struct
> w2c_javy__quickjs__provider__v3*);
>
> typedef struct w2c_array__nth__permutation {
>   struct w2c_javy__quickjs__provider__v3*
> w2c_javy__quickjs__provider__v3_instance;
>   /* import: 'javy_quickjs_provider_v3' 'memory' */
>   wasm_rt_memory_t *w2c_javy__quickjs__provider__v3_memory;
>   bool data_segment_dropped_w2c_array__nth__permutation_d0 : 1;
> } w2c_array__nth__permutation;
>
> void
> wasm2c_array__nth__permutation_instantiate(w2c_array__nth__permutation*,
> struct w2c_javy__quickjs__provider__v3*);
> void wasm2c_array__nth__permutation_free(w2c_array__nth__permutation*);
> wasm_rt_func_type_t wasm2c_array__nth__permutation_get_func_type(uint32_t
> param_count, uint32_t result_count, ...);
>
> /* import: 'javy_quickjs_provider_v3' 'canonical_abi_realloc' */
> u32 w2c_javy__quickjs__provider__v3_canonical_abi_realloc(struct
> w2c_javy__quickjs__provider__v3*, u32, u32, u32, u32);
>
> /* import: 'javy_quickjs_provider_v3' 'invoke' */
> void w2c_javy__quickjs__provider__v3_invoke(struct
> w2c_javy__quickjs__provider__v3*, u32, u32, u32, u32);
>
> extern const u64
> wasm2c_array__nth__permutation_min_javy__quickjs__provider__v3_memory;
> extern const u64
> wasm2c_array__nth__permutation_max_javy__quickjs__provider__v3_memory;
> extern const u8
> wasm2c_array__nth__permutation_is64_javy__quickjs__provider__v3_memory;
>
> /* export: '_start' */
> void w2c_array__nth__permutation_0x5Fstart(w2c_array__nth__permutation*);
>
> #ifdef __cplusplus
> }
> #endif
>
> #endif  /* JAVY_PERMUTATIONS_H_GENERATED_ */
> ```
>
> Here's what I tried so far in `main.javy.c`
>
> ```
> #include <stdio.h>
> #include <stdlib.h>
>
> #include "javy-permutations.h"
> #include "plugin.h"
>
> int main(int argc, char** argv) {
>   /* Make sure there is at least one command-line argument. */
>   if (argc < 2) {
>     printf("Invalid argument. Expected '%s NUMBER'\n", argv[0]);
>     return 1;
>   }
>
>   /* Convert the argument from a string to an int. We'll implicitly cast
> the int
>   to a `u32`, which is what `fac` expects. */
>   // u32 x = atoi(argv[1]);
>
>   /* Initialize the Wasm runtime. */
>   wasm_rt_init();
>
>   /* Declare an instance of the `fac` module. */
>   w2c_array__nth__permutation array__nth__permutation;
>
>   w2c_javy__quickjs__provider__v3 provider;
>
>   /* Construct the module instance. */
>   wasm2c_array__nth__permutation_instantiate(&array__nth__permutation,
> &provider);
>
>   /* Call `fac`, using the mangled name. */
>   // u32 result = w2c_fac_fac(&fac, x);
>
>   /* Print the result. */
>   // printf("fac(%u) -> %u\n", x, result);
>   w2c_array__nth__permutation_0x5Fstart(array__nth__permutation*)
>   /* Free the fac module. */
>
> w2c_w2c__javy__0x5Fquickjs__0x5Fprovider__0x5Fv3_canonical_abi_free(w2c_w2c__javy__0x5Fquickjs__0x5Fprovider__0x5Fv3*,
> u32, u32, u32);
>
>   /* Free the Wasm runtime state. */
>   wasm_rt_free();
>
>   return 0;
> }
> ```
>
>
> which throws errors when trying to compile
>
> ```
> cc -o javy-permutations main.javy.c javy-permutations.c
> wasm2c/wasm-rt-impl.c wasm2c/wasm-rt-mem-impl.c -Iwasm2c -lm
> main.javy.c: In function ‘main’:
> main.javy.c:24:3: error: unknown type name
> ‘w2c_javy__quickjs__provider__v3’; use ‘struct’ keyword to refer to the type
>    24 |   w2c_javy__quickjs__provider__v3 provider;
>       |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>       |   struct
> main.javy.c:27:72: warning: passing argument 2 of
> ‘wasm2c_array__nth__permutation_instantiate’ from incompatible pointer type
> [-Wincompatible-pointer-types]
>    27 | ray__nth__permutation_instantiate(&array__nth__permutation,
> &provider);
>       |
> ^~~~~~~~~
>       |                                                             |
>       |                                                             int *
>
> In file included from main.javy.c:4:
> javy-permutations.h:37:79: note: expected ‘struct
> w2c_javy__quickjs__provider__v3 *’ but argument is of type ‘int *’
>    37 | _nth__permutation_instantiate(w2c_array__nth__permutation*, struct
> w2c_javy__quickjs__provider__v3*);
>       |
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> main.javy.c:34:65: error: expected expression before ‘)’ token
>    34 |   w2c_array__nth__permutation_0x5Fstart(array__nth__permutation*)
>       |
> ```
>
> I suspect I need to initialize import `wasi_snapshot_preview` into the
> plugin in C, though I am not sure how to do that.
>
> --
> You received this message because you are subscribed to the Google Groups
> "emscripten-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to emscripten-discuss+unsubscr...@googlegroups.com.
> To view this discussion visit
> https://groups.google.com/d/msgid/emscripten-discuss/66e87783-4f35-482d-a6ae-c538477abf2an%40googlegroups.com
> <https://groups.google.com/d/msgid/emscripten-discuss/66e87783-4f35-482d-a6ae-c538477abf2an%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to emscripten-discuss+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/emscripten-discuss/CAEX4NpSFBgzGci6HgiRsy2%3Dg1Cdf64cuL%3D_i_Fr1WiC4Ec8H8g%40mail.gmail.com.

Reply via email to