Skip to content

Commit b05d88c

Browse files
committed
replace evolving a MultiUseSandbox with persist_call_guest_function_by_name
Signed-off-by: Jorge Prendes <[email protected]>
1 parent d6c3ec4 commit b05d88c

File tree

3 files changed

+25
-118
lines changed

3 files changed

+25
-118
lines changed

src/hyperlight_host/src/func/call_ctx.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,6 @@ impl MultiUseGuestCallContext {
5656
self.sbox.restore_state()?;
5757
Ok(self.sbox)
5858
}
59-
/// Close out the context and get back the internally-stored
60-
/// `MultiUseSandbox`.
61-
///
62-
/// Note that this method is pub(crate) and does not reset the state of the
63-
/// sandbox.
64-
///
65-
/// It is intended to be used when evolving a MultiUseSandbox to a new state
66-
/// and is not intended to be called publicly. It allows the state of the guest to be altered
67-
/// during the evolution of one sandbox state to another, enabling the new state created
68-
/// to be captured and stored in the Sandboxes state stack.
69-
///
70-
pub(crate) fn finish_no_reset(self) -> MultiUseSandbox {
71-
self.sbox
72-
}
7359
}
7460

7561
impl Callable for MultiUseGuestCallContext {

src/hyperlight_host/src/sandbox/initialized_multi_use.rs

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ use crate::hypervisor::{Hypervisor, InterruptHandle};
3535
use crate::mem::ptr::RawPtr;
3636
use crate::mem::shared_mem::HostSharedMemory;
3737
use crate::metrics::maybe_time_and_emit_guest_call;
38-
use crate::sandbox_state::sandbox::{EvolvableSandbox, Sandbox};
39-
use crate::sandbox_state::transition::MultiUseContextCallback;
38+
use crate::sandbox_state::sandbox::Sandbox;
4039
use crate::{HyperlightError, Result};
4140

4241
/// A sandbox that supports being used Multiple times.
@@ -189,6 +188,26 @@ impl MultiUseSandbox {
189188
})
190189
}
191190

191+
/// Call a guest function by name, with the given return type and arguments.
192+
/// The changes made to the sandbox are persisted
193+
#[instrument(err(Debug), skip(self, args), parent = Span::current())]
194+
pub fn persist_call_guest_function_by_name<Output: SupportedReturnType>(
195+
&mut self,
196+
func_name: &str,
197+
args: impl ParameterTuple,
198+
) -> Result<Output> {
199+
maybe_time_and_emit_guest_call(func_name, || {
200+
let ret = self.call_guest_function_by_name_no_reset(
201+
func_name,
202+
Output::TYPE,
203+
args.into_value(),
204+
);
205+
let ret = Output::from_value(ret?);
206+
self.mem_mgr.unwrap_mgr_mut().push_state()?;
207+
ret
208+
})
209+
}
210+
192211
/// This function is kept here for fuzz testing the parameter and return types
193212
#[cfg(feature = "fuzzing")]
194213
#[instrument(err(Debug), skip(self, args), parent = Span::current())]
@@ -279,48 +298,16 @@ impl std::fmt::Debug for MultiUseSandbox {
279298
}
280299
}
281300

282-
impl<'a, F>
283-
EvolvableSandbox<
284-
MultiUseSandbox,
285-
MultiUseSandbox,
286-
MultiUseContextCallback<'a, MultiUseSandbox, F>,
287-
> for MultiUseSandbox
288-
where
289-
F: FnOnce(&mut MultiUseGuestCallContext) -> Result<()> + 'a,
290-
{
291-
/// The purpose of this function is to allow multiple states to be associated with a single MultiUseSandbox.
292-
///
293-
/// An implementation such as HyperlightJs or HyperlightWasm can use this to call guest functions to load JS or WASM code and then evolve the sandbox causing state to be captured.
294-
/// The new MultiUseSandbox can then be used to call guest functions to execute the loaded code.
295-
///
296-
/// The evolve function creates a new MultiUseCallContext which is then passed to a callback function allowing the
297-
/// callback function to call guest functions as part of the evolve process, once the callback function is complete
298-
/// the context is finished using a crate internal method that does not restore the prior state of the Sandbox.
299-
/// It then creates a mew memory snapshot on the snapshot stack and returns the MultiUseSandbox
300-
#[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")]
301-
fn evolve(
302-
self,
303-
transition_func: MultiUseContextCallback<'a, MultiUseSandbox, F>,
304-
) -> Result<MultiUseSandbox> {
305-
let mut ctx = self.new_call_context();
306-
transition_func.call(&mut ctx)?;
307-
let mut sbox = ctx.finish_no_reset();
308-
sbox.mem_mgr.unwrap_mgr_mut().push_state()?;
309-
Ok(sbox)
310-
}
311-
}
312-
313301
#[cfg(test)]
314302
mod tests {
315303
use std::sync::{Arc, Barrier};
316304
use std::thread;
317305

318306
use hyperlight_testing::simple_guest_as_string;
319307

320-
use crate::func::call_ctx::MultiUseGuestCallContext;
321308
use crate::sandbox::{Callable, SandboxConfiguration};
322309
use crate::sandbox_state::sandbox::EvolvableSandbox;
323-
use crate::sandbox_state::transition::{MultiUseContextCallback, Noop};
310+
use crate::sandbox_state::transition::Noop;
324311
use crate::{GuestBinary, HyperlightError, MultiUseSandbox, Result, UninitializedSandbox};
325312

326313
// Tests to ensure that many (1000) function calls can be made in a call context with a small stack (1K) and heap(14K).
@@ -375,18 +362,13 @@ mod tests {
375362

376363
let snapshot = sbox.snapshot().unwrap();
377364

378-
let func = Box::new(|call_ctx: &mut MultiUseGuestCallContext| {
379-
call_ctx.call::<i32>("AddToStatic", 5i32)?;
380-
Ok(())
381-
});
382-
let transition_func = MultiUseContextCallback::from(func);
383-
let mut sbox = sbox.evolve(transition_func).unwrap();
365+
sbox.persist_call_guest_function_by_name::<i32>("AddToStatic", 5i32).unwrap();
384366

385-
let res: i32 = sbox.call_guest_function_by_name("GetStatic", ()).unwrap();
367+
let res: i32 = sbox.persist_call_guest_function_by_name("GetStatic", ()).unwrap();
386368
assert_eq!(res, 5);
387369

388370
sbox.restore(&snapshot).unwrap();
389-
let res: i32 = sbox.call_guest_function_by_name("GetStatic", ()).unwrap();
371+
let res: i32 = sbox.persist_call_guest_function_by_name("GetStatic", ()).unwrap();
390372
assert_eq!(res, 0);
391373
}
392374

src/hyperlight_host/src/sandbox_state/transition.rs

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ limitations under the License.
1616

1717
use std::marker::PhantomData;
1818

19-
use tracing::{Span, instrument};
20-
2119
use super::sandbox::Sandbox;
22-
use crate::Result;
23-
use crate::func::call_ctx::MultiUseGuestCallContext;
2420

2521
/// Metadata about an evolution. Any `Sandbox` implementation
2622
/// that also implements `EvolvableSandbox` can decide the following
@@ -82,60 +78,3 @@ impl<Cur: Sandbox, Next: Sandbox> Default for Noop<Cur, Next> {
8278
}
8379

8480
impl<Cur: Sandbox, Next: Sandbox> TransitionMetadata<Cur, Next> for Noop<Cur, Next> {}
85-
86-
/// A `TransitionMetadata` that calls a callback. The callback function takes
87-
/// a mutable reference to a `MultiUseGuestCallContext` and returns a `Result<()>`
88-
/// to signify success or failure of the function.
89-
///
90-
/// The function use the context to call guest functions.
91-
///
92-
/// Construct one of these by passing your callback to
93-
/// `MultiUseContextCallback::from`, as in the following code (assuming `MySandbox`
94-
/// is a `Sandbox` implementation):
95-
///
96-
/// ```ignore
97-
/// let my_cb_fn: dyn FnOnce(&mut MultiUseGuestCallContext) -> Result<()> = |_sbox| {
98-
/// println!("hello world!");
99-
/// };
100-
/// let mutating_cb = MultiUseContextCallback::from(my_cb_fn);
101-
/// ```
102-
pub struct MultiUseContextCallback<'func, Cur: Sandbox, F>
103-
where
104-
F: FnOnce(&mut MultiUseGuestCallContext) -> Result<()> + 'func,
105-
{
106-
cur_ph: PhantomData<Cur>,
107-
fn_life_ph: PhantomData<&'func ()>,
108-
cb: F,
109-
}
110-
111-
impl<Cur: Sandbox, Next: Sandbox, F> TransitionMetadata<Cur, Next>
112-
for MultiUseContextCallback<'_, Cur, F>
113-
where
114-
F: FnOnce(&mut MultiUseGuestCallContext) -> Result<()>,
115-
{
116-
}
117-
118-
impl<Cur: Sandbox, F> MultiUseContextCallback<'_, Cur, F>
119-
where
120-
F: FnOnce(&mut MultiUseGuestCallContext) -> Result<()>,
121-
{
122-
/// Invokes the callback on the provided guest context
123-
#[instrument(skip_all, parent = Span::current(), level= "Trace")]
124-
pub fn call(self, cur: &mut MultiUseGuestCallContext) -> Result<()> {
125-
(self.cb)(cur)
126-
}
127-
}
128-
129-
impl<'a, Cur: Sandbox, F> From<F> for MultiUseContextCallback<'a, Cur, F>
130-
where
131-
F: FnOnce(&mut MultiUseGuestCallContext) -> Result<()> + 'a,
132-
{
133-
#[instrument(skip_all, parent = Span::current(), level= "Trace")]
134-
fn from(val: F) -> Self {
135-
MultiUseContextCallback {
136-
cur_ph: PhantomData,
137-
fn_life_ph: PhantomData,
138-
cb: val,
139-
}
140-
}
141-
}

0 commit comments

Comments
 (0)