got imorts working

This commit is contained in:
elfein 2021-11-10 21:56:35 -08:00
parent 2840c8ae97
commit 04859555e9

View file

@ -2,8 +2,8 @@ extern crate wabt;
extern crate wasmi; extern crate wasmi;
use wasmi::{ use wasmi::{
Error, Externals, FuncInstance, FuncRef, ImportsBuilder, ModuleImportResolver, ModuleInstance, Error, Externals, FuncInstance, FuncRef, ImportsBuilder, ModuleImportResolver, ModuleInstance,
RuntimeArgs, RuntimeValue, Signature, Trap, ValueType, RuntimeArgs, RuntimeValue, Signature, Trap, ValueType,
}; };
pub const KILL: usize = 0; pub const KILL: usize = 0;
@ -11,95 +11,97 @@ pub const ADD_FUNC_INDEX: usize = 1;
struct HostFunctions; struct HostFunctions;
impl HostFunctions { impl HostFunctions {
fn check_signature(&self, index: usize, signature: &Signature) -> bool { fn check_signature(&self, index: usize, signature: &Signature) -> bool {
let (params, ret_ty): (&[ValueType], Option<ValueType>) = match index { let (params, ret_ty): (&[ValueType], Option<ValueType>) = match index {
ADD_FUNC_INDEX => (&[ValueType::I32, ValueType::I32], Some(ValueType::I32)), ADD_FUNC_INDEX => (&[ValueType::I32, ValueType::I32], Some(ValueType::I32)),
_ => return false, _ => return false,
}; };
signature.params() == params && signature.return_type() == ret_ty signature.params() == params && signature.return_type() == ret_ty
} }
} }
impl Externals for HostFunctions { impl Externals for HostFunctions {
fn invoke_index( fn invoke_index(
&mut self, &mut self,
index: usize, index: usize,
args: RuntimeArgs, args: RuntimeArgs,
) -> Result<Option<RuntimeValue>, Trap> { ) -> Result<Option<RuntimeValue>, Trap> {
match index { match index {
ADD_FUNC_INDEX => { ADD_FUNC_INDEX => {
println!("you pe"); println!("you pe");
let a: u32 = args.nth_checked(0)?; let a: u32 = args.nth_checked(0)?;
let b: u32 = args.nth_checked(1)?; let b: u32 = args.nth_checked(1)?;
let result = a + b; let result = a + b;
Ok(Some(RuntimeValue::I32(result as i32))) Ok(Some(RuntimeValue::I32(result as i32)))
} }
_ => panic!("Unimplemented function at {}", index), _ => panic!("Unimplemented function at {}", index),
} }
} }
} }
impl ModuleImportResolver for HostFunctions { impl ModuleImportResolver for HostFunctions {
fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result<FuncRef, Error> { fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result<FuncRef, Error> {
let index = match field_name { let index = match field_name {
"add" => ADD_FUNC_INDEX, "add" => ADD_FUNC_INDEX,
_ => { _ => {
return Err(Error::Instantiation(format!(
"Export {} not found",
field_name
)))
}
};
if !self.check_signature(index, signature) {
return Err(Error::Instantiation(format!( return Err(Error::Instantiation(format!(
"Export {} has a bad signature", "Export {} not found",
field_name field_name
))); )))
} }
};
Ok(FuncInstance::alloc_host( if !self.check_signature(index, signature) {
Signature::new(&[ValueType::I32, ValueType::I32][..], Some(ValueType::I32)), return Err(Error::Instantiation(format!(
index, "Export {} has a bad signature",
)) field_name
} )));
}
Ok(FuncInstance::alloc_host(
Signature::new(&[ValueType::I32, ValueType::I32][..], Some(ValueType::I32)),
index,
))
}
} }
fn main() { fn main() {
// Parse WAT (WebAssembly Text format) into wasm bytecode. // Parse WAT (WebAssembly Text format) into wasm bytecode.
let wasm_binary = wabt::wat2wasm(include_str!("test.wat")); let wasm_binary = wabt::wat2wasm(include_str!("test.wat"));
let wasm_binary = match wasm_binary { let wasm_binary = match wasm_binary {
Ok(abc) => abc, Ok(abc) => abc,
Err(abc) => { Err(abc) => {
println!("{}", abc); println!("{}", abc);
return; return;
} }
}; };
// .expect("failed to parse wat"); // .expect("failed to parse wat");
// Load wasm binary and prepare it for instantiation. // Load wasm binary and prepare it for instantiation.
let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm"); let module = wasmi::Module::from_buffer(&wasm_binary).expect("failed to load wasm");
// Instantiate a module with empty imports and let imports = ImportsBuilder::new().with_resolver("host", &HostFunctions);
// assert that there is no `start` function.
let instance = ModuleInstance::new(&module, &ImportsBuilder::default())
.expect("failed to instantiate wasm module")
.assert_no_start();
// Finally, invoke the exported function "test" with no parameters // Instantiate a module with empty imports and
// and empty external function executor. // assert that there is no `start` function.
let result: i32 = instance let instance = ModuleInstance::new(&module, &imports)
.invoke_export("main", &[], &mut HostFunctions) .expect("failed to instantiate wasm module")
// .with_resolver(&mut HostFunctions) .assert_no_start();
.expect("failed to execute export")
.unwrap()
.try_into()
.unwrap();
println!( // Finally, invoke the exported function "test" with no parameters
"{:?}", // and empty external function executor.
result // .unwrap() let result: i32 = instance
); .invoke_export("main", &[], &mut HostFunctions)
// .with_resolver(&mut HostFunctions)
.expect("failed to execute export")
.unwrap()
.try_into()
.unwrap();
println!(
"{:?}",
result // .unwrap()
);
} }