jets: add safety check to jet cache in jet_turn

This commit is contained in:
Edward Amsden 2024-01-17 18:54:39 -06:00
parent 98b6b67cdc
commit b884cb3130

View File

@ -4,6 +4,8 @@ use crate::interpreter::{interpret, Context, Error};
use crate::jets::util::slot;
use crate::jets::{JetErr, Result};
use crate::noun::{Cell, Noun, D, T};
use bitvec::slice::BitSlice;
use bitvec::order::Lsb0;
crate::gdb!();
@ -24,6 +26,7 @@ pub fn jet_zing(context: &mut Context, subject: Noun) -> Result {
util::zing(stack, list)
}
pub fn jet_turn(context: &mut Context, subject: Noun) -> Result {
let sample = slot(subject, 6)?;
let mut list = slot(sample, 2)?;
@ -39,6 +42,32 @@ pub fn jet_turn(context: &mut Context, subject: Noun) -> Result {
context
.warm
.find_jet(&mut context.stack, &mut gate, &mut gate_battery)
.filter(|(_jet, mut path)| {
// check that 7 is a prefix of the parent battery axis,
// to ensure that the sample (axis 6) is not part of the jet match.
//
// XX TODO this check is pessimized since there could be multiple ways to match the
// jet and we only actually match one of them, but we check all of them and run
// unjetted if any have an axis outside 7.
let axis_7_bits: &BitSlice<u64, Lsb0> = BitSlice::from_element(&7u64);
let batteries_list = context.cold.find(&mut context.stack, &mut path);
let mut ret = true;
for mut batteries in batteries_list {
if let Some((_battery, parent_axis)) = batteries.next() {
let parent_axis_prefix_bits = &parent_axis.as_bitslice()[0..3];
if parent_axis_prefix_bits == axis_7_bits {
continue;
} else {
ret = false;
break;
}
} else {
ret = false;
break;
}
};
ret
})
{
loop {
if let Ok(list_cell) = list.as_cell() {