Skip to content
This repository has been archived by the owner on Mar 24, 2022. It is now read-only.

Commit

Permalink
only force an unwind if n>0 host frames are on a guest stack
Browse files Browse the repository at this point in the history
  • Loading branch information
awortman-fastly committed Oct 8, 2019
1 parent f1e6950 commit 6557e8e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
11 changes: 10 additions & 1 deletion lucet-runtime/lucet-runtime-internals/src/hostcall_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,16 @@ macro_rules! lucet_hostcalls {
) -> $ret_ty {
$($body)*
}
hostcall_impl(&mut $crate::vmctx::Vmctx::from_raw(vmctx_raw), $( $arg ),*)

#[allow(unused_imports)]
use lucet_runtime_internals::vmctx::VmctxInternal;
$crate::vmctx::Vmctx::from_raw(vmctx_raw).instance_mut().begin_hostcall();

let res = hostcall_impl(&mut $crate::vmctx::Vmctx::from_raw(vmctx_raw), $( $arg ),*);

$crate::vmctx::Vmctx::from_raw(vmctx_raw).instance_mut().end_hostcall();

res
}
)*
}
Expand Down
20 changes: 16 additions & 4 deletions lucet-runtime/lucet-runtime-internals/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ pub struct Instance {
/// The value passed back to the guest when resuming a yielded instance.
pub(crate) resumed_val: Option<Box<dyn Any + 'static>>,

hostcall_count: u64,

/// `_padding` must be the last member of the structure.
/// This marks where the padding starts to make the structure exactly 4096 bytes long.
/// It is also used to compute the size of the structure up to that point, i.e. without padding.
Expand Down Expand Up @@ -533,10 +535,7 @@ impl Instance {
/// This function runs the guest code for the WebAssembly `start` section, and running any guest
/// code is potentially unsafe; see [`Instance::run()`](struct.Instance.html#method.run).
pub fn reset(&mut self) -> Result<(), Error> {
// temporary heuristic for whether this should happen upon a reset; in the long term we only
// want to force an unwind if there are hostcall frames present, which we'll need to track
// via the instance
if self.ctx.gpr.rsp != 0 {
if self.hostcall_count > 0 {
self.force_unwind().unwrap();
}
self.alloc.reset_heap(self.module.as_ref())?;
Expand Down Expand Up @@ -694,6 +693,14 @@ impl Instance {
self.c_fatal_handler = Some(handler);
}

pub fn begin_hostcall(&mut self) {
self.hostcall_count += 1;
}

pub fn end_hostcall(&mut self) {
self.hostcall_count -= 1;
}

#[inline]
pub fn get_instruction_count(&self) -> u64 {
self.get_instance_implicits().instruction_count
Expand Down Expand Up @@ -721,6 +728,7 @@ impl Instance {
signal_handler: Box::new(signal_handler_none) as Box<SignalHandler>,
entrypoint: None,
resumed_val: None,
hostcall_count: 0,
_padding: (),
};
inst.set_globals_ptr(globals_ptr);
Expand Down Expand Up @@ -806,6 +814,10 @@ impl Instance {
let mut args_with_vmctx = vec![Val::from(self.alloc.slot().heap)];
args_with_vmctx.extend_from_slice(args);

// when preparing a new context for the guest to run, we must have cleaned up any existing
// host call frames on the stack.
assert_eq!(self.hostcall_count, 0);

HOST_CTX.with(|host_ctx| {
Context::init(
unsafe { self.alloc.stack_u64_mut() },
Expand Down

0 comments on commit 6557e8e

Please sign in to comment.