Stream: git-wasmtime

Topic: wasmtime / Issue #1889 [wasm-rust#writing-libraries] samp...


view this post on Zulip Wasmtime GitHub notifications bot (Jun 16 2020 at 23:21):

l0yu opened Issue #1889:

https://bytecodealliance.github.io/wasmtime/wasm-rust.html#writing-libraries

^^ I am following example to build a library with one function print_hello

when run wasmtime --invoke print_hello target/wasm32-wasi/debug/hello_world.wasm
I get

Error: failed to run main module `target/wasm32-wasi/debug/hello_world.wasm`

Caused by:
    multiple tables: tables count must be at most 1 (at offset 557)

wasmtime version 0.17.0

view this post on Zulip Wasmtime GitHub notifications bot (Jun 17 2020 at 14:52):

alexcrichton commented on Issue #1889:

Thanks for the report! This is a known issue if you're using wasm-bindgen where wasmtime doesn't have full support for interface types just yet. The sample code that doesn't use wasm-bindgen should work alright though!

view this post on Zulip Wasmtime GitHub notifications bot (Jun 17 2020 at 16:31):

l0yu commented on Issue #1889:

you are right, I cleaned local wasm bits with wasm-bindgen and build new one with #[no_mangle] only
wasttime command line is working.

I further try call print_hello in my rust program reference sample in doc. but get

Error: wrong number of imports provided, 0 != 4

the difference between sample is I am using .wasm in previous instead of .wat - wasm text
as library.

hello_world lib

#[no_mangle]
pub extern "C" fn print_hello() {
    println!("Hello, world!");
}

rust program calling the lib

fn main() -> Result<(), Box<dyn Error>> {
    let engine = Engine::default();
    // A `Store` is a sort of "global object" in a sense, but for now it suffices
    // to say that it's generally passed to most constructors.
    let store = Store::new(&engine);

    // We start off by creating a `Module` which represents a compiled form
    // of our input wasm module. In this case it'll be JIT-compiled after
    // we parse the text format.
    let module = Module::from_file(&engine, "./lib/print_hello.wasm")?;

    // After we have a compiled `Module` we can then instantiate it, creating
    // an `Instance` which we can actually poke at functions on.
    // &[] -  import none of host function
    let instance = Instance::new(&store, &module, &[])?;

    // The `Instance` gives us access to various exported functions and items,
    // which we access here to pull out our `print_hello` exported function and
    // run it.
    let print_hello = instance.get_func("print_hello")
        .expect("`print_hello` was not an exported function");

    let print_hello = print_hello.get0::<()>()?;
    print_hello()?;
    Ok(())
}
cargo run
Error: wrong number of imports provided, 0 != 4

view this post on Zulip Wasmtime GitHub notifications bot (Jun 17 2020 at 16:40):

alexcrichton commented on Issue #1889:

You're compiling for the wasm32-wasi target which means you might import wasi functionality from the host (which println! does, for example). You'll want to follow the linking example to link in wasi support.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 17 2020 at 17:03):

l0yu commented on Issue #1889:

you are right, referencing example ^^ , I added WASI sdk and it print_hello wasm lib works !
is println! a system level function so that host app should provide WASI sdk ?

working code

use std::error::Error;
use wasmtime::*;
use wasmtime_wasi::{Wasi, WasiCtx};

fn main() -> Result<(), Box<dyn Error>> {
    let engine = Engine::default();
    // A `Store` is a sort of "global object" in a sense, but for now it suffices
    // to say that it's generally passed to most constructors.
    let store = Store::new(&engine);

    // Create an instance of `Wasi` which contains a `WasiCtx`. Note that
    // `WasiCtx` provides a number of ways to configure what the target program
    // will have access to.
    let mut linker = Linker::new(&store);
    let wasi = Wasi::new(&store, WasiCtx::new(std::env::args())?);
    wasi.add_to_linker(&mut linker)?;

    // We start off by creating a `Module` which represents a compiled form
    // of our input wasm module. In this case it'll be JIT-compiled after
    // we parse the text format.
    let module = Module::from_file(&engine, "./lib/print_hello.wasm")?;

    // Instantiate module use WASI
    let instance = linker.instantiate(&module)?;

    // The `Instance` gives us access to various exported functions and items,
    // which we access here to pull out our `print_hello` exported function and
    // run it.
    let print_hello = instance.get_func("print_hello")
        .expect("`print_hello` was not an exported function");

    let print_hello = print_hello.get0::<()>()?;
    print_hello()?;
    Ok(())
}

with dependency

[dependencies]
wasmtime = "0.18.0"
wasmtime-wasi = "0.18.0"
cargo run
Hello, world!

view this post on Zulip Wasmtime GitHub notifications bot (Jun 17 2020 at 17:04):

l0yu edited a comment on Issue #1889:

you are right, referencing example ^^ , I added WASI sdk and print_hello wasm lib works in host rust app!
is println! a system level function so that host app should provide WASI sdk ?

working code

use std::error::Error;
use wasmtime::*;
use wasmtime_wasi::{Wasi, WasiCtx};

fn main() -> Result<(), Box<dyn Error>> {
    let engine = Engine::default();
    // A `Store` is a sort of "global object" in a sense, but for now it suffices
    // to say that it's generally passed to most constructors.
    let store = Store::new(&engine);

    // Create an instance of `Wasi` which contains a `WasiCtx`. Note that
    // `WasiCtx` provides a number of ways to configure what the target program
    // will have access to.
    let mut linker = Linker::new(&store);
    let wasi = Wasi::new(&store, WasiCtx::new(std::env::args())?);
    wasi.add_to_linker(&mut linker)?;

    // We start off by creating a `Module` which represents a compiled form
    // of our input wasm module. In this case it'll be JIT-compiled after
    // we parse the text format.
    let module = Module::from_file(&engine, "./lib/print_hello.wasm")?;

    // Instantiate module use WASI
    let instance = linker.instantiate(&module)?;

    // The `Instance` gives us access to various exported functions and items,
    // which we access here to pull out our `print_hello` exported function and
    // run it.
    let print_hello = instance.get_func("print_hello")
        .expect("`print_hello` was not an exported function");

    let print_hello = print_hello.get0::<()>()?;
    print_hello()?;
    Ok(())
}

with dependency

[dependencies]
wasmtime = "0.18.0"
wasmtime-wasi = "0.18.0"
cargo run
Hello, world!

view this post on Zulip Wasmtime GitHub notifications bot (Jun 17 2020 at 17:05):

l0yu edited a comment on Issue #1889:

you are right, referencing example ^^ , I added WASI sdk and print_hello wasm lib works in host rust app!
is println! a system level function so that host app should provide WASI sdk for wasm lib ?

working code

use std::error::Error;
use wasmtime::*;
use wasmtime_wasi::{Wasi, WasiCtx};

fn main() -> Result<(), Box<dyn Error>> {
    let engine = Engine::default();
    // A `Store` is a sort of "global object" in a sense, but for now it suffices
    // to say that it's generally passed to most constructors.
    let store = Store::new(&engine);

    // Create an instance of `Wasi` which contains a `WasiCtx`. Note that
    // `WasiCtx` provides a number of ways to configure what the target program
    // will have access to.
    let mut linker = Linker::new(&store);
    let wasi = Wasi::new(&store, WasiCtx::new(std::env::args())?);
    wasi.add_to_linker(&mut linker)?;

    // We start off by creating a `Module` which represents a compiled form
    // of our input wasm module. In this case it'll be JIT-compiled after
    // we parse the text format.
    let module = Module::from_file(&engine, "./lib/print_hello.wasm")?;

    // Instantiate module use WASI
    let instance = linker.instantiate(&module)?;

    // The `Instance` gives us access to various exported functions and items,
    // which we access here to pull out our `print_hello` exported function and
    // run it.
    let print_hello = instance.get_func("print_hello")
        .expect("`print_hello` was not an exported function");

    let print_hello = print_hello.get0::<()>()?;
    print_hello()?;
    Ok(())
}

with dependency

[dependencies]
wasmtime = "0.18.0"
wasmtime-wasi = "0.18.0"
cargo run
Hello, world!

view this post on Zulip Wasmtime GitHub notifications bot (Jun 17 2020 at 17:06):

l0yu closed Issue #1889:

https://bytecodealliance.github.io/wasmtime/wasm-rust.html#writing-libraries

^^ I am following example to build a library with one function print_hello

when run wasmtime --invoke print_hello target/wasm32-wasi/debug/hello_world.wasm
I get

Error: failed to run main module `target/wasm32-wasi/debug/hello_world.wasm`

Caused by:
    multiple tables: tables count must be at most 1 (at offset 557)

wasmtime version 0.17.0


Last updated: Dec 23 2024 at 13:07 UTC