Skip to content

Commit 5c38bb2

Browse files
committed
feat: add run_code_stateful() to pyhl::Runtime
Signed-off-by: danbugs <danilochiarlone@gmail.com>
1 parent 4030f21 commit 5c38bb2

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

host/src/pyhl.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,38 @@ impl Runtime {
404404
}
405405
}
406406

407+
/// Execute a string of Python code **without** restoring the
408+
/// snapshot first. Python state (globals, imports, variables)
409+
/// persists across consecutive `run_code_stateful` calls on the
410+
/// same `Runtime` instance.
411+
///
412+
/// The very first call on a freshly-constructed `Runtime` still
413+
/// performs the initial restore (the sandbox is in the raw
414+
/// snapshot-loaded state and needs one restore to become runnable).
415+
/// All subsequent calls skip the restore entirely.
416+
///
417+
/// This is the building block for stateful / REPL-like sessions
418+
/// where a sequence of exec calls should share a single Python
419+
/// interpreter lifetime.
420+
pub fn run_code_stateful(&mut self, code: &str) -> Result<RunTiming> {
421+
let mut t = RunTiming::default();
422+
// The very first call after construction needs the initial
423+
// restore to transition from "snapshot loaded" to "runnable".
424+
if self.first_run {
425+
let tr = Instant::now();
426+
self.sandbox.restore()?;
427+
t.restore_ms = tr.elapsed().as_secs_f64() * 1000.0;
428+
self.first_run = false;
429+
}
430+
self.sandbox.reset_exit_code();
431+
432+
let tc = Instant::now();
433+
let _: () = self.sandbox.call_named("run", code.to_string())?;
434+
t.call_ms = tc.elapsed().as_secs_f64() * 1000.0;
435+
t.exit_code = self.sandbox.last_exit_code();
436+
Ok(t)
437+
}
438+
407439
/// Convenience: read a file and run its contents.
408440
pub fn run_script(&mut self, path: &Path) -> Result<RunTiming> {
409441
let code =

0 commit comments

Comments
 (0)