interpreter: add with_stack_frame method to context

This commit is contained in:
Edward Amsden 2023-12-08 12:44:55 -06:00
parent 529d8786cd
commit d7236aed41
3 changed files with 38 additions and 47 deletions

View File

@ -9,6 +9,7 @@ use crate::jets::warm::Warm;
use crate::jets::JetErr;
use crate::mem::unifying_equality;
use crate::mem::NockStack;
use crate::mem::Preserve;
use crate::newt::Newt;
use crate::noun;
use crate::noun::{Atom, Cell, IndirectAtom, Noun, Slots, D, T};
@ -22,7 +23,6 @@ use std::result;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::time::Instant;
use crate::mem::Preserve;
crate::gdb!();
@ -283,6 +283,26 @@ impl Context {
self.cold = saved.cold;
self.warm = saved.warm;
}
/**
* For jets that need a stack frame internally.
*
* This ensures that the frame is cleaned up even if the closure short-circuites to an error
* result using e.g. the ? syntax. We need this method separately from with_frame to allow the
* jet to use the entire context without the borrow checker complaining about the mutable
* references.
*/
pub unsafe fn with_stack_frame<F, O>(&mut self, slots: usize, f: F) -> O
where
F: FnOnce(&mut Context) -> O,
O: Preserve,
{
self.stack.frame_push(slots);
let mut ret = f(self);
ret.preserve(&mut self.stack);
self.stack.frame_pop();
ret
}
}
#[derive(Clone, Copy, Debug)]
@ -296,35 +316,19 @@ pub enum Error {
impl Preserve for Error {
unsafe fn preserve(&mut self, stack: &mut NockStack) {
match self {
Error::ScryBlocked(ref mut path) => {
path.preserve(stack)
},
Error::ScryCrashed(ref mut trace) => {
trace.preserve(stack)
},
Error::Deterministic(ref mut trace) => {
trace.preserve(stack)
}
Error::NonDeterministic(ref mut trace) => {
trace.preserve(stack)
}
Error::ScryBlocked(ref mut path) => path.preserve(stack),
Error::ScryCrashed(ref mut trace) => trace.preserve(stack),
Error::Deterministic(ref mut trace) => trace.preserve(stack),
Error::NonDeterministic(ref mut trace) => trace.preserve(stack),
}
}
unsafe fn assert_in_stack(&self, stack: &NockStack) {
match self {
Error::ScryBlocked(ref path) => {
path.assert_in_stack(stack)
},
Error::ScryCrashed(ref trace) => {
trace.assert_in_stack(stack)
},
Error::Deterministic(ref trace) => {
trace.assert_in_stack(stack)
}
Error::NonDeterministic(ref trace) => {
trace.assert_in_stack(stack)
}
Error::ScryBlocked(ref path) => path.assert_in_stack(stack),
Error::ScryCrashed(ref trace) => trace.assert_in_stack(stack),
Error::Deterministic(ref trace) => trace.assert_in_stack(stack),
Error::NonDeterministic(ref trace) => trace.assert_in_stack(stack),
}
}
}

View File

@ -58,19 +58,15 @@ pub enum JetErr {
impl Preserve for JetErr {
unsafe fn preserve(&mut self, stack: &mut NockStack) {
match self {
JetErr::Punt => {},
JetErr::Fail(ref mut err) => {
err.preserve(stack)
},
JetErr::Punt => {}
JetErr::Fail(ref mut err) => err.preserve(stack),
}
}
unsafe fn assert_in_stack(&self, stack: &NockStack) {
match self {
JetErr::Punt => {},
JetErr::Fail(ref err) => {
err.assert_in_stack(stack)
},
JetErr::Punt => {}
JetErr::Fail(ref err) => err.assert_in_stack(stack),
}
}
}

View File

@ -664,7 +664,7 @@ impl NockStack {
pub unsafe fn with_frame<F, O>(&mut self, num_locals: usize, f: F) -> O
where
F: FnOnce(&mut NockStack) -> O,
O: Preserve
O: Preserve,
{
self.frame_push(num_locals);
let mut ret = f(self);
@ -1139,24 +1139,15 @@ impl Stack for NockStack {
impl<T: Preserve, E: Preserve> Preserve for Result<T, E> {
unsafe fn preserve(&mut self, stack: &mut NockStack) {
match self.as_mut() {
Ok(t_ref) => {
t_ref.preserve(stack)
},
Err(e_ref) => {
e_ref.preserve(stack)
}
Ok(t_ref) => t_ref.preserve(stack),
Err(e_ref) => e_ref.preserve(stack),
}
}
unsafe fn assert_in_stack(&self, stack: &NockStack) {
match self.as_ref() {
Ok(t_ref) => {
t_ref.assert_in_stack(stack)
},
Err(e_ref) => {
e_ref.assert_in_stack(stack)
Ok(t_ref) => t_ref.assert_in_stack(stack),
Err(e_ref) => e_ref.assert_in_stack(stack),
}
}
}
}