Skip to content

Commit

Permalink
virtualization: properly restore cold/warm states, cache, and scry st…
Browse files Browse the repository at this point in the history
…ack when catching an error
  • Loading branch information
eamsden committed Dec 4, 2023
1 parent 9774da7 commit 7beca7e
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 3 deletions.
23 changes: 23 additions & 0 deletions rust/ares/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,12 @@ enum NockWork {
Work12(Nock12),
}

pub struct SavedContext {
cold: Cold,
warm: Warm,
cache: Hamt<Noun>,
}

pub struct Context {
pub stack: NockStack,
// For printing slogs; if None, print to stdout; Option slated to be removed
Expand All @@ -268,6 +274,23 @@ pub struct Context {
pub trace_info: Option<TraceInfo>,
}

impl Context {
pub fn save(&self) -> SavedContext {
SavedContext {
cold: self.cold,
warm: self.warm,
cache: self.cache,
}
}

pub fn restore(&mut self, saved: SavedContext) {
self.cold = saved.cold;
self.warm = saved.warm;
self.cache = saved.cache;
}
}


#[derive(Clone, Copy, Debug)]
pub enum Error {
ScryBlocked(Noun), // path
Expand Down
1 change: 1 addition & 0 deletions rust/ares/src/jets/cold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ impl Iterator for NounList {
}
}

#[derive(Copy, Clone)]
pub struct Cold(*mut ColdMem);

struct ColdMem {
Expand Down
25 changes: 22 additions & 3 deletions rust/ares/src/jets/nock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ pub fn jet_mure(context: &mut Context, subject: Noun) -> Result {
let scry = util::pass_thru_scry(&mut context.stack);

context.scry_stack = T(&mut context.stack, &[scry, context.scry_stack]);

let saved = context.save();
match interpret(context, tap, fol) {
Ok(res) => {
context.scry_stack = context.scry_stack.as_cell()?.tail();
Expand All @@ -100,7 +102,11 @@ pub fn jet_mure(context: &mut Context, subject: Noun) -> Result {
// Since we are using the pass-through scry handler, we know for a fact that a scry
// crash must have come from a senior virtualization context.
Error::NonDeterministic(_) | Error::ScryCrashed(_) => Err(JetErr::Fail(error)),
Error::Deterministic(_) | Error::ScryBlocked(_) => Ok(D(0)),
Error::Deterministic(_) | Error::ScryBlocked(_) => {
context.restore(saved);
context.scry_stack = context.scry_stack.as_cell()?.tail();
Ok(D(0))
},
},
}
}
Expand All @@ -111,6 +117,8 @@ pub fn jet_mute(context: &mut Context, subject: Noun) -> Result {
let scry = util::pass_thru_scry(&mut context.stack);

context.scry_stack = T(&mut context.stack, &[scry, context.scry_stack]);

let saved = context.save();
match interpret(context, tap, fol) {
Ok(res) => {
context.scry_stack = context.scry_stack.as_cell()?.tail();
Expand All @@ -121,12 +129,16 @@ pub fn jet_mute(context: &mut Context, subject: Noun) -> Result {
// crash must have come from a senior virtualization context.
Error::NonDeterministic(_) | Error::ScryCrashed(_) => Err(JetErr::Fail(error)),
Error::ScryBlocked(path) => {
context.scry_stack = context.scry_stack.as_cell()?.tail();
context.restore(saved);
// XX: Need to check that result is actually of type path
// return [[%leaf "mute.hunk"] ~] if not
let bon = util::smyt(&mut context.stack, path)?;
Ok(T(&mut context.stack, &[NO, bon, D(0)]))
}
Error::Deterministic(trace) => {
context.scry_stack = context.scry_stack.as_cell()?.tail();
context.restore(saved);
let ton = Cell::new(&mut context.stack, D(2), trace);
let tun = util::mook(context, ton, false)?;
Ok(T(&mut context.stack, &[NO, tun.tail()]))
Expand Down Expand Up @@ -177,11 +189,18 @@ pub mod util {
}

pub fn mink(context: &mut Context, subject: Noun, formula: Noun) -> Result<Noun, Error> {
let saved = context.save();
match interpret(context, subject, formula) {
Ok(res) => Ok(T(&mut context.stack, &[D(0), res])),
Err(err) => match err {
Error::ScryBlocked(path) => Ok(T(&mut context.stack, &[D(1), path])),
Error::Deterministic(trace) => Ok(T(&mut context.stack, &[D(2), trace])),
Error::ScryBlocked(path) => {
context.restore(saved);
Ok(T(&mut context.stack, &[D(1), path]))
},
Error::Deterministic(trace) => {
context.restore(saved);
Ok(T(&mut context.stack, &[D(2), trace]))
},
Error::NonDeterministic(_) | Error::ScryCrashed(_) => Err(err),
},
}
Expand Down
1 change: 1 addition & 0 deletions rust/ares/src/jets/warm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::noun::{Noun, Slots};
use std::ptr::{copy_nonoverlapping, null_mut};

/// key = formula
#[derive(Copy, Clone)]
pub struct Warm(Hamt<WarmEntry>);

impl Preserve for Warm {
Expand Down

0 comments on commit 7beca7e

Please sign in to comment.