Caller get_export() implemented for Extern::Func. (#2108)
* Caller get_export() implemented for func * update tests for get_export() Extern::Func return Signed-off-by: Christopher Agia <chrisagia@google.com> * document get_export() for Extern::Func Signed-off-by: Christopher Agia <chrisagia@google.com>
This commit is contained in:
@@ -1421,17 +1421,21 @@ pub trait IntoFunc<Params, Results> {
|
|||||||
/// via [`Func::wrap`].
|
/// via [`Func::wrap`].
|
||||||
///
|
///
|
||||||
/// This structure can be taken as the first parameter of a closure passed to
|
/// This structure can be taken as the first parameter of a closure passed to
|
||||||
/// [`Func::wrap`], and it can be used to learn information about the caller of
|
/// [Func::wrap], and it can be used to learn information about the caller of
|
||||||
/// the function, such as the calling module's memory, exports, etc.
|
/// the function, such as the calling module's memory, exports, etc.
|
||||||
///
|
///
|
||||||
/// The primary purpose of this structure is to provide access to the
|
/// The primary purpose of this structure is to provide access to the
|
||||||
/// caller's information, such as it's exported memory. This allows
|
/// caller's information, namely it's exported memory and exported functions. This
|
||||||
/// functions which take pointers as arguments to easily read the memory the
|
/// allows functions which take pointers as arguments to easily read the memory the
|
||||||
/// pointers point into.
|
/// pointers point into, or if a function is expected to call malloc in the wasm
|
||||||
|
/// module to reserve space for the output you can do that.
|
||||||
///
|
///
|
||||||
/// Note that this is intended to be a pretty temporary mechanism for accessing
|
/// Note that this Caller type a pretty temporary mechanism for accessing the
|
||||||
/// the caller's memory until interface types has been fully standardized and
|
/// caller's information until interface types has been fully standardized and
|
||||||
/// implemented.
|
/// implemented. The interface types proposal will obsolete this type and this will
|
||||||
|
/// be removed in the future at some point after interface types is implemented. If
|
||||||
|
/// you're relying on this Caller type it's recommended to become familiar with
|
||||||
|
/// interface types to ensure that your use case is covered by the proposal.
|
||||||
pub struct Caller<'a> {
|
pub struct Caller<'a> {
|
||||||
// Note that this is a `Weak` pointer instead of a `&'a Store`,
|
// Note that this is a `Weak` pointer instead of a `&'a Store`,
|
||||||
// intentionally so. This allows us to break an `Rc` cycle which would
|
// intentionally so. This allows us to break an `Rc` cycle which would
|
||||||
@@ -1457,14 +1461,18 @@ impl Caller<'_> {
|
|||||||
/// Looks up an export from the caller's module by the `name` given.
|
/// Looks up an export from the caller's module by the `name` given.
|
||||||
///
|
///
|
||||||
/// Note that this function is only implemented for the `Extern::Memory`
|
/// Note that this function is only implemented for the `Extern::Memory`
|
||||||
/// type currently. No other exported structure can be acquired through this
|
/// and the `Extern::Func` types currently. No other exported structures
|
||||||
/// just yet, but this may be implemented in the future!
|
/// can be acquired through this just yet, but this may be implemented
|
||||||
|
/// in the future!
|
||||||
|
///
|
||||||
|
/// Note that when accessing and calling exported functions, one should adhere
|
||||||
|
/// to the guidlines of the interface types proposal.
|
||||||
///
|
///
|
||||||
/// # Return
|
/// # Return
|
||||||
///
|
///
|
||||||
/// If a memory export with the `name` provided was found, then it is
|
/// If a memory or function export with the `name` provided was found, then it is
|
||||||
/// returned as a `Memory`. There are a number of situations, however, where
|
/// returned as a `Memory`. There are a number of situations, however, where
|
||||||
/// the memory may not be available:
|
/// the memory or function may not be available:
|
||||||
///
|
///
|
||||||
/// * The caller instance may not have an export named `name`
|
/// * The caller instance may not have an export named `name`
|
||||||
/// * The export named `name` may not be an exported memory
|
/// * The export named `name` may not be an exported memory
|
||||||
@@ -1479,10 +1487,7 @@ impl Caller<'_> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let instance = InstanceHandle::from_vmctx(self.caller_vmctx);
|
let instance = InstanceHandle::from_vmctx(self.caller_vmctx);
|
||||||
let export = match instance.lookup(name) {
|
let export = instance.lookup(name)?;
|
||||||
Some(Export::Memory(m)) => m,
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
// Our `Weak` pointer is used only to break a cycle where `Store`
|
// Our `Weak` pointer is used only to break a cycle where `Store`
|
||||||
// stores instance handles which have this weak pointer as their
|
// stores instance handles which have this weak pointer as their
|
||||||
// custom host data. This function should only be invoke-able while
|
// custom host data. This function should only be invoke-able while
|
||||||
@@ -1490,8 +1495,11 @@ impl Caller<'_> {
|
|||||||
debug_assert!(self.store.upgrade().is_some());
|
debug_assert!(self.store.upgrade().is_some());
|
||||||
let handle =
|
let handle =
|
||||||
Store::from_inner(self.store.upgrade()?).existing_instance_handle(instance);
|
Store::from_inner(self.store.upgrade()?).existing_instance_handle(instance);
|
||||||
let mem = Memory::from_wasmtime_memory(export, handle);
|
match export {
|
||||||
Some(Extern::Memory(mem))
|
Export::Memory(m) => Some(Extern::Memory(Memory::from_wasmtime_memory(m, handle))),
|
||||||
|
Export::Function(f) => Some(Extern::Func(Func::from_wasmtime_function(f, handle))),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -409,7 +409,7 @@ fn caller_memory() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
let f = Func::wrap(&store, |c: Caller<'_>| {
|
let f = Func::wrap(&store, |c: Caller<'_>| {
|
||||||
assert!(c.get_export("m").is_some());
|
assert!(c.get_export("m").is_some());
|
||||||
assert!(c.get_export("f").is_none());
|
assert!(c.get_export("f").is_some());
|
||||||
assert!(c.get_export("g").is_none());
|
assert!(c.get_export("g").is_none());
|
||||||
assert!(c.get_export("t").is_none());
|
assert!(c.get_export("t").is_none());
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user