Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jets for min, max, and peg #117

Merged
merged 15 commits into from
Nov 15, 2023
2 changes: 1 addition & 1 deletion rust/ares/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 53 additions & 1 deletion rust/ares/src/jets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ pub mod util {
use std::result;

/**
* Address-based size checks.
* Currently, only addresses indexable by the first 48 bits are reachable by
* modern 64-bit CPUs.
*/
Expand All @@ -159,7 +160,7 @@ pub mod util {
.ok_or(JetErr::Fail(Error::NonDeterministic(D(0))))
}

/// Performs addition that returns None on Noun size overflow
/// Performs subtraction that returns None on Noun size overflow
pub fn checked_sub(a: usize, b: usize) -> result::Result<usize, JetErr> {
a.checked_sub(b)
.ok_or(JetErr::Fail(Error::NonDeterministic(D(0))))
Expand Down Expand Up @@ -339,5 +340,56 @@ pub mod util {
}
}
}

pub fn assert_jet_size(context: &mut Context, jet: Jet, sam: Noun, siz: usize) {
let sam = T(&mut context.stack, &[D(0), sam, D(0)]);
let res = assert_no_alloc(|| jet(context, sam).unwrap());
assert!(res.is_atom(), "jet result not atom");
let res_siz = res.atom().unwrap().size();
assert!(siz == res_siz, "got: {}, need: {}", res_siz, siz);
}

pub fn assert_common_jet(
context: &mut Context,
jet: Jet,
sam: &[fn(&mut NockStack) -> Noun],
res: UBig,
) {
let sam: Vec<Noun> = sam.iter().map(|f| f(&mut context.stack)).collect();
assert_nary_jet_ubig(context, jet, &sam, res);
}

pub fn assert_common_jet_noun(
context: &mut Context,
jet: Jet,
sam: &[fn(&mut NockStack) -> Noun],
res: Noun,
) {
let sam: Vec<Noun> = sam.iter().map(|f| f(&mut context.stack)).collect();
let sam = T(&mut context.stack, &sam);
assert_jet(context, jet, sam, res);
}

pub fn assert_common_jet_err(
context: &mut Context,
jet: Jet,
sam: &[fn(&mut NockStack) -> Noun],
err: JetErr,
) {
let sam: Vec<Noun> = sam.iter().map(|f| f(&mut context.stack)).collect();
let sam = T(&mut context.stack, &sam);
assert_jet_err(context, jet, sam, err);
}

pub fn assert_common_jet_size(
context: &mut Context,
jet: Jet,
sam: &[fn(&mut NockStack) -> Noun],
siz: usize,
) {
let sam: Vec<Noun> = sam.iter().map(|f| f(&mut context.stack)).collect();
let sam = T(&mut context.stack, &sam);
assert_jet_size(context, jet, sam, siz)
}
}
}
33 changes: 18 additions & 15 deletions rust/ares/src/jets/bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,7 @@ pub fn jet_lsh(context: &mut Context, subject: Noun) -> Result {
let (bloq, step) = bite(slot(arg, 2)?)?;
let a = slot(arg, 3)?.as_atom()?;

let len = util::met(bloq, a);
if len == 0 {
return Ok(D(0));
}

let new_size = bits_to_word(checked_add(a.bit_size(), checked_left_shift(bloq, step)?)?)?;
unsafe {
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(&mut context.stack, new_size);
chop(bloq, 0, len, step, dest, a.as_bitslice())?;
Ok(atom.normalize_as_atom().as_noun())
}
util::lsh(&mut context.stack, bloq, step, a)
}

pub fn jet_met(_context: &mut Context, subject: Noun) -> Result {
Expand Down Expand Up @@ -373,6 +363,20 @@ pub mod util {
}
}

pub fn lsh(stack: &mut NockStack, bloq: usize, step: usize, a: Atom) -> Result {
let len = met(bloq, a);
if len == 0 {
return Ok(D(0));
}

let new_size = bits_to_word(checked_add(a.bit_size(), checked_left_shift(bloq, step)?)?)?;
unsafe {
let (mut atom, dest) = IndirectAtom::new_raw_mut_bitslice(stack, new_size);
chop(bloq, 0, len, step, dest, a.as_bitslice())?;
Ok(atom.normalize_as_atom().as_noun())
}
}

/// Measure the number of bloqs in an atom
pub fn met(bloq: usize, a: Atom) -> usize {
if unsafe { a.as_noun().raw_equals(D(0)) } {
Expand Down Expand Up @@ -458,7 +462,7 @@ pub mod util {
#[cfg(test)]
mod tests {
use super::*;
use crate::jets::util::test::{assert_jet, assert_jet_ubig, init_context, A};
use crate::jets::util::test::*;
use crate::mem::NockStack;
use crate::noun::{Noun, D, T};
use ibig::ubig;
Expand Down Expand Up @@ -633,9 +637,8 @@ mod tests {
fn test_lsh() {
let c = &mut init_context();

let (a0, a24, _a63, a96, a128) = atoms(&mut c.stack);
let sam = T(&mut c.stack, &[a0, a24]);
assert_jet(c, jet_lsh, sam, D(0x10eca86));
let (_, a24, _a63, a96, a128) = atoms(&mut c.stack);
assert_common_jet_noun(c, jet_lsh, &[atom_0, atom_24], D(0x10eca86));
let sam = T(&mut c.stack, &[D(3), a24]);
assert_jet(c, jet_lsh, sam, D(0x87654300));
let sam = T(&mut c.stack, &[D(7), a24]);
Expand Down
Loading