* Compute instance exports on demand. Instead having instances eagerly compute a Vec of Externs, and bumping the refcount for each Extern, compute Externs on demand. This also enables `Instance::get_export` to avoid doing a linear search. This also means that the closure returned by `get0` and friends now holds an `InstanceHandle` to dynamically hold the instance live rather than being scoped to a lifetime. * Compute module imports and exports on demand too. And compute Extern::ty on demand too. * Add a utility function for computing an ExternType. * Add a utility function for looking up a function's signature. * Add a utility function for computing the ValType of a Global. * Rename wasmtime_environ::Export to EntityIndex. This helps differentiate it from other Export types in the tree, and describes what it is. * Fix a typo in a comment. * Simplify module imports and exports. * Make `Instance::exports` return the export names. This significantly simplifies the public API, as it's relatively common to need the names, and this avoids the need to do a zip with `Module::exports`. This also changes `ImportType` and `ExportType` to have public members instead of private members and accessors, as I find that simplifies the usage particularly in cases where there are temporary instances. * Remove `Instance::module`. This doesn't quite remove `Instance`'s `module` member, it gets a step closer. * Use a InstanceHandle utility function. * Don't consume self in the `Func::get*` methods. Instead, just create a closure containing the instance handle and the export for them to call. * Use `ExactSizeIterator` to avoid needing separate `num_*` methods. * Rename `Extern::func()` etc. to `into_func()` etc. * Revise examples to avoid using `nth`. * Add convenience methods to instance for getting specific extern types. * Use the convenience functions in more tests and examples. * Avoid cloning strings for `ImportType` and `ExportType`. * Remove more obviated clone() calls. * Simplify `Func`'s closure state. * Make wasmtime::Export's fields private. This makes them more consistent with ExportType. * Fix compilation error. * Make a lifetime parameter explicit, and use better lifetime names. Instead of 'me, use 'instance and 'module to make it clear what the lifetime is. * More lifetime cleanups.
98 lines
2.8 KiB
Rust
98 lines
2.8 KiB
Rust
use crate::{handle_result, wasmtime_error_t};
|
|
use crate::{wasm_byte_vec_t, wasm_exporttype_vec_t, wasm_importtype_vec_t};
|
|
use crate::{wasm_exporttype_t, wasm_importtype_t, wasm_store_t};
|
|
use std::ptr;
|
|
use wasmtime::{HostRef, Module};
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone)]
|
|
pub struct wasm_module_t {
|
|
pub(crate) module: HostRef<Module>,
|
|
pub(crate) imports: Vec<wasm_importtype_t>,
|
|
pub(crate) exports: Vec<wasm_exporttype_t>,
|
|
}
|
|
|
|
wasmtime_c_api_macros::declare_ref!(wasm_module_t);
|
|
|
|
impl wasm_module_t {
|
|
fn anyref(&self) -> wasmtime::AnyRef {
|
|
self.module.anyref()
|
|
}
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn wasm_module_new(
|
|
store: &wasm_store_t,
|
|
binary: &wasm_byte_vec_t,
|
|
) -> Option<Box<wasm_module_t>> {
|
|
let mut ret = ptr::null_mut();
|
|
match wasmtime_module_new(store, binary, &mut ret) {
|
|
Some(_err) => None,
|
|
None => {
|
|
assert!(!ret.is_null());
|
|
Some(unsafe { Box::from_raw(ret) })
|
|
}
|
|
}
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn wasmtime_module_new(
|
|
store: &wasm_store_t,
|
|
binary: &wasm_byte_vec_t,
|
|
ret: &mut *mut wasm_module_t,
|
|
) -> Option<Box<wasmtime_error_t>> {
|
|
let binary = binary.as_slice();
|
|
let store = &store.store.borrow();
|
|
handle_result(Module::from_binary(store, binary), |module| {
|
|
let imports = module
|
|
.imports()
|
|
.map(|i| wasm_importtype_t::new(i.module().to_owned(), i.name().to_owned(), i.ty()))
|
|
.collect::<Vec<_>>();
|
|
let exports = module
|
|
.exports()
|
|
.map(|e| wasm_exporttype_t::new(e.name().to_owned(), e.ty()))
|
|
.collect::<Vec<_>>();
|
|
let module = Box::new(wasm_module_t {
|
|
module: HostRef::new(module),
|
|
imports,
|
|
exports,
|
|
});
|
|
*ret = Box::into_raw(module);
|
|
})
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn wasm_module_validate(store: &wasm_store_t, binary: &wasm_byte_vec_t) -> bool {
|
|
wasmtime_module_validate(store, binary).is_none()
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn wasmtime_module_validate(
|
|
store: &wasm_store_t,
|
|
binary: &wasm_byte_vec_t,
|
|
) -> Option<Box<wasmtime_error_t>> {
|
|
let binary = binary.as_slice();
|
|
let store = &store.store.borrow();
|
|
handle_result(Module::validate(store, binary), |()| {})
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn wasm_module_exports(module: &wasm_module_t, out: &mut wasm_exporttype_vec_t) {
|
|
let buffer = module
|
|
.exports
|
|
.iter()
|
|
.map(|et| Some(Box::new(et.clone())))
|
|
.collect::<Vec<_>>();
|
|
out.set_buffer(buffer);
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn wasm_module_imports(module: &wasm_module_t, out: &mut wasm_importtype_vec_t) {
|
|
let buffer = module
|
|
.imports
|
|
.iter()
|
|
.map(|it| Some(Box::new(it.clone())))
|
|
.collect::<Vec<_>>();
|
|
out.set_buffer(buffer);
|
|
}
|