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

Add u64/u128 atom exports #127

Merged
merged 9 commits into from
Nov 17, 2023
Merged
37 changes: 37 additions & 0 deletions rust/ares/src/noun.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,24 @@ impl IndirectAtom {
UBig::from_le_bytes_stack(stack, self.as_bytes())
}

pub unsafe fn as_u64(self) -> Result<u64> {
if self.size() == 1 {
Ok(*(self.data_pointer()))
} else {
Err(Error::NotRepresentable)
}
}

pub unsafe fn as_u128_pair(self) -> Result<[u64; 2]> {
if self.size() <= 2 {
let u128_array = &mut [0u64; 2];
u128_array.copy_from_slice(&(self.as_slice()[0..2]));
Ok(*u128_array)
} else {
Err(Error::NotRepresentable)
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rust has a native u128 type: https://doc.rust-lang.org/std/primitive.u128.html

You could make a 16-element byte array, copy into it from atom.as_bytes(), and then call u128::from_le_bytes() on the array to get the atom.

Suggested change
pub unsafe fn as_u128_pair(self) -> Result<[u64; 2]> {
if self.size() <= 2 {
let u128_array = &mut [0u64; 2];
u128_array.copy_from_slice(&(self.as_slice()[0..2]));
Ok(*u128_array)
} else {
Err(Error::NotRepresentable)
}
}
pub unsafe fn as_u128(self) -> Result<u128> {
if self.size() <= 2 {
let mut u128_array = [0u8; 16];
let self_bytes = self.as_bytes();
u128_array[0..self.as_bytes()].copy_from_slice(self_bytes);
Ok(u128::from_le_bytes(u128_array)
} else {
Err(Error::NotRepresentable)
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a pair of u64 to match the SoftFloat interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not a generic u128, it's to solve a particular use case from urcrypt.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

urcrypt urfloat, whatever we end up calling it


/** Ensure that the size does not contain any trailing 0 words */
pub unsafe fn normalize(&mut self) -> &Self {
let mut index = self.size() - 1;
Expand Down Expand Up @@ -738,6 +756,25 @@ impl Atom {
}
}

pub fn as_u64(self) -> Result<u64> {
if self.is_direct() {
Ok(unsafe { self.direct.data() })
} else {
unsafe { self.indirect.as_u64() }
}
}

pub unsafe fn as_u128_pair(self) -> Result<[u64; 2]> {
if self.is_direct() {
let u128_array = &mut [0u64; 2];
u128_array[0] = 0x0_u64;
u128_array[1] = self.as_direct()?.data();
eamsden marked this conversation as resolved.
Show resolved Hide resolved
Ok(*u128_array)
sigilante marked this conversation as resolved.
Show resolved Hide resolved
} else {
unsafe { self.indirect.as_u128_pair() }
sigilante marked this conversation as resolved.
Show resolved Hide resolved
}
}

pub fn as_bitslice(&self) -> &BitSlice<u64, Lsb0> {
if self.is_indirect() {
unsafe { self.indirect.as_bitslice() }
Expand Down