mirror of
https://github.com/urbit/ares.git
synced 2024-12-23 21:31:57 +03:00
Add rev jet
This commit is contained in:
parent
4cb2af9bf0
commit
c9ff3ce67c
@ -61,6 +61,7 @@ pub fn get_jet(jet_name: Noun) -> Option<Jet> {
|
||||
tas!(b"rip") => Some(jet_rip),
|
||||
tas!(b"met") => Some(jet_met),
|
||||
tas!(b"mug") => Some(jet_mug),
|
||||
tas!(b"rev") => Some(jet_rev),
|
||||
_ => {
|
||||
// eprintln!("Unknown jet: {:?}", jet_name);
|
||||
None
|
||||
|
@ -651,6 +651,41 @@ pub fn met(bloq: usize, a: Atom) -> usize {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jet_rev(stack: &mut NockStack, subject: Noun) -> Result<Noun, JetErr> {
|
||||
let arg = raw_slot(subject, 6);
|
||||
let boz = raw_slot(arg, 2).as_atom()?.as_direct()?.data();
|
||||
|
||||
if boz >= 64 {
|
||||
return Err(NonDeterministic);
|
||||
}
|
||||
|
||||
let boz = boz as usize;
|
||||
|
||||
let len = raw_slot(arg, 6).as_atom()?.as_direct()?.data();
|
||||
|
||||
let dat = raw_slot(arg, 7).as_atom()?;
|
||||
|
||||
let bits = len << boz;
|
||||
|
||||
let mut output = if dat.is_direct() && bits < 64 {
|
||||
unsafe { DirectAtom::new_unchecked(0).as_atom() }
|
||||
} else {
|
||||
unsafe { IndirectAtom::new_raw(stack, ((bits + 7) / 8) as usize, &0).as_atom() }
|
||||
};
|
||||
|
||||
let src = dat.as_bitslice();
|
||||
let dest = output.as_bitslice_mut();
|
||||
|
||||
let len = len as usize;
|
||||
let total_len = len << boz;
|
||||
|
||||
for (start, end) in (0..len).map(|b| (b << boz, (b + 1) << boz)) {
|
||||
dest[start..end].copy_from_bitslice(&src[(total_len - end)..(total_len - start)]);
|
||||
}
|
||||
|
||||
Ok(output.as_noun())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -1292,4 +1327,15 @@ mod tests {
|
||||
let sam = T(s, &[sam, a0, a24, a63, a96, a128]);
|
||||
assert_jet(s, jet_mug, sam, D(0x7543cac7));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rev() {
|
||||
let ref mut s = init();
|
||||
let (_a0, a24, _a63, a96, a128) = atoms(s);
|
||||
let sam = T(s, &[D(0), D(60), a24]);
|
||||
assert_jet(s, jet_rev, sam, D(0xc2a6e1000000000));
|
||||
let test = 0x1234567890123u64;
|
||||
let sam = T(s, &[D(3), D(7), D(test)]);
|
||||
assert_jet(s, jet_rev, sam, D(test.swap_bytes() >> 8));
|
||||
}
|
||||
}
|
||||
|
@ -182,6 +182,10 @@ impl DirectAtom {
|
||||
pub fn as_bitslice(&self) -> &BitSlice<u64, Lsb0> {
|
||||
BitSlice::from_element(&self.0)
|
||||
}
|
||||
|
||||
pub fn as_bitslice_mut<'a>(&'a mut self) -> &'a mut BitSlice<u64, Lsb0> {
|
||||
BitSlice::from_element_mut(&mut self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DirectAtom {
|
||||
@ -372,10 +376,18 @@ impl IndirectAtom {
|
||||
unsafe { self.to_raw_pointer().add(2) as *const u64 }
|
||||
}
|
||||
|
||||
pub fn data_pointer_mut(&mut self) -> *mut u64 {
|
||||
unsafe { self.to_raw_pointer_mut().add(2) as *mut u64 }
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &[u64] {
|
||||
unsafe { from_raw_parts(self.data_pointer(), self.size()) }
|
||||
}
|
||||
|
||||
pub fn as_mut_slice(&mut self) -> &mut [u64] {
|
||||
unsafe { from_raw_parts_mut(self.data_pointer_mut(), self.size()) }
|
||||
}
|
||||
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
unsafe { from_raw_parts(self.data_pointer() as *const u8, self.size() << 3) }
|
||||
}
|
||||
@ -385,6 +397,10 @@ impl IndirectAtom {
|
||||
BitSlice::from_slice(self.as_slice())
|
||||
}
|
||||
|
||||
pub fn as_bitslice_mut<'a>(&'a mut self) -> &'a mut BitSlice<u64, Lsb0> {
|
||||
BitSlice::from_slice_mut(self.as_mut_slice())
|
||||
}
|
||||
|
||||
pub fn as_ubig<S: Stack>(&self, stack: &mut S) -> UBig {
|
||||
UBig::from_le_bytes_stack(stack, self.as_bytes())
|
||||
}
|
||||
@ -595,16 +611,10 @@ impl Atom {
|
||||
let bit_size = big.bit_len();
|
||||
let buffer = big.to_le_bytes_stack();
|
||||
if bit_size < 64 {
|
||||
#[rustfmt::skip]
|
||||
let value: u64 =
|
||||
if bit_size == 0 { 0 } else { (buffer[0] as u64)
|
||||
| if bit_size <= 8 { 0 } else { (buffer[1] as u64) << 8
|
||||
| if bit_size <= 16 { 0 } else { (buffer[2] as u64) << 16
|
||||
| if bit_size <= 24 { 0 } else { (buffer[3] as u64) << 24
|
||||
| if bit_size <= 32 { 0 } else { (buffer[4] as u64) << 32
|
||||
| if bit_size <= 40 { 0 } else { (buffer[5] as u64) << 40
|
||||
| if bit_size <= 48 { 0 } else { (buffer[6] as u64) << 48
|
||||
| if bit_size <= 56 { 0 } else { (buffer[7] as u64) << 56 } } } } } } } };
|
||||
let mut value = 0u64;
|
||||
for i in (0..bit_size).step_by(8) {
|
||||
value |= (buffer[i / 8] as u64) << i;
|
||||
}
|
||||
unsafe { DirectAtom::new_unchecked(value).as_atom() }
|
||||
} else {
|
||||
let byte_size = (big.bit_len() + 7) >> 3;
|
||||
@ -652,6 +662,14 @@ impl Atom {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_bitslice_mut<'a>(&'a mut self) -> &'a mut BitSlice<u64, Lsb0> {
|
||||
if self.is_indirect() {
|
||||
unsafe { self.indirect.as_bitslice_mut() }
|
||||
} else {
|
||||
unsafe { self.direct.as_bitslice_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_ubig<S: Stack>(self, stack: &mut S) -> UBig {
|
||||
if self.is_indirect() {
|
||||
unsafe { self.indirect.as_ubig(stack) }
|
||||
|
Loading…
Reference in New Issue
Block a user