Remove the need for HostRef<Store> (#771)
* Remove the need for `HostRef<Store>` This commit goes through the public API of the `wasmtime` crate and removes the need for `HostRef<Store>`, as discussed in #708. This commit is accompanied with a few changes: * The `Store` type now also implements `Default`, creating a new `Engine` with default settings and returning that. * The `Store` type now implements `Clone`, and is documented as being a "cheap clone" aka being reference counted. As before there is no supported way to create a deep clone of a `Store`. * All APIs take/return `&Store` or `Store` instead of `HostRef<Store>`, and `HostRef<T>` is left as purely a detail of the C API. * The `global_exports` function is tagged as `#[doc(hidden)]` for now while we await its removal. * The `Store` type is not yet `Send` nor `Sync` due to the usage of `global_exports`, but it is intended to become so eventually. * Touch up comments on some examples * Run rustfmt
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
//! Example of instantiating of the WebAssembly module and
|
||||
//! invoking its exported function.
|
||||
|
||||
use anyhow::{format_err, Result};
|
||||
use wasmtime::*;
|
||||
|
||||
const WAT: &str = r#"
|
||||
@@ -34,14 +33,11 @@ const WAT: &str = r#"
|
||||
)
|
||||
"#;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
fn main() -> anyhow::Result<()> {
|
||||
// Load our WebAssembly (parsed WAT in our case), and then load it into a
|
||||
// `Module` which is attached to a `Store` cache.
|
||||
let wasm = wat::parse_str(WAT)?;
|
||||
|
||||
// Instantiate engine and store.
|
||||
let engine = Engine::default();
|
||||
let store = HostRef::new(Store::new(&engine));
|
||||
|
||||
// Load a module.
|
||||
let store = Store::default();
|
||||
let module = HostRef::new(Module::new(&store, &wasm)?);
|
||||
|
||||
// Find index of the `gcd` export.
|
||||
@@ -59,10 +55,7 @@ fn main() -> Result<()> {
|
||||
|
||||
// Invoke `gcd` export
|
||||
let gcd = instance.exports()[gcd_index].func().expect("gcd");
|
||||
let result = gcd
|
||||
.borrow()
|
||||
.call(&[Val::from(6i32), Val::from(27i32)])
|
||||
.map_err(|e| format_err!("call error: {:?}", e))?;
|
||||
let result = gcd.borrow().call(&[Val::from(6i32), Val::from(27i32)])?;
|
||||
|
||||
println!("{:?}", result);
|
||||
Ok(())
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Translation of hello example
|
||||
|
||||
use anyhow::{ensure, format_err, Context as _, Result};
|
||||
use anyhow::{ensure, Context as _, Result};
|
||||
use std::rc::Rc;
|
||||
use wasmtime::*;
|
||||
|
||||
@@ -15,11 +15,11 @@ impl Callable for HelloCallback {
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// Configure the initial compilation environment, creating more global
|
||||
// structures such as an `Engine` and a `Store`.
|
||||
// Configure the initial compilation environment, creating the global
|
||||
// `Store` structure. Note that you can also tweak configuration settings
|
||||
// with a `Config` and an `Engine` if desired.
|
||||
println!("Initializing...");
|
||||
let engine = Engine::default();
|
||||
let store = HostRef::new(Store::new(&engine));
|
||||
let store = Store::default();
|
||||
|
||||
// Next upload the `*.wasm` binary file, which in this case we're going to
|
||||
// be parsing an inline text format into a binary.
|
||||
@@ -59,10 +59,7 @@ fn main() -> Result<()> {
|
||||
|
||||
// And last but not least we can call it!
|
||||
println!("Calling export...");
|
||||
run_func
|
||||
.borrow()
|
||||
.call(&[])
|
||||
.map_err(|e| format_err!("> Error calling function: {:?}", e))?;
|
||||
run_func.borrow().call(&[])?;
|
||||
|
||||
println!("Done.");
|
||||
Ok(())
|
||||
|
||||
@@ -62,8 +62,7 @@ macro_rules! call {
|
||||
fn main() -> Result<(), Error> {
|
||||
// Initialize.
|
||||
println!("Initializing...");
|
||||
let engine = Engine::default();
|
||||
let store = HostRef::new(Store::new(&engine));
|
||||
let store = Store::default();
|
||||
|
||||
// Load binary.
|
||||
println!("Loading binary...");
|
||||
|
||||
@@ -46,7 +46,7 @@ fn main() -> Result<()> {
|
||||
// Initialize.
|
||||
println!("Initializing...");
|
||||
let engine = Engine::new(Config::new().wasm_multi_value(true));
|
||||
let store = HostRef::new(Store::new(&engine));
|
||||
let store = Store::new(&engine);
|
||||
|
||||
// Load binary.
|
||||
println!("Loading binary...");
|
||||
|
||||
@@ -43,8 +43,7 @@ use wasmtime_runtime::Export;
|
||||
/// "#)?;
|
||||
///
|
||||
/// // Initialise environment and our module.
|
||||
/// let engine = wasmtime::Engine::default();
|
||||
/// let store = HostRef::new(wasmtime::Store::new(&engine));
|
||||
/// let store = wasmtime::Store::default();
|
||||
/// let module = HostRef::new(wasmtime::Module::new(&store, &binary)?);
|
||||
///
|
||||
/// // Define the type of the function we're going to call.
|
||||
@@ -103,13 +102,13 @@ pub(crate) trait WrappedCallable {
|
||||
}
|
||||
|
||||
pub(crate) struct WasmtimeFn {
|
||||
store: HostRef<Store>,
|
||||
store: Store,
|
||||
instance: InstanceHandle,
|
||||
export: Export,
|
||||
}
|
||||
|
||||
impl WasmtimeFn {
|
||||
pub fn new(store: &HostRef<Store>, instance: InstanceHandle, export: Export) -> WasmtimeFn {
|
||||
pub fn new(store: &Store, instance: InstanceHandle, export: Export) -> WasmtimeFn {
|
||||
WasmtimeFn {
|
||||
store: store.clone(),
|
||||
instance,
|
||||
@@ -146,7 +145,6 @@ impl WrappedCallable for WasmtimeFn {
|
||||
// Get the trampoline to call for this function.
|
||||
let exec_code_buf = self
|
||||
.store
|
||||
.borrow_mut()
|
||||
.context()
|
||||
.compiler()
|
||||
.get_published_trampoline(body, &signature, value_size)
|
||||
@@ -191,11 +189,7 @@ pub struct NativeCallable {
|
||||
}
|
||||
|
||||
impl NativeCallable {
|
||||
pub(crate) fn new(
|
||||
callable: Rc<dyn Callable + 'static>,
|
||||
ft: &FuncType,
|
||||
store: &HostRef<Store>,
|
||||
) -> Self {
|
||||
pub(crate) fn new(callable: Rc<dyn Callable + 'static>, ft: &FuncType, store: &Store) -> Self {
|
||||
let (instance, export) =
|
||||
generate_func_export(ft, &callable, store).expect("generated func");
|
||||
NativeCallable {
|
||||
|
||||
@@ -30,7 +30,7 @@ impl Context {
|
||||
self.debug_info
|
||||
}
|
||||
|
||||
pub(crate) fn compiler(&mut self) -> RefMut<Compiler> {
|
||||
pub(crate) fn compiler(&self) -> RefMut<Compiler> {
|
||||
self.compiler.borrow_mut()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ impl Extern {
|
||||
}
|
||||
|
||||
pub(crate) fn from_wasmtime_export(
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
instance_handle: InstanceHandle,
|
||||
export: wasmtime_runtime::Export,
|
||||
) -> Extern {
|
||||
@@ -112,19 +112,19 @@ impl From<HostRef<Table>> for Extern {
|
||||
}
|
||||
|
||||
pub struct Func {
|
||||
_store: HostRef<Store>,
|
||||
_store: Store,
|
||||
callable: Rc<dyn WrappedCallable + 'static>,
|
||||
r#type: FuncType,
|
||||
}
|
||||
|
||||
impl Func {
|
||||
pub fn new(store: &HostRef<Store>, ty: FuncType, callable: Rc<dyn Callable + 'static>) -> Self {
|
||||
pub fn new(store: &Store, ty: FuncType, callable: Rc<dyn Callable + 'static>) -> Self {
|
||||
let callable = Rc::new(NativeCallable::new(callable, &ty, &store));
|
||||
Func::from_wrapped(store, ty, callable)
|
||||
}
|
||||
|
||||
fn from_wrapped(
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
r#type: FuncType,
|
||||
callable: Rc<dyn WrappedCallable + 'static>,
|
||||
) -> Func {
|
||||
@@ -159,7 +159,7 @@ impl Func {
|
||||
|
||||
pub(crate) fn from_wasmtime_function(
|
||||
export: wasmtime_runtime::Export,
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
instance_handle: InstanceHandle,
|
||||
) -> Self {
|
||||
let ty = if let wasmtime_runtime::Export::Function { signature, .. } = &export {
|
||||
@@ -179,7 +179,7 @@ impl fmt::Debug for Func {
|
||||
}
|
||||
|
||||
pub struct Global {
|
||||
_store: HostRef<Store>,
|
||||
_store: Store,
|
||||
r#type: GlobalType,
|
||||
wasmtime_export: wasmtime_runtime::Export,
|
||||
#[allow(dead_code)]
|
||||
@@ -187,7 +187,7 @@ pub struct Global {
|
||||
}
|
||||
|
||||
impl Global {
|
||||
pub fn new(store: &HostRef<Store>, r#type: GlobalType, val: Val) -> Global {
|
||||
pub fn new(store: &Store, r#type: GlobalType, val: Val) -> Global {
|
||||
let (wasmtime_export, wasmtime_state) =
|
||||
generate_global_export(&r#type, val).expect("generated global");
|
||||
Global {
|
||||
@@ -246,10 +246,7 @@ impl Global {
|
||||
&self.wasmtime_export
|
||||
}
|
||||
|
||||
pub(crate) fn from_wasmtime_global(
|
||||
export: wasmtime_runtime::Export,
|
||||
store: &HostRef<Store>,
|
||||
) -> Global {
|
||||
pub(crate) fn from_wasmtime_global(export: wasmtime_runtime::Export, store: &Store) -> Global {
|
||||
let global = if let wasmtime_runtime::Export::Global { ref global, .. } = export {
|
||||
global
|
||||
} else {
|
||||
@@ -266,7 +263,7 @@ impl Global {
|
||||
}
|
||||
|
||||
pub struct Table {
|
||||
store: HostRef<Store>,
|
||||
store: Store,
|
||||
r#type: TableType,
|
||||
wasmtime_handle: InstanceHandle,
|
||||
wasmtime_export: wasmtime_runtime::Export,
|
||||
@@ -274,7 +271,7 @@ pub struct Table {
|
||||
|
||||
fn get_table_item(
|
||||
handle: &InstanceHandle,
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
table_index: wasm::DefinedTableIndex,
|
||||
item_index: u32,
|
||||
) -> Val {
|
||||
@@ -287,7 +284,7 @@ fn get_table_item(
|
||||
|
||||
fn set_table_item(
|
||||
handle: &mut InstanceHandle,
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
table_index: wasm::DefinedTableIndex,
|
||||
item_index: u32,
|
||||
val: Val,
|
||||
@@ -302,7 +299,7 @@ fn set_table_item(
|
||||
}
|
||||
|
||||
impl Table {
|
||||
pub fn new(store: &HostRef<Store>, r#type: TableType, init: Val) -> Table {
|
||||
pub fn new(store: &Store, r#type: TableType, init: Val) -> Table {
|
||||
match r#type.element() {
|
||||
ValType::FuncRef => (),
|
||||
_ => panic!("table is not for funcref"),
|
||||
@@ -387,7 +384,7 @@ impl Table {
|
||||
|
||||
pub(crate) fn from_wasmtime_table(
|
||||
export: wasmtime_runtime::Export,
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
instance_handle: wasmtime_runtime::InstanceHandle,
|
||||
) -> Table {
|
||||
let table = if let wasmtime_runtime::Export::Table { ref table, .. } = export {
|
||||
@@ -406,14 +403,14 @@ impl Table {
|
||||
}
|
||||
|
||||
pub struct Memory {
|
||||
_store: HostRef<Store>,
|
||||
_store: Store,
|
||||
r#type: MemoryType,
|
||||
wasmtime_handle: InstanceHandle,
|
||||
wasmtime_export: wasmtime_runtime::Export,
|
||||
}
|
||||
|
||||
impl Memory {
|
||||
pub fn new(store: &HostRef<Store>, r#type: MemoryType) -> Memory {
|
||||
pub fn new(store: &Store, r#type: MemoryType) -> Memory {
|
||||
let (wasmtime_handle, wasmtime_export) =
|
||||
generate_memory_export(&r#type).expect("generated memory");
|
||||
Memory {
|
||||
@@ -473,7 +470,7 @@ impl Memory {
|
||||
|
||||
pub(crate) fn from_wasmtime_memory(
|
||||
export: wasmtime_runtime::Export,
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
instance_handle: wasmtime_runtime::InstanceHandle,
|
||||
) -> Memory {
|
||||
let memory = if let wasmtime_runtime::Export::Memory { ref memory, .. } = export {
|
||||
|
||||
@@ -30,7 +30,7 @@ impl Resolver for SimpleResolver {
|
||||
pub fn instantiate_in_context(
|
||||
data: &[u8],
|
||||
imports: Vec<(String, String, Extern)>,
|
||||
mut context: Context,
|
||||
context: Context,
|
||||
exports: Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>>,
|
||||
) -> Result<(InstanceHandle, HashSet<Context>), Error> {
|
||||
let mut contexts = HashSet::new();
|
||||
@@ -70,12 +70,12 @@ pub struct Instance {
|
||||
|
||||
impl Instance {
|
||||
pub fn new(
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
module: &HostRef<Module>,
|
||||
externs: &[Extern],
|
||||
) -> Result<Instance, Error> {
|
||||
let context = store.borrow_mut().context().clone();
|
||||
let exports = store.borrow_mut().global_exports().clone();
|
||||
let context = store.context().clone();
|
||||
let exports = store.global_exports().clone();
|
||||
let imports = module
|
||||
.borrow()
|
||||
.imports()
|
||||
@@ -131,7 +131,7 @@ impl Instance {
|
||||
Some(&self.exports()[i])
|
||||
}
|
||||
|
||||
pub fn from_handle(store: &HostRef<Store>, instance_handle: InstanceHandle) -> Instance {
|
||||
pub fn from_handle(store: &Store, instance_handle: InstanceHandle) -> Instance {
|
||||
let contexts = HashSet::new();
|
||||
|
||||
let mut exports = Vec::new();
|
||||
@@ -143,7 +143,7 @@ impl Instance {
|
||||
// HACK ensure all handles, instantiated outside Store, present in
|
||||
// the store's SignatureRegistry, e.g. WASI instances that are
|
||||
// imported into this store using the from_handle() method.
|
||||
let _ = store.borrow_mut().register_wasmtime_signature(signature);
|
||||
let _ = store.register_wasmtime_signature(signature);
|
||||
}
|
||||
let extern_type = ExternType::from_wasmtime_export(&export);
|
||||
exports_types.push(ExportType::new(name, extern_type));
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::r#ref::HostRef;
|
||||
use crate::runtime::Store;
|
||||
use crate::types::{
|
||||
ExportType, ExternType, FuncType, GlobalType, ImportType, Limits, MemoryType, Mutability,
|
||||
@@ -173,7 +172,7 @@ pub(crate) enum ModuleCodeSource {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Module {
|
||||
store: HostRef<Store>,
|
||||
store: Store,
|
||||
source: ModuleCodeSource,
|
||||
imports: Box<[ImportType]>,
|
||||
exports: Box<[ExportType]>,
|
||||
@@ -182,13 +181,13 @@ pub struct Module {
|
||||
impl Module {
|
||||
/// Validate and decode the raw wasm data in `binary` and create a new
|
||||
/// `Module` in the given `store`.
|
||||
pub fn new(store: &HostRef<Store>, binary: &[u8]) -> Result<Module> {
|
||||
pub fn new(store: &Store, binary: &[u8]) -> Result<Module> {
|
||||
Self::validate(store, binary)?;
|
||||
Self::new_unchecked(store, binary)
|
||||
}
|
||||
/// Similar to `new`, but does not perform any validation. Only use this
|
||||
/// on modules which are known to have been validated already!
|
||||
pub fn new_unchecked(store: &HostRef<Store>, binary: &[u8]) -> Result<Module> {
|
||||
pub fn new_unchecked(store: &Store, binary: &[u8]) -> Result<Module> {
|
||||
let (imports, exports) = read_imports_and_exports(binary)?;
|
||||
Ok(Module {
|
||||
store: store.clone(),
|
||||
@@ -203,8 +202,8 @@ impl Module {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
pub fn validate(store: &HostRef<Store>, binary: &[u8]) -> Result<()> {
|
||||
let features = store.borrow().engine().config.features.clone();
|
||||
pub fn validate(store: &Store, binary: &[u8]) -> Result<()> {
|
||||
let features = store.engine().config.features.clone();
|
||||
let config = ValidatingParserConfig {
|
||||
operator_config: OperatorValidatorConfig {
|
||||
enable_threads: features.threads,
|
||||
@@ -222,7 +221,7 @@ impl Module {
|
||||
pub fn exports(&self) -> &[ExportType] {
|
||||
&self.exports
|
||||
}
|
||||
pub fn from_exports(store: &HostRef<Store>, exports: Box<[ExportType]>) -> Self {
|
||||
pub fn from_exports(store: &Store, exports: Box<[ExportType]>) -> Self {
|
||||
Module {
|
||||
store: store.clone(),
|
||||
source: ModuleCodeSource::Unknown,
|
||||
|
||||
@@ -288,12 +288,13 @@ pub enum OptLevel {
|
||||
///
|
||||
/// Using `clone` on an `Engine` is a cheap operation. It will not create an
|
||||
/// entirely new engine, but rather just a new reference to the existing engine.
|
||||
/// In other words it's a shallow copy, not a deep copy.
|
||||
///
|
||||
/// ## Engines and `Default`
|
||||
///
|
||||
/// You can create an engine with default settings using `Engine::default()`.
|
||||
/// This engine will not have any unstable wasm features enabled and will use
|
||||
/// the default compilation backend configured at this crate's compile time.
|
||||
/// You can create an engine with default configuration settings using
|
||||
/// `Engine::default()`. Be sure to consult the documentation of [`Config`] for
|
||||
/// default settings.
|
||||
#[derive(Default, Clone)]
|
||||
pub struct Engine {
|
||||
pub(crate) config: Arc<Config>,
|
||||
@@ -311,45 +312,72 @@ impl Engine {
|
||||
|
||||
// Store
|
||||
|
||||
/// A `Store` is a shared cache of information between WebAssembly modules.
|
||||
///
|
||||
/// Each `Module` is compiled into a `Store` and a `Store` is associated with an
|
||||
/// [`Engine`]. You'll use a `Store` to attach to a number of global items in
|
||||
/// the production of various items for wasm modules.
|
||||
///
|
||||
/// # Stores and `Clone`
|
||||
///
|
||||
/// Using `clone` on a `Store` is a cheap operation. It will not create an
|
||||
/// entirely new store, but rather just a new reference to the existing object.
|
||||
/// In other words it's a shallow copy, not a deep copy.
|
||||
///
|
||||
/// ## Stores and `Default`
|
||||
///
|
||||
/// You can create a store with default configuration settings using
|
||||
/// `Store::default()`. This will create a brand new [`Engine`] with default
|
||||
/// ocnfiguration (see [`Config`] for more information).
|
||||
#[derive(Clone)]
|
||||
pub struct Store {
|
||||
inner: Rc<StoreInner>,
|
||||
}
|
||||
|
||||
struct StoreInner {
|
||||
engine: Engine,
|
||||
context: Context,
|
||||
global_exports: Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>>,
|
||||
signature_cache: HashMap<wasmtime_runtime::VMSharedSignatureIndex, ir::Signature>,
|
||||
signature_cache: RefCell<HashMap<wasmtime_runtime::VMSharedSignatureIndex, ir::Signature>>,
|
||||
}
|
||||
|
||||
impl Store {
|
||||
/// Creates a new store to be associated with the given [`Engine`].
|
||||
pub fn new(engine: &Engine) -> Store {
|
||||
Store {
|
||||
engine: engine.clone(),
|
||||
context: Context::new(&engine.config),
|
||||
global_exports: Rc::new(RefCell::new(HashMap::new())),
|
||||
signature_cache: HashMap::new(),
|
||||
inner: Rc::new(StoreInner {
|
||||
engine: engine.clone(),
|
||||
context: Context::new(&engine.config),
|
||||
global_exports: Rc::new(RefCell::new(HashMap::new())),
|
||||
signature_cache: RefCell::new(HashMap::new()),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the [`Engine`] that this store is associated with.
|
||||
pub fn engine(&self) -> &Engine {
|
||||
&self.engine
|
||||
&self.inner.engine
|
||||
}
|
||||
|
||||
pub(crate) fn context(&mut self) -> &mut Context {
|
||||
&mut self.context
|
||||
pub(crate) fn context(&self) -> &Context {
|
||||
&self.inner.context
|
||||
}
|
||||
|
||||
// Specific to wasmtime: hack to pass memory around to wasi
|
||||
#[doc(hidden)]
|
||||
pub fn global_exports(
|
||||
&self,
|
||||
) -> &Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>> {
|
||||
&self.global_exports
|
||||
&self.inner.global_exports
|
||||
}
|
||||
|
||||
pub(crate) fn register_wasmtime_signature(
|
||||
&mut self,
|
||||
&self,
|
||||
signature: &ir::Signature,
|
||||
) -> wasmtime_runtime::VMSharedSignatureIndex {
|
||||
use std::collections::hash_map::Entry;
|
||||
let index = self.context().compiler().signatures().register(signature);
|
||||
match self.signature_cache.entry(index) {
|
||||
match self.inner.signature_cache.borrow_mut().entry(index) {
|
||||
Entry::Vacant(v) => {
|
||||
v.insert(signature.clone());
|
||||
}
|
||||
@@ -361,8 +389,18 @@ impl Store {
|
||||
pub(crate) fn lookup_wasmtime_signature(
|
||||
&self,
|
||||
type_index: wasmtime_runtime::VMSharedSignatureIndex,
|
||||
) -> Option<&ir::Signature> {
|
||||
self.signature_cache.get(&type_index)
|
||||
) -> Option<ir::Signature> {
|
||||
self.inner
|
||||
.signature_cache
|
||||
.borrow()
|
||||
.get(&type_index)
|
||||
.cloned()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Store {
|
||||
fn default() -> Store {
|
||||
Store::new(&Engine::default())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use crate::runtime::Store;
|
||||
use anyhow::Result;
|
||||
use std::any::Any;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::rc::Rc;
|
||||
use wasmtime_environ::entity::PrimaryMap;
|
||||
@@ -13,7 +13,7 @@ use wasmtime_runtime::{Imports, InstanceHandle, VMFunctionBody};
|
||||
|
||||
pub(crate) fn create_handle(
|
||||
module: Module,
|
||||
signature_registry: Option<RefMut<Store>>,
|
||||
signature_registry: Option<&Store>,
|
||||
finished_functions: PrimaryMap<DefinedFuncIndex, *const VMFunctionBody>,
|
||||
state: Box<dyn Any>,
|
||||
) -> Result<InstanceHandle> {
|
||||
@@ -31,7 +31,7 @@ pub(crate) fn create_handle(
|
||||
|
||||
// Compute indices into the shared signature table.
|
||||
let signatures = signature_registry
|
||||
.map(|mut signature_registry| {
|
||||
.map(|signature_registry| {
|
||||
module
|
||||
.signatures
|
||||
.values()
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use super::create_handle::create_handle;
|
||||
use super::trap::{record_api_trap, TrapSink, API_TRAP_CODE};
|
||||
use crate::r#ref::HostRef;
|
||||
use crate::{Callable, FuncType, Store, Val};
|
||||
use anyhow::Result;
|
||||
use std::cmp;
|
||||
@@ -234,7 +233,7 @@ fn make_trampoline(
|
||||
pub fn create_handle_with_function(
|
||||
ft: &FuncType,
|
||||
func: &Rc<dyn Callable + 'static>,
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
) -> Result<InstanceHandle> {
|
||||
let sig = ft.get_wasmtime_signature().clone();
|
||||
|
||||
@@ -270,7 +269,7 @@ pub fn create_handle_with_function(
|
||||
|
||||
create_handle(
|
||||
module,
|
||||
Some(store.borrow_mut()),
|
||||
Some(store),
|
||||
finished_functions,
|
||||
Box::new(trampoline_state),
|
||||
)
|
||||
|
||||
@@ -12,7 +12,6 @@ use self::global::create_global;
|
||||
use self::memory::create_handle_with_memory;
|
||||
use self::table::create_handle_with_table;
|
||||
use super::{Callable, FuncType, GlobalType, MemoryType, Store, TableType, Val};
|
||||
use crate::r#ref::HostRef;
|
||||
use anyhow::Result;
|
||||
use std::rc::Rc;
|
||||
|
||||
@@ -22,7 +21,7 @@ pub use self::trap::take_api_trap;
|
||||
pub fn generate_func_export(
|
||||
ft: &FuncType,
|
||||
func: &Rc<dyn Callable + 'static>,
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
) -> Result<(wasmtime_runtime::InstanceHandle, wasmtime_runtime::Export)> {
|
||||
let mut instance = create_handle_with_function(ft, func, store)?;
|
||||
let export = instance.lookup("trampoline").expect("trampoline export");
|
||||
|
||||
@@ -197,7 +197,7 @@ impl From<RuntimeValue> for Val {
|
||||
|
||||
pub(crate) fn into_checked_anyfunc(
|
||||
val: Val,
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
) -> wasmtime_runtime::VMCallerCheckedAnyfunc {
|
||||
match val {
|
||||
Val::AnyRef(AnyRef::Null) => wasmtime_runtime::VMCallerCheckedAnyfunc {
|
||||
@@ -215,7 +215,7 @@ pub(crate) fn into_checked_anyfunc(
|
||||
} => (*vmctx, *address, signature),
|
||||
_ => panic!("expected function export"),
|
||||
};
|
||||
let type_index = store.borrow_mut().register_wasmtime_signature(signature);
|
||||
let type_index = store.register_wasmtime_signature(signature);
|
||||
wasmtime_runtime::VMCallerCheckedAnyfunc {
|
||||
func_ptr,
|
||||
type_index,
|
||||
@@ -228,16 +228,14 @@ pub(crate) fn into_checked_anyfunc(
|
||||
|
||||
pub(crate) fn from_checked_anyfunc(
|
||||
item: &wasmtime_runtime::VMCallerCheckedAnyfunc,
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
) -> Val {
|
||||
if item.type_index == wasmtime_runtime::VMSharedSignatureIndex::default() {
|
||||
return Val::AnyRef(AnyRef::Null);
|
||||
}
|
||||
let signature = store
|
||||
.borrow()
|
||||
.lookup_wasmtime_signature(item.type_index)
|
||||
.expect("signature")
|
||||
.clone();
|
||||
.expect("signature");
|
||||
let instance_handle = unsafe { wasmtime_runtime::InstanceHandle::from_vmctx(item.vmctx) };
|
||||
let export = wasmtime_runtime::Export::Function {
|
||||
address: item.func_ptr,
|
||||
|
||||
@@ -609,7 +609,7 @@ pub unsafe extern "C" fn wasm_func_new(
|
||||
ty: *const wasm_functype_t,
|
||||
callback: wasm_func_callback_t,
|
||||
) -> *mut wasm_func_t {
|
||||
let store = &(*store).store;
|
||||
let store = &(*store).store.borrow();
|
||||
let ty = (*ty).functype.clone();
|
||||
let callback = Rc::new(callback);
|
||||
let func = Box::new(wasm_func_t {
|
||||
@@ -663,7 +663,7 @@ pub unsafe extern "C" fn wasm_instance_new(
|
||||
imports: *const *const wasm_extern_t,
|
||||
result: *mut *mut wasm_trap_t,
|
||||
) -> *mut wasm_instance_t {
|
||||
let store = &(*store).store;
|
||||
let store = &(*store).store.borrow();
|
||||
let mut externs: Vec<Extern> = Vec::with_capacity((*module).imports.len());
|
||||
for i in 0..(*module).imports.len() {
|
||||
let import = *imports.add(i);
|
||||
@@ -731,7 +731,7 @@ pub unsafe extern "C" fn wasm_module_new(
|
||||
binary: *const wasm_byte_vec_t,
|
||||
) -> *mut wasm_module_t {
|
||||
let binary = (*binary).as_slice();
|
||||
let store = &(*store).store;
|
||||
let store = &(*store).store.borrow();
|
||||
let module = Module::new_unchecked(store, binary).expect("module");
|
||||
let imports = module
|
||||
.imports()
|
||||
@@ -765,7 +765,7 @@ pub unsafe extern "C" fn wasm_module_validate(
|
||||
binary: *const wasm_byte_vec_t,
|
||||
) -> bool {
|
||||
let binary = (*binary).as_slice();
|
||||
let store = &(*store).store;
|
||||
let store = &(*store).store.borrow();
|
||||
Module::validate(store, binary).is_ok()
|
||||
}
|
||||
|
||||
@@ -814,7 +814,7 @@ pub unsafe extern "C" fn wasm_func_new_with_env(
|
||||
env: *mut std::ffi::c_void,
|
||||
finalizer: std::option::Option<unsafe extern "C" fn(arg1: *mut std::ffi::c_void)>,
|
||||
) -> *mut wasm_func_t {
|
||||
let store = &(*store).store;
|
||||
let store = &(*store).store.borrow();
|
||||
let ty = (*ty).functype.clone();
|
||||
let callback = Rc::new(CallbackWithEnv {
|
||||
callback,
|
||||
@@ -1337,7 +1337,7 @@ pub unsafe extern "C" fn wasm_global_new(
|
||||
val: *const wasm_val_t,
|
||||
) -> *mut wasm_global_t {
|
||||
let global = HostRef::new(Global::new(
|
||||
&(*store).store,
|
||||
&(*store).store.borrow(),
|
||||
(*gt).globaltype.clone(),
|
||||
(*val).val(),
|
||||
));
|
||||
@@ -1456,7 +1456,10 @@ pub unsafe extern "C" fn wasm_memory_new(
|
||||
store: *mut wasm_store_t,
|
||||
mt: *const wasm_memorytype_t,
|
||||
) -> *mut wasm_memory_t {
|
||||
let memory = HostRef::new(Memory::new(&(*store).store, (*mt).memorytype.clone()));
|
||||
let memory = HostRef::new(Memory::new(
|
||||
&(*store).store.borrow(),
|
||||
(*mt).memorytype.clone(),
|
||||
));
|
||||
let m = Box::new(wasm_memory_t { memory, ext: None });
|
||||
Box::into_raw(m)
|
||||
}
|
||||
@@ -1549,7 +1552,11 @@ pub unsafe extern "C" fn wasm_table_new(
|
||||
Val::AnyRef(AnyRef::Null)
|
||||
};
|
||||
let t = Box::new(wasm_table_t {
|
||||
table: HostRef::new(Table::new(&(*store).store, (*tt).tabletype.clone(), init)),
|
||||
table: HostRef::new(Table::new(
|
||||
&(*store).store.borrow(),
|
||||
(*tt).tabletype.clone(),
|
||||
init,
|
||||
)),
|
||||
ext: None,
|
||||
});
|
||||
Box::into_raw(t)
|
||||
|
||||
@@ -32,8 +32,7 @@ fn test_import_calling_export() {
|
||||
}
|
||||
}
|
||||
|
||||
let engine = Engine::default();
|
||||
let store = HostRef::new(Store::new(&engine));
|
||||
let store = Store::default();
|
||||
let wasm = wat::parse_str(WAT).unwrap();
|
||||
let module = HostRef::new(Module::new(&store, &wasm).expect("failed to create module"));
|
||||
|
||||
|
||||
@@ -12,8 +12,7 @@ fn test_trap_return() -> Result<(), String> {
|
||||
}
|
||||
}
|
||||
|
||||
let engine = Engine::default();
|
||||
let store = HostRef::new(Store::new(&engine));
|
||||
let store = Store::default();
|
||||
let binary = parse_str(
|
||||
r#"
|
||||
(module
|
||||
|
||||
@@ -42,7 +42,7 @@ pub fn instantiate(wasm: &[u8], strategy: Strategy) {
|
||||
.strategy(strategy)
|
||||
.expect("failed to enable lightbeam");
|
||||
let engine = Engine::new(&config);
|
||||
let store = HostRef::new(Store::new(&engine));
|
||||
let store = Store::new(&engine);
|
||||
|
||||
let module =
|
||||
HostRef::new(Module::new(&store, wasm).expect("Failed to compile a valid Wasm module!"));
|
||||
@@ -91,7 +91,7 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) {
|
||||
|
||||
let mut config: Option<Config> = None;
|
||||
let mut engine: Option<Engine> = None;
|
||||
let mut store: Option<HostRef<Store>> = None;
|
||||
let mut store: Option<Store> = None;
|
||||
let mut modules: HashMap<usize, HostRef<Module>> = Default::default();
|
||||
let mut instances: HashMap<usize, HostRef<Instance>> = Default::default();
|
||||
|
||||
@@ -113,7 +113,7 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) {
|
||||
|
||||
ApiCall::StoreNew => {
|
||||
assert!(store.is_none());
|
||||
store = Some(HostRef::new(Store::new(engine.as_ref().unwrap())));
|
||||
store = Some(Store::new(engine.as_ref().unwrap()));
|
||||
}
|
||||
|
||||
ApiCall::ModuleNew { id, wasm } => {
|
||||
|
||||
@@ -7,10 +7,7 @@ use wasmtime::{
|
||||
};
|
||||
|
||||
/// Create a set of dummy functions/globals/etc for the given imports.
|
||||
pub fn dummy_imports(
|
||||
store: &HostRef<Store>,
|
||||
import_tys: &[ImportType],
|
||||
) -> Result<Vec<Extern>, Trap> {
|
||||
pub fn dummy_imports(store: &Store, import_tys: &[ImportType]) -> Result<Vec<Extern>, Trap> {
|
||||
let mut imports = Vec::with_capacity(import_tys.len());
|
||||
for imp in import_tys {
|
||||
imports.push(match imp.ty() {
|
||||
@@ -38,7 +35,7 @@ pub struct DummyFunc(FuncType);
|
||||
|
||||
impl DummyFunc {
|
||||
/// Construct a new dummy `Func`.
|
||||
pub fn new(store: &HostRef<Store>, ty: FuncType) -> Func {
|
||||
pub fn new(store: &Store, ty: FuncType) -> Func {
|
||||
let callable = DummyFunc(ty.clone());
|
||||
Func::new(store, ty, Rc::new(callable) as _)
|
||||
}
|
||||
@@ -80,18 +77,18 @@ pub fn dummy_value(val_ty: &ValType) -> Result<Val, Trap> {
|
||||
}
|
||||
|
||||
/// Construct a dummy global for the given global type.
|
||||
pub fn dummy_global(store: &HostRef<Store>, ty: GlobalType) -> Result<Global, Trap> {
|
||||
pub fn dummy_global(store: &Store, ty: GlobalType) -> Result<Global, Trap> {
|
||||
let val = dummy_value(ty.content())?;
|
||||
Ok(Global::new(store, ty, val))
|
||||
}
|
||||
|
||||
/// Construct a dummy table for the given table type.
|
||||
pub fn dummy_table(store: &HostRef<Store>, ty: TableType) -> Result<Table, Trap> {
|
||||
pub fn dummy_table(store: &Store, ty: TableType) -> Result<Table, Trap> {
|
||||
let init_val = dummy_value(&ty.element())?;
|
||||
Ok(Table::new(store, ty, init_val))
|
||||
}
|
||||
|
||||
/// Construct a dummy memory for the given memory type.
|
||||
pub fn dummy_memory(store: &HostRef<Store>, ty: MemoryType) -> Memory {
|
||||
pub fn dummy_memory(store: &Store, ty: MemoryType) -> Memory {
|
||||
Memory::new(store, ty)
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ impl wasmtime::Callable for WrappedFn {
|
||||
}
|
||||
|
||||
pub fn wrap_into_pyfunction(
|
||||
store: &wasmtime::HostRef<wasmtime::Store>,
|
||||
store: &wasmtime::Store,
|
||||
callable: &PyAny,
|
||||
) -> PyResult<wasmtime::HostRef<wasmtime::Func>> {
|
||||
if !callable.hasattr("__annotations__")? {
|
||||
|
||||
@@ -44,11 +44,7 @@ impl InstantiateResultObject {
|
||||
}
|
||||
}
|
||||
|
||||
fn find_export_in(
|
||||
obj: &PyAny,
|
||||
store: &wasmtime::HostRef<wasmtime::Store>,
|
||||
name: &str,
|
||||
) -> PyResult<wasmtime::Extern> {
|
||||
fn find_export_in(obj: &PyAny, store: &wasmtime::Store, name: &str) -> PyResult<wasmtime::Extern> {
|
||||
let obj = obj.cast_as::<PyDict>()?;
|
||||
|
||||
Ok(if let Some(item) = obj.get_item(name) {
|
||||
@@ -86,7 +82,7 @@ pub fn instantiate(
|
||||
let wasm_data = buffer_source.as_bytes();
|
||||
|
||||
let engine = wasmtime::Engine::new(&wasmtime::Config::new().wasm_multi_value(true));
|
||||
let store = wasmtime::HostRef::new(wasmtime::Store::new(&engine));
|
||||
let store = wasmtime::Store::new(&engine);
|
||||
|
||||
let module = wasmtime::HostRef::new(wasmtime::Module::new(&store, wasm_data).map_err(err2py)?);
|
||||
|
||||
|
||||
@@ -52,8 +52,8 @@ fn generate_load(item: &syn::ItemTrait) -> syn::Result<TokenStream> {
|
||||
use #root::anyhow::{bail, format_err};
|
||||
|
||||
let engine = Engine::new(Config::new().wasm_multi_value(true));
|
||||
let store = HostRef::new(Store::new(&engine));
|
||||
let global_exports = store.borrow().global_exports().clone();
|
||||
let store = Store::new(&engine);
|
||||
let global_exports = store.global_exports().clone();
|
||||
|
||||
let data = #root::wasmtime_interface_types::ModuleData::new(&bytes)?;
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
use anyhow::{bail, Context};
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use wasmtime::{Engine, HostRef, Instance, Module, Store};
|
||||
use wasmtime::{HostRef, Instance, Module, Store};
|
||||
|
||||
pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> anyhow::Result<()> {
|
||||
let engine = Engine::default();
|
||||
let store = HostRef::new(Store::new(&engine));
|
||||
let store = Store::default();
|
||||
|
||||
let global_exports = store.borrow().global_exports().clone();
|
||||
let global_exports = store.global_exports().clone();
|
||||
let get_preopens = |workspace: Option<&Path>| -> anyhow::Result<Vec<_>> {
|
||||
if let Some(workspace) = workspace {
|
||||
let preopen_dir = wasi_common::preopen_dir(workspace)
|
||||
|
||||
@@ -14,12 +14,12 @@ use wasmtime_runtime::{Imports, InstanceHandle, InstantiationError, VMContext};
|
||||
|
||||
/// Creates `wasmtime::Instance` object implementing the "wasi" interface.
|
||||
pub fn create_wasi_instance(
|
||||
store: &wasmtime::HostRef<wasmtime::Store>,
|
||||
store: &wasmtime::Store,
|
||||
preopened_dirs: &[(String, File)],
|
||||
argv: &[String],
|
||||
environ: &[(String, String)],
|
||||
) -> Result<wasmtime::Instance, InstantiationError> {
|
||||
let global_exports = store.borrow().global_exports().clone();
|
||||
let global_exports = store.global_exports().clone();
|
||||
let wasi = instantiate_wasi(global_exports, preopened_dirs, argv, environ)?;
|
||||
let instance = wasmtime::Instance::from_handle(&store, wasi);
|
||||
Ok(instance)
|
||||
|
||||
@@ -14,12 +14,12 @@ use wasmtime_runtime::{Imports, InstanceHandle, InstantiationError, VMFunctionBo
|
||||
|
||||
/// Creates `wasmtime::Instance` object implementing the "wasi" interface.
|
||||
pub fn create_wasi_instance(
|
||||
store: &wasmtime::HostRef<wasmtime::Store>,
|
||||
store: &wasmtime::Store,
|
||||
preopened_dirs: &[(String, File)],
|
||||
argv: &[String],
|
||||
environ: &[(String, String)],
|
||||
) -> Result<wasmtime::Instance, InstantiationError> {
|
||||
let global_exports = store.borrow().global_exports().clone();
|
||||
let global_exports = store.global_exports().clone();
|
||||
let wasi = instantiate_wasi(global_exports, preopened_dirs, argv, environ)?;
|
||||
let instance = wasmtime::Instance::from_handle(&store, wasi);
|
||||
Ok(instance)
|
||||
|
||||
@@ -17,7 +17,7 @@ where
|
||||
}
|
||||
|
||||
fn wrap(
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
ty: FuncType,
|
||||
callable: impl Fn(&[Val], &mut [Val]) -> Result<(), Trap> + 'static,
|
||||
) -> Func {
|
||||
@@ -26,7 +26,7 @@ fn wrap(
|
||||
|
||||
/// Return an instance implementing the "spectest" interface used in the
|
||||
/// spec testsuite.
|
||||
pub fn instantiate_spectest(store: &HostRef<Store>) -> HashMap<&'static str, Extern> {
|
||||
pub fn instantiate_spectest(store: &Store) -> HashMap<&'static str, Extern> {
|
||||
let mut ret = HashMap::new();
|
||||
|
||||
let ty = FuncType::new(Box::new([]), Box::new([]));
|
||||
|
||||
@@ -30,7 +30,7 @@ pub struct WastContext {
|
||||
current: Option<HostRef<Instance>>,
|
||||
|
||||
instances: HashMap<String, HostRef<Instance>>,
|
||||
store: HostRef<Store>,
|
||||
store: Store,
|
||||
spectest: Option<HashMap<&'static str, Extern>>,
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ enum Outcome<T = Vec<Val>> {
|
||||
|
||||
impl WastContext {
|
||||
/// Construct a new instance of `WastContext`.
|
||||
pub fn new(store: HostRef<Store>) -> Self {
|
||||
pub fn new(store: Store) -> Self {
|
||||
Self {
|
||||
current: None,
|
||||
store,
|
||||
|
||||
@@ -33,13 +33,12 @@ wasmtime = "<current version>"
|
||||
|
||||
where "<current version>" is the current version number of the `wasmtime` crate.
|
||||
|
||||
It is time to add code to the `src/main.rs`. First, the engine and storage need to be activated:
|
||||
It is time to add code to the `src/main.rs`. First, storage needs to be activated:
|
||||
|
||||
```rust
|
||||
use wasmtime::*;
|
||||
|
||||
let engine = Engine::default();
|
||||
let store = HostRef::new(Store::new(&engine));
|
||||
let store = Store::default();
|
||||
```
|
||||
|
||||
The `HostRef` will be used a lot -- it is a "convenience" object to store and refer an object between the host and
|
||||
@@ -87,8 +86,7 @@ use std::fs::read;
|
||||
use wasmtime::*;
|
||||
|
||||
fn main() {
|
||||
let engine = Engine::default();
|
||||
let store = HostRef::new(Store::new(&engine));
|
||||
let store = Store::default();
|
||||
|
||||
let wasm = read("hello.wasm").expect("wasm file");
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ impl RunCommand {
|
||||
}
|
||||
|
||||
let engine = Engine::new(&config);
|
||||
let store = HostRef::new(Store::new(&engine));
|
||||
let store = Store::new(&engine);
|
||||
let mut module_registry = HashMap::new();
|
||||
|
||||
// Make wasi available by default.
|
||||
@@ -151,7 +151,7 @@ impl RunCommand {
|
||||
let wasi_unstable = HostRef::new(if self.enable_wasi_c {
|
||||
#[cfg(feature = "wasi-c")]
|
||||
{
|
||||
let global_exports = store.borrow().global_exports().clone();
|
||||
let global_exports = store.global_exports().clone();
|
||||
let handle = instantiate_wasi_c(global_exports, &preopen_dirs, &argv, &self.vars)?;
|
||||
Instance::from_handle(&store, handle)
|
||||
}
|
||||
@@ -231,12 +231,12 @@ impl RunCommand {
|
||||
}
|
||||
|
||||
fn instantiate_module(
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
module_registry: &HashMap<String, HostRef<Instance>>,
|
||||
path: &Path,
|
||||
) -> Result<(HostRef<Instance>, HostRef<Module>, Vec<u8>)> {
|
||||
// Read the wasm module binary either as `*.wat` or a raw binary
|
||||
let data = wat::parse_file(path.to_path_buf())?;
|
||||
let data = wat::parse_file(path)?;
|
||||
|
||||
let module = HostRef::new(Module::new(store, &data)?);
|
||||
|
||||
@@ -274,7 +274,7 @@ impl RunCommand {
|
||||
|
||||
fn handle_module(
|
||||
&self,
|
||||
store: &HostRef<Store>,
|
||||
store: &Store,
|
||||
module_registry: &HashMap<String, HostRef<Instance>>,
|
||||
) -> Result<()> {
|
||||
let (instance, module, data) =
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::{init_file_per_thread_logger, pick_compilation_strategy, CommonOption
|
||||
use anyhow::{bail, Context as _, Result};
|
||||
use std::{fmt::Write, path::PathBuf};
|
||||
use structopt::{clap::AppSettings, StructOpt};
|
||||
use wasmtime::{Config, Engine, HostRef, Store};
|
||||
use wasmtime::{Config, Engine, Store};
|
||||
use wasmtime_environ::cache_init;
|
||||
use wasmtime_wast::WastContext;
|
||||
|
||||
@@ -65,7 +65,7 @@ impl WastCommand {
|
||||
config.cranelift_opt_level(wasmtime::OptLevel::Speed);
|
||||
}
|
||||
|
||||
let store = HostRef::new(Store::new(&Engine::new(&config)));
|
||||
let store = Store::new(&Engine::new(&config));
|
||||
let mut wast_context = WastContext::new(store);
|
||||
|
||||
wast_context
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::path::Path;
|
||||
use wasmtime::{Config, Engine, HostRef, Store, Strategy};
|
||||
use wasmtime::{Config, Engine, Store, Strategy};
|
||||
use wasmtime_wast::WastContext;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/wast_testsuite_tests.rs"));
|
||||
@@ -15,7 +15,7 @@ fn run_wast(wast: &str, strategy: Strategy) -> anyhow::Result<()> {
|
||||
.wasm_multi_value(wast.iter().any(|s| s == "multi-value"))
|
||||
.strategy(strategy)?
|
||||
.cranelift_debug_verifier(true);
|
||||
let store = HostRef::new(Store::new(&Engine::new(&cfg)));
|
||||
let store = Store::new(&Engine::new(&cfg));
|
||||
let mut wast_context = WastContext::new(store);
|
||||
wast_context.register_spectest()?;
|
||||
wast_context.run_file(wast)?;
|
||||
|
||||
Reference in New Issue
Block a user