Add a method to Linker and flag to wasmtime-cli to trap unknown import funcs (#4312)

* Add a method to Linker and flag to wasmtime-cli to trap unknown import funcs

Sometimes users have a Command module which imports functions unknown to
the wasmtime-cli, but does not call them at runtime. This PR provides a
convenience method on Linker to define all unknown import functions in
a given Module as a trivial implementation which traps, and hooks this
up to a new cli flag --trap-unknown-imports.

* add cfg guards - func_new requires compiler (naturally)
This commit is contained in:
Pat Hickey
2022-06-27 06:55:50 -07:00
committed by GitHub
parent 87007c5839
commit 84a43d86a1
3 changed files with 92 additions and 3 deletions

View File

@@ -2,8 +2,8 @@ use crate::func::HostFunc;
use crate::instance::InstancePre;
use crate::store::StoreOpaque;
use crate::{
AsContextMut, Caller, Engine, Extern, Func, FuncType, ImportType, Instance, IntoFunc, Module,
StoreContextMut, Trap, Val, ValRaw,
AsContextMut, Caller, Engine, Extern, ExternType, Func, FuncType, ImportType, Instance,
IntoFunc, Module, StoreContextMut, Trap, Val, ValRaw,
};
use anyhow::{anyhow, bail, Context, Result};
use log::warn;
@@ -237,6 +237,48 @@ impl<T> Linker<T> {
self
}
/// Implement any imports of the given [`Module`] with a function which traps.
///
/// By default a [`Linker`] will error when unknown imports are encountered
/// in a command module while using [`Linker::module`]. Use this function
/// when
///
/// This method can be used to allow unknown imports from command modules.
///
/// # Examples
///
/// ```
/// # use wasmtime::*;
/// # fn main() -> anyhow::Result<()> {
/// # let engine = Engine::default();
/// # let module = Module::new(&engine, "(module (import \"unknown\" \"import\" (func)))")?;
/// # let mut store = Store::new(&engine, ());
/// let mut linker = Linker::new(&engine);
/// linker.define_unknown_imports_as_traps(&module)?;
/// linker.instantiate(&mut store, &module)?;
/// # Ok(())
/// # }
/// ```
#[cfg(compiler)]
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
pub fn define_unknown_imports_as_traps(&mut self, module: &Module) -> anyhow::Result<()> {
for import in module.imports() {
if self._get_by_import(&import).is_err() {
if let ExternType::Func(func_ty) = import.ty() {
let err_msg = format!(
"unknown import: `{}::{}` has not been defined",
import.module(),
import.name(),
);
self.func_new(import.module(), import.name(), func_ty, move |_, _, _| {
Err(Trap::new(err_msg.clone()))
})?;
}
}
}
Ok(())
}
/// Defines a new item in this [`Linker`].
///
/// This method will add a new definition, by name, to this instance of