WasmEdge
WasmEdge copied to clipboard
Validation Error
Hi @hydai @q82419,
I ran into a validation failure when I was trying to call an async wasm function from a wasm file. The detailed steps are described below. Could you please help check it? Thanks a lot!
Create and build test.wasm
I created a wasm library with the following three functions and used cargo build --target wasm32-wasi --release
command to generate test.wasm
:
// lib.rs
#[no_mangle]
pub async fn hundred() -> i32 {
println!("sleep 500ms first");
std::thread::sleep(std::time::Duration::from_millis(500));
100
}
#[no_mangle]
pub async fn echo(num: i32) -> i32 {
println!("sleep 500ms first");
std::thread::sleep(std::time::Duration::from_millis(500));
num
}
#[no_mangle]
pub async fn plus_one(num: i32) -> i32 {
println!("sleep 500ms first");
std::thread::sleep(std::time::Duration::from_millis(500));
num + 1
}
// Cargo.toml
[lib]
crate-type = ["cdylib"]
The details of test.wasm
are as below:
// test.wasm
(module
(type $t0 (func (result i32)))
(type $t1 (func (param i32 i32)))
(type $t2 (func))
(func $hundred (type $t0) (result i32)
i32.const 0)
(func $echo (type $t1) (param $p0 i32) (param $p1 i32)
local.get $p0
i32.const 0
i32.store8 offset=4
local.get $p0
local.get $p1
i32.store)
(func $dummy (type $t2))
(func $__wasm_call_dtors (type $t2)
call $dummy
call $dummy)
(func $hundred.command_export (type $t0) (result i32)
call $hundred
call $__wasm_call_dtors)
(func $echo.command_export (type $t1) (param $p0 i32) (param $p1 i32)
local.get $p0
local.get $p1
call $echo
call $__wasm_call_dtors)
(func $plus_one.command_export (type $t1) (param $p0 i32) (param $p1 i32)
local.get $p0
local.get $p1
call $echo
call $__wasm_call_dtors)
(table $T0 1 1 funcref)
(memory $memory 16)
(global $g0 (mut i32) (i32.const 1048576))
(global $__heap_base i32 (i32.const 1048576))
(global $__data_end i32 (i32.const 1048576))
(export "memory" (memory 0))
(export "__heap_base" (global 1))
(export "__data_end" (global 2))
(export "hundred" (func $hundred.command_export))
(export "echo" (func $echo.command_export))
(export "plus_one" (func $plus_one.command_export)))
Create and run example code
Then, I used test.wasm
in the following example and tried to call the export asynchronous function plus_one
:
use wasmedge_sys::{Executor, Loader, Store, WasmValue};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let wasm_file = std::path::Path::new(
"/Volumes/Dev/secondstate/me/issue/issue-1580/target/wasm32-wasi/release/test.wasm",
);
let loader = Loader::create(None)?;
let module = loader.from_file(&wasm_file)?;
println!("count of exports: {}", module.count_of_exports());
module.exports().iter().for_each(|ty| {
println!("export name: {}", ty.name());
println!("export type: {:?}", ty.ty());
});
let mut executor = Executor::create(None, None)?;
let mut store = Store::create()?;
// register module
let instance = executor.register_named_module(&mut store, &module, "extern")?; // an error is raised in this step
// get the export async function `plus_one`
let plus_one = instance.get_func("plus_one")?;
// call the async function
let returns = plus_one.call(&mut executor, [WasmValue::from_i32(99)])?;
println!("result: {}", returns[0].to_i32());
Ok(())
}
An error is raised while registering the module into the store:
[2022-09-20 16:06:28.880] [error] wasmedge runtime failed: wasm module hasn't passed validation yet, Code: 0x08
[2022-09-20 16:06:28.880] [error] At AST node: module
Error: Core(Common(NotValidated))
Before instantiate, please validate the module by validator.
Before instantiate, please validate the module by validator.
Yes, you're right. The error disappears while doing validation with a validator instance. But a new issue appears, please help with it. I refactored the example code above, and it looks like below now:
use wasmedge_sys::{Vm, WasmValue};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let wasm_file = std::path::Path::new("test.wasm");
let mut vm = Vm::create(None, None)?;
vm.register_wasm_from_file("extern", wasm_file)?;
let async_result = vm.run_registered_function_async(
"extern",
"plus_one",
[WasmValue::from_i32(10), WasmValue::from_i32(99)],
)?;
// get the result returned by the host function
let returns = async_result.get_async()?;
assert_eq!(returns.len(), 1);
Ok(())
}
The code failed in the last assertion. The length of the actual returns is 0, but not 1. Does WasmEdge_VMAsyncExecuteRegistered
interface support async wasm functions? If I was wrong in the example code above, please correct me. Thanks a lot!
I'll also post the same issue to the Rust toolchain community so that we can hear the voice about the issue from the outside.
Hi @apepkuss ,
Is this issue still active?