Skip to content

Commit

Permalink
Merge pull request #117 from urbit/sigilante/jets-one
Browse files Browse the repository at this point in the history
Jets for `min`, `max`, and `peg`
  • Loading branch information
eamsden authored Nov 15, 2023
2 parents 66d51f5 + 77fa2a3 commit 7a82b5d
Show file tree
Hide file tree
Showing 5 changed files with 427 additions and 137 deletions.
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

0 comments on commit 7a82b5d

Please sign in to comment.