Stream: wasmtime

Topic: environment variables in wasm


view this post on Zulip Hanif Ariffin (Feb 07 2023 at 13:48):

Does wasm have the concept of a runtime environment variable? I can't seem to be able to get them through std::env::vars(). This reddit comment says that runtime env is not a thing? https://www.reddit.com/r/rust/comments/y5fpnn/accessing_environment_variables_from_rust_wasm/isjaurz/
however there's a function to inherit_env when building WasiCtxBuilder.
Is it because I am only executing an exported function?

let instance = linker.instantiate(&mut store, &module).unwrap();
        let handle_rpc = instance
            .get_typed_func::<(), (), _>(&mut store, "handle_rpc")
            .unwrap();
        for msg in io_rx {
            if let Ok(msg) = serde_json::to_string(&msg) {
                let _ = writeln!(stdin.write().unwrap(), "{msg}");
            }
            let _ = handle_rpc.call(&mut store, ());
        }

view this post on Zulip bjorn3 (Feb 07 2023 at 13:52):

Wasm itself doesn't have env vars, but wasi does. You can set env vars using the WasiCtx you put in the store. (wasi_ctx.push_env) Or using inherit_env on WasiCtxBuilder.

view this post on Zulip bjorn3 (Feb 07 2023 at 13:54):

Did you compile as wasi command (the default) or wasi reactor? If you compiled as wasi command see https://github.com/rust-lang/rust/issues/107635

The code: fn main() {} #[export_name="test"] pub fn test() {} would produce the following Wasm assembly on Rust 1.66.1 compiled with cargo build --target="wasm32-wasi": ;; ... t...

view this post on Zulip bjorn3 (Feb 07 2023 at 13:56):

As workaround it seems that you can add

[lib]
crate-type = ["cdylib"]

to Cargo.toml and move main.rs to lib.rs.

view this post on Zulip Hanif Ariffin (Feb 07 2023 at 15:08):

I have done as you asked and it still compiles as a command instead of a reactor (it doesn't expose _initialize). How do I debug/take a look at the generated wasm itself? I thought it's suppoesd to be human readable (looks like lisp) but it looks like gibberish in my text editor.

view this post on Zulip Lann Martin (Feb 07 2023 at 15:55):

There are both binary and text (WAT) forms. You can convert binary to WAT with the wasm-tools crate (the print subcommand).

view this post on Zulip Lann Martin (Feb 07 2023 at 15:56):

The wasm-tools dump subcommand is also useful for this kind of debugging

view this post on Zulip Hanif Ariffin (Feb 10 2023 at 07:33):

So I used wasm-tools print and after some grepping I found these. I have no idea what it actually means but it does seem to me that it is trying to load some environment variables?

hbina@akarin ~/g/lapce-prettier (master)> rg __wasm_call_ctors lapce-prettier.txt --context 2
47-  (import "wasi_snapshot_preview1" "environ_sizes_get" (func $__imported_wasi_snapshot_preview1_environ_sizes_get (;6;) (type 3)))
48-  (import "wasi_snapshot_preview1" "proc_exit" (func $__imported_wasi_snapshot_preview1_proc_exit (;7;) (type 0)))
49:  (func $__wasm_call_ctors (;8;) (type 9)
50-    call $__wasilibc_initialize_environ_eagerly
51-  )
--
310049-  )
310050-  (func $handle_rpc.command_export (;1490;) (type 9)
310051:    call $__wasm_call_ctors
310052-    call $handle_rpc
310053-    call $__wasm_call_dtors
hbina@akarin ~/g/lapce-prettier (master)> rg __wasilibc_initialize_environ_eagerly lapce-prettier.txt --context 2
48-  (import "wasi_snapshot_preview1" "proc_exit" (func $__imported_wasi_snapshot_preview1_proc_exit (;7;) (type 0)))
49-  (func $__wasm_call_ctors (;8;) (type 9)
50:    call $__wasilibc_initialize_environ_eagerly
51-  )
52-  (func $_ZN10serde_json5value2de11visit_array17h02b51c85ebb372c1E (;9;) (type 4) (param i32 i32)
--
282322-    global.set $__stack_pointer
282323-  )
282324:  (func $__wasilibc_initialize_environ_eagerly (;1311;) (type 9)
282325-    call $__wasilibc_initialize_environ
282326-  )

view this post on Zulip bjorn3 (Feb 10 2023 at 08:48):

__wasm_call_ctors is only called by _start (for a command) or _initialize (for a reactor). If you skip _start or _initialize, the env vars won't be initialized.

view this post on Zulip Hanif Ariffin (Feb 10 2023 at 09:08):

what if my wasm exports neither?

hbina@akarin ~/g/lapce-prettier (master)> just diagnose
cargo +nightly build --target="wasm32-wasi"
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s
wasm-tools print target/wasm32-wasi/debug/lapce_prettier.wasm > ./lapce_prettier.txt
rg -w "_start" lapce_prettier.txt --context 2 || true
rg -w "_initialize" lapce_prettier.txt --context 2 || true

__wasm_call_ctors is only called by _start (for a command) or _initialize (for a reactor). If you skip _start or _initialize, the env vars won't be initialized.

i dont think this is true? since

  1. it exports (export "handle_rpc" (func $handle_rpc.command_export))
  2. which in turn calls
  (func $handle_rpc.command_export (;8794;) (type 10)
    call $__wasm_call_ctors
    call $handle_rpc
    call $__wasm_call_dtors
  )

so every invocation of handle_rpc should initialize the env?

view this post on Zulip bjorn3 (Feb 10 2023 at 19:59):

For older versions of wasi-sdk exports other than _start get this wrapper too, but for the latest version this is no longer the case.


Last updated: Dec 23 2024 at 13:07 UTC