Use embedded API in the wasmtime-rust (#540)

This commit is contained in:
Yury Delendik
2019-11-13 09:15:37 -06:00
committed by Alex Crichton
parent 2737c5e8e5
commit 98266498af
13 changed files with 316 additions and 112 deletions

View File

@@ -21,6 +21,7 @@ wasmtime-interface-types = { path = "../../interface-types" }
wasmtime-jit = { path = "../../jit" }
wasmtime-rust-macro = { path = "./macro" }
wasmtime-wasi = { path = "../../wasi" }
wasmtime = { path = "../../api" }
anyhow = "1.0.19"
[badges]

View File

@@ -34,8 +34,7 @@ fn generate_struct(item: &syn::ItemTrait) -> syn::Result<TokenStream> {
let root = root();
Ok(quote! {
#vis struct #name {
cx: #root::wasmtime_jit::Context,
handle: #root::wasmtime_jit::InstanceHandle,
instance: #root::wasmtime_api::HostRef<#root::wasmtime_api::Instance>,
data: #root::wasmtime_interface_types::ModuleData,
}
})
@@ -49,34 +48,53 @@ fn generate_load(item: &syn::ItemTrait) -> syn::Result<TokenStream> {
#vis fn load_file(path: impl AsRef<std::path::Path>) -> #root::anyhow::Result<#name> {
let bytes = std::fs::read(path)?;
let isa = {
let isa_builder = #root::cranelift_native::builder()
.map_err(|s| #root::anyhow::format_err!("{}", s))?;
let flag_builder = #root::cranelift_codegen::settings::builder();
isa_builder.finish(#root::cranelift_codegen::settings::Flags::new(flag_builder))
};
use #root::wasmtime_api::{HostRef, Config, Extern, Engine, Store, Instance, Module};
use #root::anyhow::{bail, format_err};
let config = {
let flag_builder = #root::cranelift_codegen::settings::builder();
let flags = #root::cranelift_codegen::settings::Flags::new(flag_builder);
let features = #root::wasmtime_jit::Features {
multi_value: true,
..Default::default()
};
let strategy = #root::wasmtime_jit::CompilationStrategy::Auto;
Config::new(flags, features, false, strategy)
};
let engine = HostRef::new(Engine::new(config));
let store = HostRef::new(Store::new(&engine));
let global_exports = store.borrow().global_exports().clone();
let mut cx = #root::wasmtime_jit::Context::with_isa(
isa,
#root::wasmtime_jit::CompilationStrategy::Auto
).with_features(#root::wasmtime_jit::Features {
multi_value: true,
..Default::default()
});
let data = #root::wasmtime_interface_types::ModuleData::new(&bytes)?;
let module = HostRef::new(Module::new(&store, &bytes)?);
let mut imports: Vec<Extern> = Vec::new();
if let Some(module_name) = data.find_wasi_module_name() {
let wasi_handle = wasmtime_wasi::instantiate_wasi(
"",
cx.get_global_exports(),
global_exports,
&[],
&[],
&[],
)?;
cx.name_instance(module_name, wasi_handle);
let wasi_instance = Instance::from_handle(&store, wasi_handle)?;
for i in module.borrow().imports().iter() {
if i.module().as_str() != module_name {
bail!("unknown import module {}", i.module().as_str());
}
if let Some(export) = wasi_instance.find_export_by_name(i.name().as_str()) {
imports.push(export.clone());
} else {
bail!("unknown import {}:{}", i.module().as_str(), i.name().as_str())
}
}
}
let handle = cx.instantiate_module(None, &bytes)?;
let instance = HostRef::new(
Instance::new(&store, &module, &imports).map_err(|t| format_err!("instantiation trap: {:?}", t))?
);
Ok(#name { cx, handle, data })
Ok(#name { instance, data })
}
})
}
@@ -156,9 +174,8 @@ fn generate_methods(item: &syn::ItemTrait) -> syn::Result<TokenStream> {
let args = [
#(#args),*
];
let results = self.data.invoke(
&mut self.cx,
&mut self.handle,
let results = self.data.invoke_export(
&self.instance,
stringify!(#name),
&args,
).expect("wasm execution failed");

View File

@@ -6,6 +6,7 @@ pub mod __rt {
pub use anyhow;
pub use cranelift_codegen;
pub use cranelift_native;
pub use wasmtime_api;
pub use wasmtime_interface_types;
pub use wasmtime_jit;