Document the wasmtime::Instance APIs (#814)
* Document the `wasmtime::Instance` APIs This documents oddities like the import list and export list and how to match them all up. Addtionally this largely just expands all the docs related to `Instance` to get filled out. This also moves the `set_signal_handler` functions into platform-specific modules in order to follow Rust idioms about how to expose platform-specific information. Additionally the methods are marked `unsafe` because I figure anything having to do with signal handling is `unsafe` inherently. I don't actually know what these functions do, so they're currently still undocumented. * Fix build of python bindings * Fix some rebase conflicts
This commit is contained in:
@@ -3,6 +3,7 @@ mod tests {
|
||||
use anyhow::Result;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use wasmtime::unix::InstanceExt;
|
||||
use wasmtime::*;
|
||||
|
||||
const WAT1: &str = r#"
|
||||
@@ -38,7 +39,7 @@ mod tests {
|
||||
|
||||
fn invoke_export(instance: &Instance, func_name: &str) -> Result<Box<[Val]>, Trap> {
|
||||
let ret = instance
|
||||
.find_export_by_name(func_name)
|
||||
.get_export(func_name)
|
||||
.unwrap()
|
||||
.func()
|
||||
.unwrap()
|
||||
@@ -111,9 +112,11 @@ mod tests {
|
||||
let instance = Instance::new(&module, &[])?;
|
||||
|
||||
let (base, length) = set_up_memory(&instance);
|
||||
instance.set_signal_handler(move |signum, siginfo, _| {
|
||||
handle_sigsegv(base, length, signum, siginfo)
|
||||
});
|
||||
unsafe {
|
||||
instance.set_signal_handler(move |signum, siginfo, _| {
|
||||
handle_sigsegv(base, length, signum, siginfo)
|
||||
});
|
||||
}
|
||||
|
||||
let exports = instance.exports();
|
||||
assert!(!exports.is_empty());
|
||||
@@ -171,20 +174,18 @@ mod tests {
|
||||
let instance1 = Instance::new(&module, &[])?;
|
||||
let instance1_handler_triggered = Rc::new(AtomicBool::new(false));
|
||||
|
||||
{
|
||||
unsafe {
|
||||
let (base1, length1) = set_up_memory(&instance1);
|
||||
|
||||
instance1.set_signal_handler({
|
||||
let instance1_handler_triggered = instance1_handler_triggered.clone();
|
||||
move |_signum, _siginfo, _context| {
|
||||
// Remove protections so the execution may resume
|
||||
unsafe {
|
||||
libc::mprotect(
|
||||
base1 as *mut libc::c_void,
|
||||
length1,
|
||||
libc::PROT_READ | libc::PROT_WRITE,
|
||||
);
|
||||
}
|
||||
libc::mprotect(
|
||||
base1 as *mut libc::c_void,
|
||||
length1,
|
||||
libc::PROT_READ | libc::PROT_WRITE,
|
||||
);
|
||||
instance1_handler_triggered.store(true, Ordering::SeqCst);
|
||||
println!(
|
||||
"Hello from instance1 signal handler! {}",
|
||||
@@ -198,20 +199,18 @@ mod tests {
|
||||
let instance2 = Instance::new(&module, &[]).expect("failed to instantiate module");
|
||||
let instance2_handler_triggered = Rc::new(AtomicBool::new(false));
|
||||
|
||||
{
|
||||
unsafe {
|
||||
let (base2, length2) = set_up_memory(&instance2);
|
||||
|
||||
instance2.set_signal_handler({
|
||||
let instance2_handler_triggered = instance2_handler_triggered.clone();
|
||||
move |_signum, _siginfo, _context| {
|
||||
// Remove protections so the execution may resume
|
||||
unsafe {
|
||||
libc::mprotect(
|
||||
base2 as *mut libc::c_void,
|
||||
length2,
|
||||
libc::PROT_READ | libc::PROT_WRITE,
|
||||
);
|
||||
}
|
||||
libc::mprotect(
|
||||
base2 as *mut libc::c_void,
|
||||
length2,
|
||||
libc::PROT_READ | libc::PROT_WRITE,
|
||||
);
|
||||
instance2_handler_triggered.store(true, Ordering::SeqCst);
|
||||
println!(
|
||||
"Hello from instance2 signal handler! {}",
|
||||
@@ -266,10 +265,12 @@ mod tests {
|
||||
let module1 = Module::new(&store, &data1)?;
|
||||
let instance1 = Instance::new(&module1, &[])?;
|
||||
let (base1, length1) = set_up_memory(&instance1);
|
||||
instance1.set_signal_handler(move |signum, siginfo, _| {
|
||||
println!("instance1");
|
||||
handle_sigsegv(base1, length1, signum, siginfo)
|
||||
});
|
||||
unsafe {
|
||||
instance1.set_signal_handler(move |signum, siginfo, _| {
|
||||
println!("instance1");
|
||||
handle_sigsegv(base1, length1, signum, siginfo)
|
||||
});
|
||||
}
|
||||
|
||||
let instance1_exports = instance1.exports();
|
||||
assert!(!instance1_exports.is_empty());
|
||||
@@ -281,9 +282,11 @@ mod tests {
|
||||
let instance2 = Instance::new(&module2, &[instance1_read])?;
|
||||
// since 'instance2.run' calls 'instance1.read' we need to set up the signal handler to handle
|
||||
// SIGSEGV originating from within the memory of instance1
|
||||
instance2.set_signal_handler(move |signum, siginfo, _| {
|
||||
handle_sigsegv(base1, length1, signum, siginfo)
|
||||
});
|
||||
unsafe {
|
||||
instance2.set_signal_handler(move |signum, siginfo, _| {
|
||||
handle_sigsegv(base1, length1, signum, siginfo)
|
||||
});
|
||||
}
|
||||
|
||||
println!("calling instance2.run");
|
||||
let result = invoke_export(&instance2, "run")?;
|
||||
|
||||
Reference in New Issue
Block a user