jets: touch up previous commit

This commit is contained in:
Alex Shelkovnykov 2023-12-05 00:56:12 -03:00
parent 1c80366066
commit ff08e07b3f
3 changed files with 55 additions and 50 deletions

View File

@ -254,12 +254,6 @@ enum NockWork {
Work12(Nock12), Work12(Nock12),
} }
pub struct SavedContext {
cold: Cold,
warm: Warm,
cache: Hamt<Noun>,
}
pub struct Context { pub struct Context {
pub stack: NockStack, pub stack: NockStack,
// For printing slogs; if None, print to stdout; Option slated to be removed // For printing slogs; if None, print to stdout; Option slated to be removed
@ -274,22 +268,6 @@ pub struct Context {
pub trace_info: Option<TraceInfo>, 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)] #[derive(Clone, Copy, Debug)]
pub enum Error { pub enum Error {
ScryBlocked(Noun), // path ScryBlocked(Noun), // path

View File

@ -1,6 +1,5 @@
/** Virtualization jets /** Virtualization jets
*/ */
use crate::hamt::Hamt;
use crate::interpreter::{interpret, Context, Error}; use crate::interpreter::{interpret, Context, Error};
use crate::jets::util::slot; use crate::jets::util::slot;
use crate::jets::{JetErr, Result}; use crate::jets::{JetErr, Result};
@ -36,16 +35,12 @@ pub fn jet_mink(context: &mut Context, subject: Noun) -> Result {
let v_formula = slot(arg, 5)?; let v_formula = slot(arg, 5)?;
let scry_handler = slot(arg, 3)?; let scry_handler = slot(arg, 3)?;
let old_cache = context.cache; let snapshot = util::snapshot_and_virtualize(context, scry_handler);
let old_scry_stack = context.scry_stack;
context.cache = Hamt::<Noun>::new();
context.scry_stack = T(&mut context.stack, &[scry_handler, old_scry_stack]);
match util::mink(context, v_subject, v_formula) { match util::mink(context, v_subject, v_formula) {
Ok(noun) => { Ok(noun) => {
context.cache = old_cache; context.cache = snapshot.cache;
context.scry_stack = old_scry_stack; context.scry_stack = snapshot.scry_stack;
Ok(noun) Ok(noun)
} }
Err(error) => match error { Err(error) => match error {
@ -64,7 +59,7 @@ pub fn jet_mink(context: &mut Context, subject: Noun) -> Result {
// Error::ScryCrashed, jet_mink() compares the two scry handler stack Nouns> If they // Error::ScryCrashed, jet_mink() compares the two scry handler stack Nouns> If they
// are identical, jet_mink() bails with Error::Deterministic. Otherwise, it forwards // are identical, jet_mink() bails with Error::Deterministic. Otherwise, it forwards
// the Error::ScryCrashed to the senior virtualization call. // the Error::ScryCrashed to the senior virtualization call.
if unsafe { context.scry_stack.raw_equals(old_scry_stack) } { if unsafe { context.scry_stack.raw_equals(snapshot.scry_stack) } {
Err(JetErr::Fail(Error::Deterministic(trace))) Err(JetErr::Fail(Error::Deterministic(trace)))
} else { } else {
Err(JetErr::Fail(error)) Err(JetErr::Fail(error))
@ -90,21 +85,26 @@ pub fn jet_mure(context: &mut Context, subject: Noun) -> Result {
let fol = util::slam_gate_fol(&mut context.stack); let fol = util::slam_gate_fol(&mut context.stack);
let scry = util::pass_thru_scry(&mut context.stack); let scry = util::pass_thru_scry(&mut context.stack);
context.scry_stack = T(&mut context.stack, &[scry, context.scry_stack]); let snapshot = util::snapshot_and_virtualize(context, scry);
let saved = context.save();
match interpret(context, tap, fol) { match interpret(context, tap, fol) {
Ok(res) => { Ok(res) => {
context.scry_stack = context.scry_stack.as_cell()?.tail(); context.cache = snapshot.cache;
context.scry_stack = snapshot.scry_stack;
Ok(T(&mut context.stack, &[D(0), res])) Ok(T(&mut context.stack, &[D(0), res]))
} }
Err(error) => match error { Err(error) => match error {
// Since we are using the pass-through scry handler, we know for a fact that a scry // 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. // crash must have come from a senior virtualization context.
Error::NonDeterministic(_) | Error::ScryCrashed(_) => Err(JetErr::Fail(error)), Error::NonDeterministic(_) | Error::ScryCrashed(_) => Err(JetErr::Fail(error)),
Error::Deterministic(_) | Error::ScryBlocked(_) => { Error::ScryBlocked(_) => {
context.restore(saved); context.scry_stack = snapshot.scry_stack;
context.scry_stack = context.scry_stack.as_cell()?.tail(); Ok(D(0))
}
Error::Deterministic(_) => {
context.cold = snapshot.cold;
context.warm = snapshot.warm;
context.scry_stack = snapshot.scry_stack;
Ok(D(0)) Ok(D(0))
} }
}, },
@ -116,12 +116,12 @@ pub fn jet_mute(context: &mut Context, subject: Noun) -> Result {
let fol = util::slam_gate_fol(&mut context.stack); let fol = util::slam_gate_fol(&mut context.stack);
let scry = util::pass_thru_scry(&mut context.stack); let scry = util::pass_thru_scry(&mut context.stack);
context.scry_stack = T(&mut context.stack, &[scry, context.scry_stack]); let snapshot = util::snapshot_and_virtualize(context, scry);
let saved = context.save();
match interpret(context, tap, fol) { match interpret(context, tap, fol) {
Ok(res) => { Ok(res) => {
context.scry_stack = context.scry_stack.as_cell()?.tail(); context.cache = snapshot.cache;
context.scry_stack = snapshot.scry_stack;
Ok(T(&mut context.stack, &[YES, res])) Ok(T(&mut context.stack, &[YES, res]))
} }
Err(error) => match error { Err(error) => match error {
@ -129,16 +129,16 @@ pub fn jet_mute(context: &mut Context, subject: Noun) -> Result {
// crash must have come from a senior virtualization context. // crash must have come from a senior virtualization context.
Error::NonDeterministic(_) | Error::ScryCrashed(_) => Err(JetErr::Fail(error)), Error::NonDeterministic(_) | Error::ScryCrashed(_) => Err(JetErr::Fail(error)),
Error::ScryBlocked(path) => { Error::ScryBlocked(path) => {
context.scry_stack = context.scry_stack.as_cell()?.tail(); context.scry_stack = snapshot.scry_stack;
context.restore(saved);
// XX: Need to check that result is actually of type path // XX: Need to check that result is actually of type path
// return [[%leaf "mute.hunk"] ~] if not // return [[%leaf "mute.hunk"] ~] if not
let bon = util::smyt(&mut context.stack, path)?; let bon = util::smyt(&mut context.stack, path)?;
Ok(T(&mut context.stack, &[NO, bon, D(0)])) Ok(T(&mut context.stack, &[NO, bon, D(0)]))
} }
Error::Deterministic(trace) => { Error::Deterministic(trace) => {
context.scry_stack = context.scry_stack.as_cell()?.tail(); context.cold = snapshot.cold;
context.restore(saved); context.warm = snapshot.warm;
context.scry_stack = snapshot.scry_stack;
let ton = Cell::new(&mut context.stack, D(2), trace); let ton = Cell::new(&mut context.stack, D(2), trace);
let tun = util::mook(context, ton, false)?; let tun = util::mook(context, ton, false)?;
Ok(T(&mut context.stack, &[NO, tun.tail()])) Ok(T(&mut context.stack, &[NO, tun.tail()]))
@ -148,10 +148,13 @@ pub fn jet_mute(context: &mut Context, subject: Noun) -> Result {
} }
pub mod util { pub mod util {
use crate::hamt::Hamt;
use crate::interpreter::{interpret, Context, Error}; use crate::interpreter::{interpret, Context, Error};
use crate::jets; use crate::jets;
use crate::jets::bits::util::rip; use crate::jets::bits::util::rip;
use crate::jets::cold::Cold;
use crate::jets::form::util::scow; use crate::jets::form::util::scow;
use crate::jets::warm::Warm;
use crate::jets::JetErr; use crate::jets::JetErr;
use crate::mem::NockStack; use crate::mem::NockStack;
use crate::noun::{tape, Cell, Noun, D, T}; use crate::noun::{tape, Cell, Noun, D, T};
@ -162,6 +165,27 @@ pub mod util {
pub const LEAF: Noun = D(tas!(b"leaf")); pub const LEAF: Noun = D(tas!(b"leaf"));
pub const ROSE: Noun = D(tas!(b"rose")); pub const ROSE: Noun = D(tas!(b"rose"));
pub struct ContextSnapshot {
pub cold: Cold,
pub warm: Warm,
pub cache: Hamt<Noun>,
pub scry_stack: Noun,
}
pub fn snapshot_and_virtualize(context: &mut Context, scry: Noun) -> ContextSnapshot {
let res = ContextSnapshot {
cold: context.cold,
warm: context.warm,
cache: context.cache,
scry_stack: context.scry_stack,
};
context.cache = Hamt::<Noun>::new();
context.scry_stack = T(&mut context.stack, &[scry, context.scry_stack]);
res
}
/// The classic "slam gate" formula. /// The classic "slam gate" formula.
pub fn slam_gate_fol(stack: &mut NockStack) -> Noun { pub fn slam_gate_fol(stack: &mut NockStack) -> Noun {
T(stack, &[D(9), D(2), D(0), D(1)]) T(stack, &[D(9), D(2), D(0), D(1)])
@ -189,16 +213,15 @@ pub mod util {
} }
pub fn mink(context: &mut Context, subject: Noun, formula: Noun) -> Result<Noun, Error> { pub fn mink(context: &mut Context, subject: Noun, formula: Noun) -> Result<Noun, Error> {
let saved = context.save(); let cold_snapshot = context.cold;
let warm_snapshot = context.warm;
match interpret(context, subject, formula) { match interpret(context, subject, formula) {
Ok(res) => Ok(T(&mut context.stack, &[D(0), res])), Ok(res) => Ok(T(&mut context.stack, &[D(0), res])),
Err(err) => match err { Err(err) => match err {
Error::ScryBlocked(path) => { Error::ScryBlocked(path) => Ok(T(&mut context.stack, &[D(1), path])),
context.restore(saved);
Ok(T(&mut context.stack, &[D(1), path]))
}
Error::Deterministic(trace) => { Error::Deterministic(trace) => {
context.restore(saved); context.cold = cold_snapshot;
context.warm = warm_snapshot;
Ok(T(&mut context.stack, &[D(2), trace])) Ok(T(&mut context.stack, &[D(2), trace]))
} }
Error::NonDeterministic(_) | Error::ScryCrashed(_) => Err(err), Error::NonDeterministic(_) | Error::ScryCrashed(_) => Err(err),

View File

@ -321,6 +321,8 @@ fn goof(context: &mut Context, traces: Noun) -> Noun {
* Generate tracing events, if JSON tracing enabled. * Generate tracing events, if JSON tracing enabled.
*/ */
fn soft(context: &mut Context, ovo: Noun, trace_name: Option<String>) -> Result<Noun, Noun> { fn soft(context: &mut Context, ovo: Noun, trace_name: Option<String>) -> Result<Noun, Noun> {
let cold_snapshot = context.nock_context.cold;
let warm_snapshot = context.nock_context.warm;
let slam_res = if context.nock_context.trace_info.is_some() { let slam_res = if context.nock_context.trace_info.is_some() {
let start = Instant::now(); let start = Instant::now();
let slam_res = slam(context, POKE_AXIS, ovo); let slam_res = slam(context, POKE_AXIS, ovo);
@ -339,6 +341,8 @@ fn soft(context: &mut Context, ovo: Noun, trace_name: Option<String>) -> Result<
Ok(res) => Ok(res), Ok(res) => Ok(res),
Err(error) => match error { Err(error) => match error {
Error::Deterministic(trace) | Error::NonDeterministic(trace) => { Error::Deterministic(trace) | Error::NonDeterministic(trace) => {
context.nock_context.cold = cold_snapshot;
context.nock_context.warm = warm_snapshot;
Err(goof(context, trace)) Err(goof(context, trace))
} }
Error::ScryBlocked(_) | Error::ScryCrashed(_) => { Error::ScryBlocked(_) | Error::ScryCrashed(_) => {