Save exit Wasm FP and PC in component-to-host trampolines (#4601)
* Wasmtime: Add a pointer to `VMRuntimeLimits` in component contexts * Save exit Wasm FP and PC in component-to-host trampolines Fixes #4535 * Add comment about why we deref the trampoline's FP * Update some tests to use new `vmruntime_limits_*` methods
This commit is contained in:
@@ -222,61 +222,57 @@ fn attempt_to_leave_during_malloc() -> Result<()> {
|
||||
let component = Component::new(&engine, component)?;
|
||||
let mut store = Store::new(&engine, ());
|
||||
|
||||
// TODO(#4535): we need to fold the Wasm<--->host trampoline functionality into
|
||||
// component trampolines. Until then, we panic when getting a backtrace here.
|
||||
if false {
|
||||
// Assert that during a host import if we return values to wasm that a trap
|
||||
// happens if we try to leave the instance.
|
||||
let trap = linker
|
||||
.instantiate(&mut store, &component)?
|
||||
.get_typed_func::<(), (), _>(&mut store, "run")?
|
||||
.call(&mut store, ())
|
||||
.unwrap_err()
|
||||
.downcast::<Trap>()?;
|
||||
assert!(
|
||||
trap.to_string().contains("cannot leave component instance"),
|
||||
"bad trap: {}",
|
||||
trap,
|
||||
);
|
||||
// Assert that during a host import if we return values to wasm that a trap
|
||||
// happens if we try to leave the instance.
|
||||
let trap = linker
|
||||
.instantiate(&mut store, &component)?
|
||||
.get_typed_func::<(), (), _>(&mut store, "run")?
|
||||
.call(&mut store, ())
|
||||
.unwrap_err()
|
||||
.downcast::<Trap>()?;
|
||||
assert!(
|
||||
trap.to_string().contains("cannot leave component instance"),
|
||||
"bad trap: {}",
|
||||
trap,
|
||||
);
|
||||
|
||||
let trace = trap.trace().unwrap();
|
||||
assert_eq!(trace.len(), 4);
|
||||
let trace = trap.trace().unwrap();
|
||||
assert_eq!(trace.len(), 4);
|
||||
|
||||
// This was our entry point...
|
||||
assert_eq!(trace[3].module_name(), Some("m"));
|
||||
assert_eq!(trace[3].func_name(), Some("run"));
|
||||
// This was our entry point...
|
||||
assert_eq!(trace[3].module_name(), Some("m"));
|
||||
assert_eq!(trace[3].func_name(), Some("run"));
|
||||
|
||||
// ... which called an imported function which ends up being originally
|
||||
// defined by the shim instance. The shim instance then does an indirect
|
||||
// call through a table which goes to the `canon.lower`'d host function
|
||||
assert_eq!(trace[2].module_name(), Some("host_shim"));
|
||||
assert_eq!(trace[2].func_name(), Some("shim_ret_string"));
|
||||
// ... which called an imported function which ends up being originally
|
||||
// defined by the shim instance. The shim instance then does an indirect
|
||||
// call through a table which goes to the `canon.lower`'d host function
|
||||
assert_eq!(trace[2].module_name(), Some("host_shim"));
|
||||
assert_eq!(trace[2].func_name(), Some("shim_ret_string"));
|
||||
|
||||
// ... and the lowered host function will call realloc to allocate space for
|
||||
// the result
|
||||
assert_eq!(trace[1].module_name(), Some("m"));
|
||||
assert_eq!(trace[1].func_name(), Some("realloc"));
|
||||
// ... and the lowered host function will call realloc to allocate space for
|
||||
// the result
|
||||
assert_eq!(trace[1].module_name(), Some("m"));
|
||||
assert_eq!(trace[1].func_name(), Some("realloc"));
|
||||
|
||||
// ... but realloc calls the shim instance and tries to exit the
|
||||
// component, triggering a dynamic trap
|
||||
assert_eq!(trace[0].module_name(), Some("host_shim"));
|
||||
assert_eq!(trace[0].func_name(), Some("shim_thunk"));
|
||||
// ... but realloc calls the shim instance and tries to exit the
|
||||
// component, triggering a dynamic trap
|
||||
assert_eq!(trace[0].module_name(), Some("host_shim"));
|
||||
assert_eq!(trace[0].func_name(), Some("shim_thunk"));
|
||||
|
||||
// In addition to the above trap also ensure that when we enter a wasm
|
||||
// component if we try to leave while lowering then that's also a dynamic
|
||||
// trap.
|
||||
let trap = linker
|
||||
.instantiate(&mut store, &component)?
|
||||
.get_typed_func::<(&str,), (), _>(&mut store, "take-string")?
|
||||
.call(&mut store, ("x",))
|
||||
.unwrap_err()
|
||||
.downcast::<Trap>()?;
|
||||
assert!(
|
||||
trap.to_string().contains("cannot leave component instance"),
|
||||
"bad trap: {}",
|
||||
trap,
|
||||
);
|
||||
}
|
||||
// In addition to the above trap also ensure that when we enter a wasm
|
||||
// component if we try to leave while lowering then that's also a dynamic
|
||||
// trap.
|
||||
let trap = linker
|
||||
.instantiate(&mut store, &component)?
|
||||
.get_typed_func::<(&str,), (), _>(&mut store, "take-string")?
|
||||
.call(&mut store, ("x",))
|
||||
.unwrap_err()
|
||||
.downcast::<Trap>()?;
|
||||
assert!(
|
||||
trap.to_string().contains("cannot leave component instance"),
|
||||
"bad trap: {}",
|
||||
trap,
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -605,24 +601,21 @@ fn bad_import_alignment() -> Result<()> {
|
||||
let component = Component::new(&engine, component)?;
|
||||
let mut store = Store::new(&engine, ());
|
||||
|
||||
// TODO(#4535): we need to fold the Wasm<--->host trampoline functionality into
|
||||
// component trampolines. Until then, we panic when getting a backtrace here.
|
||||
if false {
|
||||
let trap = linker
|
||||
.instantiate(&mut store, &component)?
|
||||
.get_typed_func::<(), (), _>(&mut store, "unaligned-retptr")?
|
||||
.call(&mut store, ())
|
||||
.unwrap_err()
|
||||
.downcast::<Trap>()?;
|
||||
assert!(trap.to_string().contains("pointer not aligned"), "{}", trap);
|
||||
let trap = linker
|
||||
.instantiate(&mut store, &component)?
|
||||
.get_typed_func::<(), (), _>(&mut store, "unaligned-argptr")?
|
||||
.call(&mut store, ())
|
||||
.unwrap_err()
|
||||
.downcast::<Trap>()?;
|
||||
assert!(trap.to_string().contains("pointer not aligned"), "{}", trap);
|
||||
}
|
||||
let trap = linker
|
||||
.instantiate(&mut store, &component)?
|
||||
.get_typed_func::<(), (), _>(&mut store, "unaligned-retptr")?
|
||||
.call(&mut store, ())
|
||||
.unwrap_err()
|
||||
.downcast::<Trap>()?;
|
||||
assert!(trap.to_string().contains("pointer not aligned"), "{}", trap);
|
||||
let trap = linker
|
||||
.instantiate(&mut store, &component)?
|
||||
.get_typed_func::<(), (), _>(&mut store, "unaligned-argptr")?
|
||||
.call(&mut store, ())
|
||||
.unwrap_err()
|
||||
.downcast::<Trap>()?;
|
||||
assert!(trap.to_string().contains("pointer not aligned"), "{}", trap);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user